package org.fnppl.opensdx.security; /* * Copyright (C) 2010-2015 * fine people e.V. <opensdx@fnppl.org> * Henning Thieß <ht@fnppl.org> * * http://fnppl.org */ /* * Software license * * As far as this file or parts of this file is/are software, rather than documentation, this software-license applies / shall be applied. * * This file is part of openSDX * openSDX is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * openSDX is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * and GNU General Public License along with openSDX. * If not, see <http://www.gnu.org/licenses/>. * */ /* * Documentation license * * As far as this file or parts of this file is/are documentation, rather than software, this documentation-license applies / shall be applied. * * This file is part of openSDX. * Permission is granted to copy, distribute and/or modify this document * under the terms of the GNU Free Documentation License, Version 1.3 * or any later version published by the Free Software Foundation; * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. * A copy of the license is included in the section entitled "GNU * Free Documentation License" resp. in the file called "FDL.txt". * */ import java.util.HashMap; import java.util.Vector; public class TrustGraph { private HashMap<String, TrustGraphNode> nodes = new HashMap<String, TrustGraphNode>(); public TrustGraph() { } public TrustGraphNode addOrGetNode(String keyid, int level, long valid_from, long valid_to) { TrustGraphNode node = nodes.get(keyid); if (node == null) { node = new TrustGraphNode(keyid, level, valid_from, valid_to, this); nodes.put(keyid, node); } return node; } public TrustGraphNode addOrGetNode(TrustGraphNode node) { if (nodes.containsKey(node.getKeyid())) { TrustGraphNode nodeIn = nodes.get(node.getKeyid()); nodeIn.addKeylogsFrom(node.getKeylogsFrom()); return nodeIn; } else { node.setGraph(this); nodes.put(node.getKeyid(), node); return node; } } public TrustGraphNode getNode(String keyid) { return nodes.get(keyid); } public void addFromKeyStore(KeyApprovingStore store) { //adding keys with subkey edges Vector<OSDXKey> keys = store.getAllKeys(); for (OSDXKey key : keys) { TrustGraphNode node = addOrGetNode(key.getKeyID(), key.getLevel(), key.validFrom, key.validUntil); //add parentkey if key is subkey if (key.isSub()) { MasterKey master = ((SubKey)key).getParentKey(); if (master!=null) { TrustGraphNode n = addOrGetNode(master.getKeyID(), master.getLevel(), master.validFrom, master.validUntil); node.addKeyLogFrom(master.getKeyID(), TrustGraphEdge.TYPE_SUBKEY, Long.MIN_VALUE); } } } //adding keylogs Vector<KeyLog> keylogs = store.getKeyLogs(); for (KeyLog keylog : keylogs) { try { TrustGraphNode node = getNode(keylog.getKeyIDTo()); if (node!=null) { String action = keylog.getAction(); if (action.equals(KeyLogAction.APPROVAL)) { OSDXKey sigKey = keylog.getActionSignatureKey(); TrustGraphNode n = addOrGetNode(sigKey.getKeyID(), sigKey.getLevel(), sigKey.validFrom, sigKey.validUntil); node.addKeyLogFrom(keylog.getKeyIDFrom(), TrustGraphEdge.TYPE_APPROVE, keylog.getActionDatetime()); } else if (action.equals(KeyLogAction.REVOCATION)) { OSDXKey sigKey = keylog.getActionSignatureKey(); TrustGraphNode n = addOrGetNode(sigKey.getKeyID(), sigKey.getLevel(), sigKey.validFrom, sigKey.validUntil); node.addKeyLogFrom(keylog.getKeyIDFrom(), TrustGraphEdge.TYPE_REVOKE, keylog.getActionDatetime()); } else if (action.equals(KeyLogAction.DISAPPROVAL)) { OSDXKey sigKey = keylog.getActionSignatureKey(); TrustGraphNode n = addOrGetNode(sigKey.getKeyID(), sigKey.getLevel(), sigKey.validFrom, sigKey.validUntil); node.addKeyLogFrom(keylog.getKeyIDFrom(), TrustGraphEdge.TYPE_DISAPPROVE, keylog.getActionDatetime()); } } } catch (Exception ex) { ex.printStackTrace(); } } } public void addEdgesForKey(OSDXKey key, KeyVerificator keyverificator) { TrustGraphNode node = addOrGetNode(key.getKeyID(), key.getLevel(), key.validFrom, key.validUntil); //add parentkey if key is subkey if (key.isSub()) { MasterKey master = ((SubKey)key).getParentKey(); if (master == null) { //request at server master = keyverificator.requestParentKey((SubKey)key); } if (master!=null) { TrustGraphNode n = addOrGetNode(master.getKeyID(), master.getLevel(), master.validFrom, master.validUntil); node.addKeyLogFrom(master.getKeyID(), TrustGraphEdge.TYPE_SUBKEY, Long.MIN_VALUE); } } System.out.println("requesting keylogs for: "+key.getKeyID()); Vector<KeyLog> logs = keyverificator.requestKeyLogs(key); // request keylogs includes verification of keyserver-key, // when keyserver key is not trusted, no keylogs are found !!! Vector<KeyLog> keylogs = keyverificator.requestKeyLogs(key); for (KeyLog keylog : keylogs) { try { String action = keylog.getAction(); if (action.equals(KeyLogAction.APPROVAL)) { OSDXKey sigKey = keylog.getActionSignatureKey(); TrustGraphNode n = addOrGetNode(sigKey.getKeyID(), sigKey.getLevel(), sigKey.validFrom, sigKey.validUntil); node.addKeyLogFrom(keylog.getKeyIDFrom(), TrustGraphEdge.TYPE_APPROVE, keylog.getActionDatetime()); } else if (action.equals(KeyLogAction.REVOCATION)) { OSDXKey sigKey = keylog.getActionSignatureKey(); TrustGraphNode n = addOrGetNode(sigKey.getKeyID(), sigKey.getLevel(), sigKey.validFrom, sigKey.validUntil); node.addKeyLogFrom(keylog.getKeyIDFrom(), TrustGraphEdge.TYPE_REVOKE, keylog.getActionDatetime()); } else if (action.equals(KeyLogAction.DISAPPROVAL)) { OSDXKey sigKey = keylog.getActionSignatureKey(); TrustGraphNode n = addOrGetNode(sigKey.getKeyID(), sigKey.getLevel(), sigKey.validFrom, sigKey.validUntil); node.addKeyLogFrom(keylog.getKeyIDFrom(), TrustGraphEdge.TYPE_DISAPPROVE, keylog.getActionDatetime()); } } catch (Exception ex) { ex.printStackTrace(); } } } // private Vector<TrustGraphNode> nodes = new Vector<TrustGraphNode>(); // //private Vector<TrustGraphEdge> edges = new Vector<TrustGraphEdge>(); // private HashMap<String, TrustRatingOfKey> directRating = new HashMap<String, TrustRatingOfKey>(); // // public void addKeyRating(OSDXKey key, int trustRating) { // addOrGetNode(key); // TrustRatingOfKey tr = directRating.get(key.getKeyID()); // if (tr==null || tr.getTrustRating()!=trustRating) { // directRating.put(key.getKeyID(), new TrustRatingOfKey(key.getKeyID(), trustRating)); // //updateAllTrustRatings(); // } // } // public void removeDirectRating(OSDXKey key) { // directRating.remove(key.getKeyID()); // } // // public void removeAllDirectRatings() { // directRating.clear(); // } // // // public boolean isDirectlyTrusted(String keyid) { // TrustRatingOfKey tr = directRating.get(keyid); // if (tr!=null && tr.getTrustRating()>= TrustRatingOfKey.RATING_MARGINAL) { // return true; // } // return false; // } // // public boolean isDirectlyRated(String keyid) { // TrustRatingOfKey tr = directRating.get(keyid); // if (tr!=null) { // return true; // } // return false; // } // // private void updateAllTrustRatings(long datetime) { // //System.out.println("update trust ratings: "); // Vector<TrustGraphNode> queue = new Vector<TrustGraphNode>(); // for (TrustGraphNode n : nodes) { // n.resetTrustRating(); // } // for (TrustRatingOfKey tr : directRating.values()) { // int rating = tr.getTrustRating(); // TrustGraphNode n = getNode(tr.getKeyID()); // if (n!=null) { // n.setTrustRating(rating, true); // queue.add(n); // //System.out.println("direct trust: "+rating+" of "+tr.getKeyID()); // } // } // while (queue.size()>0) { // TrustGraphNode v = queue.remove(0); // int rating = v.getTrustRating(); // if (rating<TrustRatingOfKey.RATING_MARGINAL) rating = TrustRatingOfKey.RATING_UNKNOWN; // for (TrustGraphNode w : getKnownChilderen(v, datetime)) { // // if (w.getTrustRating()==TrustRatingOfKey.RATING_UNKNOWN && rating>=TrustRatingOfKey.RATING_MARGINAL) { // w.setTrustRating(rating, false); // queue.add(w); // } // else if (w.getTrustRating()==-999) { // w.setTrustRating(rating, false); // //System.out.println("indirect trust: "+v.getTrustRating()+" of "+w.getID()); // queue.add(w); // } // } // } // } // // public Vector<TrustGraphNode> getKnownChilderen(TrustGraphNode v, long datetime) { // Vector<TrustGraphEdge> isTrustedBy = v.getIsTrustedBy(keyverificator); // // Vector<TrustGraphNode> children = new Vector<TrustGraphNode>(); // for (TrustGraphEdge w : edges) { // if (w.from == v && w.datetime <= datetime) children.add(w.to); // } // return children; // } // // // public int getTrustRating(String keyid, long datetime) { // TrustGraphNode n = getNode(keyid); // if (n!=null) { // updateAllTrustRatings(datetime); // return n.getTrustRating(); // } // return TrustRatingOfKey.RATING_UNKNOWN; // } // // public TrustGraphNode addOrGetNode(OSDXKey key) { // String id = key.getKeyID(); // TrustGraphNode node = getNode(id); // if (node==null) { // node = new TrustGraphNode(id,this); // node.setKey(key); // nodes.add(node); // } // return node; // } // // public TrustGraphNode getNode(String keyid) { // for (TrustGraphNode n : nodes) { // if (n.getID().equals(keyid)) { // return n; // } // } // return null; // } // // public void addEdge(TrustGraphNode from, TrustGraphNode to, int type, long datetime) { // //check if already present // for (TrustGraphEdge e : edges) { // if (e.from==from && e.to==to && e.type == type) { // return; // } // } // edges.add(new TrustGraphEdge(from,to,type, datetime)); // } // // //// /** //// * implements a breadth-first-search for a trusted Node //// * @param start Node to start searching from //// * @param maxDepth maximum distance from start node //// * @returns a trusted node or null if no trusted node could be found within the given maxDetph //// */ //// public TrustGraphNode breadth_first_search_to_trusted(TrustGraphNode start, int maxDepth, KeyVerificator keyverificator) { //// return breadth_first_search_to_trusted(start, maxDepth, true, keyverificator); //// } //// //// /** //// * implements a breadth-first-traversal up to a given maxDepth //// * @param start node to start traversal from //// * @param maxDepth maximum distance from start node //// */ //// public void breadth_first_search(TrustGraphNode start, int maxDepth, KeyVerificator keyverificator) { //// breadth_first_search_to_trusted(start, maxDepth, false, keyverificator); //// } //// //// private TrustGraphNode breadth_first_search_to_trusted(TrustGraphNode start, int maxDepth, boolean stopAtTrusted, KeyVerificator keyverificator) { //// if (start.isTrusted(keyverificator)) return start; //// Vector<TrustGraphNode> queue = new Vector<TrustGraphNode>(); //// start.setVisited(true); //// start.setDepth(0); //// queue.add(start); //// while (queue.size()>0) { //// TrustGraphNode v = queue.remove(0); //// if (v.getDepth()<=maxDepth) { //// int depth = v.getDepth()+1; //// for (TrustGraphNode w : v.getIsTrustedBy(keyverificator)) { //// if (!w.isVisited()) { //// w.setVisited(true); //// w.addParent(v); //// w.setDepth(depth); //// if (stopAtTrusted && w.isTrusted(keyverificator)) return w; //// queue.add(w); //// } //// } //// } //// } //// return null; //// } //// //// public void expandNode(TrustGraphNode v, KeyVerificator keyverificator) { //// for (TrustGraphNode w : v.reloadIsTrustedBy(keyverificator)) { //// if (!w.isVisited()) { //// w.setVisited(true); //// w.addParent(v); //// } //// } //// } }