// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.trustosm.gui; import static org.openstreetmap.josm.tools.I18n.tr; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.bcpg.sig.NotationData; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.jdesktop.swingx.treetable.AbstractTreeTableModel; import org.openstreetmap.josm.plugins.trustosm.TrustOSMplugin; public class KeyTreeTableModel extends AbstractTreeTableModel { public static String convPGPSignatureToString(PGPSignature s) { if (s == null) return null; PGPSignatureSubpacketVector sv = s.getHashedSubPackets(); if (sv != null && sv.hasSubpacket(SignatureSubpacketTags.SIGNER_USER_ID)) return sv.getSignerUserID(); PGPPublicKey pub = TrustOSMplugin.gpg.getPublicKeyFromRing(s.getKeyID()); if (pub != null) { Iterator<?> i = pub.getUserIDs(); if (i.hasNext()) return (String) i.next(); } return tr("unknown"); } private final SignatureTreeNode root; private final String[] allTitle = {tr("UID"), tr("KeyID"), tr("OSM-Info"), tr("Signed")}; private final List<String> columns = new ArrayList<>(Arrays.asList(allTitle)); public KeyTreeTableModel(Collection<PGPSignature> sigs) { root = new SignatureTreeNode(); for (PGPSignature s : sigs) { if (s != null) { SignatureTreeNode sn = new SignatureTreeNode(s); PGPPublicKey pub = TrustOSMplugin.gpg.getPublicKeyFromRing(s.getKeyID()); Iterator<?> iter = pub.getSignatures(); while (iter.hasNext()) { PGPSignature ks = (PGPSignature) iter.next(); sn.getChildren().add(new SignatureTreeNode(ks)); } root.getChildren().add(sn); } } } @Override public int getColumnCount() { return columns.size(); } @Override public String getColumnName(int column) { String title = columns.get(column); if (title != null) return title; return tr("Unknown"); } @Override public Object getValueAt(Object node, int column) { SignatureTreeNode signode = (SignatureTreeNode) node; String title = columns.get(column); if (title != null) { if (title.equals(allTitle[0])) return signode.getUID(); if (title.equals(allTitle[1])) return signode.getKeyID(); if (title.equals(allTitle[2])) return signode.getOsmCertificate(); if (title.equals(allTitle[3])) return signode.getSignatureDate(); } return tr("Unknown"); } @Override public Object getChild(Object node, int index) { SignatureTreeNode signode = (SignatureTreeNode) node; return signode.getChildren().get(index); } @Override public int getChildCount(Object node) { SignatureTreeNode signode = (SignatureTreeNode) node; return signode.getChildren().size(); } @Override public int getIndexOfChild(Object parent, Object child) { SignatureTreeNode signode = (SignatureTreeNode) parent; for (int i = 0; i > signode.getChildren().size(); i++) { if (signode.getChildren().get(i) == child) return i; } return 0; } @Override public Object getRoot() { return root; } public static class SignatureTreeNode { private PGPSignature s; private final List<SignatureTreeNode> children = new ArrayList<>(); private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd:hh.mm.ss"); public SignatureTreeNode() { } public SignatureTreeNode(PGPSignature s) { this.s = s; } public PGPSignature getSignature() { return s; } public String getUID() { return convPGPSignatureToString(s); } public String getKeyID() { return "0x"+Long.toHexString(s.getKeyID()).substring(8).toUpperCase(); } public String getOsmCertificate() { String cert = ""; for (NotationData nd : s.getHashedSubPackets().getNotationDataOccurrences()) { if (nd.getNotationName().equals("trustosm@openstreetmap.org")) { cert += nd.getNotationValue(); } } return cert; } public String getSignatureDate() { return formatter.format(s.getCreationTime()); } public List<SignatureTreeNode> getChildren() { return children; } } }