diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties index 8ba6d1bda..72562eb61 100644 --- a/resources/languages/resources.properties +++ b/resources/languages/resources.properties @@ -720,23 +720,24 @@ identity cannot
be automatically verified. \ Do you want to continue connecting?

\ For more information, click "Show Certificate". service.gui.CONTINUE_ANYWAY=Continue anyway -service.gui.CERT_INFO_ISSUED_TO=Issued To +service.gui.CERT_INFO_CHAIN=Certificate Chain: +service.gui.CERT_INFO_ISSUED_TO=Issued To service.gui.CERT_INFO_CN=Common Name: service.gui.CERT_INFO_O=Organization: service.gui.CERT_INFO_C=Country Name: service.gui.CERT_INFO_ST=State or Province Name: service.gui.CERT_INFO_L=Locality Name: -service.gui.CERT_INFO_ISSUED_BY=Issued By +service.gui.CERT_INFO_ISSUED_BY=Issued By service.gui.CERT_INFO_OU=Organizational Unit: -service.gui.CERT_INFO_VALIDITY=Validity +service.gui.CERT_INFO_VALIDITY=Validity service.gui.CERT_INFO_ISSUED_ON=Issued On: service.gui.CERT_INFO_EXPIRES_ON=Expires On: -service.gui.CERT_INFO_FINGERPRINTS=Fingerprints -service.gui.CERT_INFO_CERT_DETAILS=Certificate Info +service.gui.CERT_INFO_FINGERPRINTS=Fingerprints +service.gui.CERT_INFO_CERT_DETAILS=Certificate Info service.gui.CERT_INFO_SER_NUM=Serial Number: service.gui.CERT_INFO_VER=Version: service.gui.CERT_INFO_SIGN_ALG=Signature Algorithm: -service.gui.CERT_INFO_PUB_KEY_INFO=Public Key Info +service.gui.CERT_INFO_PUB_KEY_INFO=Public Key Info service.gui.CERT_INFO_ALG=Algorithm: service.gui.CERT_INFO_PUB_KEY=Public Key: service.gui.CERT_INFO_KEY_BYTES_PRINT={0} bytes: {1} diff --git a/src/net/java/sip/communicator/plugin/desktoputil/VerifyCertificateDialogImpl.java b/src/net/java/sip/communicator/plugin/desktoputil/VerifyCertificateDialogImpl.java index 62415b5ef..ed09959e3 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/VerifyCertificateDialogImpl.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/VerifyCertificateDialogImpl.java @@ -11,6 +11,7 @@ import java.security.cert.*; import javax.swing.*; +import javax.swing.border.*; import net.java.sip.communicator.service.certificate.*; import net.java.sip.communicator.util.*; @@ -51,9 +52,9 @@ class VerifyCertificateDialogImpl private static final int MAX_MSG_PANE_HEIGHT = 800; /** - * The certificate to show. + * The certificates to show. */ - Certificate cert; + Certificate[] certs; /** * A text that describes why the verification failed. @@ -110,8 +111,7 @@ public VerifyCertificateDialogImpl(Certificate[] certs, R.getI18NString("service.gui.CERT_DIALOG_TITLE")); setModal(true); - // for now shows only the first certificate from the chain - this.cert = certs[0]; + this.certs = certs; this.message = message; setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); @@ -224,34 +224,11 @@ private void actionShowCertificate() return; } - certPanel.setLayout(new BorderLayout()); + certPanel.setLayout(new BorderLayout(5, 5)); + certPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); certPanel.add(alwaysTrustCheckBox, BorderLayout.NORTH); - Component certInfoPane = null; - if(cert instanceof X509Certificate) - { - certInfoPane = new X509CertificatePanel((X509Certificate)cert); - } - else - { - JTextArea textArea = new JTextArea(); - textArea.setOpaque(false); - textArea.setEditable(false); - textArea.setText(cert.toString()); - certInfoPane = textArea; - } - - final JScrollPane certScroll = new JScrollPane(certInfoPane); - certScroll.setPreferredSize(new Dimension(300, 300)); - certPanel.add(certScroll, BorderLayout.CENTER); - - SwingUtilities.invokeLater(new Runnable() - { - public void run() - { - certScroll.getVerticalScrollBar().setValue(0); - } - }); + certPanel.add(new X509CertificatePanel(certs), BorderLayout.CENTER); certButton.setText(R.getI18NString("service.gui.HIDE_CERT")); diff --git a/src/net/java/sip/communicator/plugin/desktoputil/ViewCertificateFrame.java b/src/net/java/sip/communicator/plugin/desktoputil/ViewCertificateFrame.java index 3c6bf336f..943a20401 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/ViewCertificateFrame.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/ViewCertificateFrame.java @@ -39,9 +39,9 @@ public class ViewCertificateFrame private static final int MAX_MSG_PANE_HEIGHT = 800; /** - * The certificate to show. + * The certificates to show. */ - Certificate cert; + Certificate[] certs; /** * A text that describes why the verification failed. @@ -74,8 +74,7 @@ public ViewCertificateFrame(Certificate[] certs, setTitle(title != null ? title : R.getI18NString("service.gui.CERT_DIALOG_TITLE")); - // for now shows only the first certificate from the chain - this.cert = certs[0]; + this.certs = certs; this.message = message; setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); @@ -123,31 +122,8 @@ private void init() this.getContentPane().add(contentPane, BorderLayout.CENTER); - Component certInfoPane; - if(cert instanceof X509Certificate) - { - certInfoPane = new X509CertificatePanel((X509Certificate)cert); - } - else - { - JTextArea textArea = new JTextArea(); - textArea.setOpaque(false); - textArea.setEditable(false); - textArea.setText(cert.toString()); - certInfoPane = textArea; - } - - final JScrollPane certScroll = new JScrollPane(certInfoPane); - certScroll.setPreferredSize(new Dimension(300, 600)); - certPanel.add(certScroll, BorderLayout.CENTER); - - SwingUtilities.invokeLater(new Runnable() - { - public void run() - { - certScroll.getVerticalScrollBar().setValue(0); - } - }); + certPanel.add(new X509CertificatePanel(certs), BorderLayout.CENTER); + setPreferredSize(null); pack(); diff --git a/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java b/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java index dde05a449..ff4865113 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/X509CertificatePanel.java @@ -9,14 +9,18 @@ import java.awt.*; import java.security.*; import java.security.cert.*; +import java.security.cert.Certificate; import java.security.interfaces.*; -import java.text.*; import java.util.*; import javax.naming.*; import javax.naming.ldap.*; import javax.security.auth.x500.*; import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.tree.*; import org.jitsi.service.resources.*; @@ -28,42 +32,171 @@ public class X509CertificatePanel { private static final long serialVersionUID = -8368302061995971947L; + private final JEditorPane infoTextPane = new JEditorPane(); + + private final ResourceManagementService R + = DesktopUtilActivator.getResources(); + /** - * Constructs a X509 certificate panel. + * Constructs a X509 certificate panel from a single certificate. + * If a chain is available instead use the second constructor. + * This constructor is kept for backwards compatibility and for convenience + * when there is only one certificate of interest. * * @param certificate X509Certificate object */ - public X509CertificatePanel(X509Certificate certificate) + public X509CertificatePanel(Certificate certificate) + { + this(new Certificate[] + { + certificate + }); + } + + /** + * Constructs a X509 certificate panel. + * + * @param certificates X509Certificate objects + */ + public X509CertificatePanel(Certificate[] certificates) { - ResourceManagementService R = DesktopUtilActivator.getResources(); - DateFormat dateFormatter - = DateFormat.getDateInstance(DateFormat.MEDIUM); + setLayout(new BorderLayout(5, 5)); + + // Certificate chain list + TransparentPanel topPanel = new TransparentPanel(new BorderLayout()); + topPanel.add(new JLabel("" + + R.getI18NString("service.gui.CERT_INFO_CHAIN") + + ""), BorderLayout.NORTH); + + DefaultMutableTreeNode top = new DefaultMutableTreeNode(); + DefaultMutableTreeNode previous = top; + for (int i = certificates.length - 1; i >= 0; i--) + { + Certificate cert = certificates[i]; + DefaultMutableTreeNode next = new DefaultMutableTreeNode(cert); + previous.add(next); + previous = next; + } + JTree tree = new JTree(top); + tree.setBorder(new BevelBorder(BevelBorder.LOWERED)); + tree.setRootVisible(false); + tree.setExpandsSelectedPaths(true); + tree.getSelectionModel().setSelectionMode( + TreeSelectionModel.SINGLE_TREE_SELECTION); + tree.setCellRenderer(new DefaultTreeCellRenderer() + { + + @Override + public Component getTreeCellRendererComponent(JTree tree, + Object value, boolean sel, boolean expanded, boolean leaf, + int row, boolean hasFocus) + { + JLabel component = (JLabel) super.getTreeCellRendererComponent( + tree, value, sel, expanded, leaf, row, hasFocus); + if (value instanceof DefaultMutableTreeNode) + { + Object o = ((DefaultMutableTreeNode) value).getUserObject(); + if (o instanceof X509Certificate) + { + component.setText( + getSimplifiedName((X509Certificate) o)); + } + else + { + // We don't know how to represent this certificate type, + // let's use the first 20 characters + String text = o.toString(); + if (text.length() > 20) + { + text = text.substring(0, 20); + } + component.setText(text); + } + } + return component; + } + + }); + tree.getSelectionModel().addTreeSelectionListener( + new TreeSelectionListener() + { + + @Override + public void valueChanged(TreeSelectionEvent e) + { + valueChangedPerformed(e); + } + }); + tree.setSelectionPath(new TreePath((( + (DefaultTreeModel)tree.getModel()).getPathToRoot(previous)))); + topPanel.add(tree, BorderLayout.CENTER); + + add(topPanel, BorderLayout.NORTH); + + // Certificate details pane + Caret caret = infoTextPane.getCaret(); + if (caret instanceof DefaultCaret) + { + ((DefaultCaret) caret).setUpdatePolicy(DefaultCaret.NEVER_UPDATE); + } - Insets valueInsets = new Insets(2,10,0,0); - Insets titleInsets = new Insets(10,5,0,0); + /* + * Make JEditorPane respect our default font because we will be using it + * to just display text. + */ + infoTextPane.putClientProperty( + JEditorPane.HONOR_DISPLAY_PROPERTIES, + true); + + infoTextPane.setOpaque(false); + infoTextPane.setEditable(false); + infoTextPane.setContentType("text/html"); + infoTextPane.setText(toString(certificates[0])); + + final JScrollPane certScroll = new JScrollPane(infoTextPane); + certScroll.setPreferredSize(new Dimension(300, 500)); + add(certScroll, BorderLayout.CENTER); + } - setLayout(new GridBagLayout()); + /** + * Creates a String representation of the given object. + * @param certificate to print + * @return the String representation + */ + private String toString(Object certificate) + { + final StringBuilder sb = new StringBuilder(); + sb.append("\n"); - int currentRow = 0; + if (certificate instanceof X509Certificate) + { + renderX509(sb, (X509Certificate) certificate); + } + else + { + sb.append("
\n");
+            sb.append(certificate.toString());
+            sb.append("
\n"); + } - GridBagConstraints constraints = new GridBagConstraints(); - constraints.anchor = GridBagConstraints.WEST; - constraints.fill = GridBagConstraints.HORIZONTAL; - constraints.insets = new Insets(2,5,0,0); - constraints.gridx = 0; - constraints.weightx = 0; - constraints.weighty = 0; - constraints.gridy = currentRow++; + sb.append(""); + return sb.toString(); + } + /** + * Appends an HTML representation of the given X509Certificate. + * @param sb StringBuilder to append to + * @param certificate to print + */ + private void renderX509(StringBuilder sb, X509Certificate certificate) + { X500Principal issuer = certificate.getIssuerX500Principal(); X500Principal subject = certificate.getSubjectX500Principal(); - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_ISSUED_TO")), - constraints); + sb.append("\n"); // subject - constraints.insets = valueInsets; + addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_TO")); try { for(Rdn name : new LdapName(subject.getName()).getRdns()) @@ -75,47 +208,31 @@ public X509CertificatePanel(X509Certificate certificate) if ((lbl == null) || ("!" + lblKey + "!").equals(lbl)) lbl = nameType; - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel(lbl), constraints); - + final String value; Object nameValue = name.getValue(); if (nameValue instanceof byte[]) { byte[] nameValueAsByteArray = (byte[]) nameValue; - lbl + value = getHex(nameValueAsByteArray) + " (" + new String(nameValueAsByteArray) + ")"; } else - lbl = nameValue.toString(); + value = nameValue.toString(); - constraints.gridx = 1; - add(new JLabel(lbl), constraints); + addField(sb, lbl, value); } } catch (InvalidNameException ine) { - constraints.gridy = currentRow++; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_CN")), - constraints); - constraints.gridx = 1; - add( - new JLabel(subject.getName()), - constraints); + addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"), + subject.getName()); } // issuer - constraints.gridy = currentRow++; - constraints.gridx = 0; - constraints.insets = titleInsets; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_ISSUED_BY")), - constraints); - constraints.insets = valueInsets; + addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_BY")); try { for(Rdn name : new LdapName(issuer.getName()).getRdns()) @@ -127,268 +244,133 @@ public X509CertificatePanel(X509Certificate certificate) if ((lbl == null) || ("!" + lblKey + "!").equals(lbl)) lbl = nameType; - constraints.gridy = currentRow++; - constraints.gridx = 0; - constraints.gridx = 0; - add(new JLabel(lbl), constraints); - + final String value; Object nameValue = name.getValue(); if (nameValue instanceof byte[]) { byte[] nameValueAsByteArray = (byte[]) nameValue; - lbl + value = getHex(nameValueAsByteArray) + " (" + new String(nameValueAsByteArray) + ")"; } else - lbl = nameValue.toString(); + value = nameValue.toString(); - constraints.gridx = 1; - add(new JLabel(lbl), constraints); + addField(sb, lbl, value); } } catch (InvalidNameException ine) { - constraints.gridy = currentRow++; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_CN")), - constraints); - constraints.gridx = 1; - add( - new JLabel(issuer.getName()), - constraints); + addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"), + issuer.getName()); } // validity - constraints.gridy = currentRow++; - constraints.gridx = 0; - constraints.insets = titleInsets; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_VALIDITY")), - constraints); - constraints.insets = valueInsets; - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_ISSUED_ON")), - constraints); - constraints.gridx = 1; - add( - new JLabel(dateFormatter.format(certificate.getNotBefore())), - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON")), - constraints); - constraints.gridx = 1; - add( - new JLabel(dateFormatter.format(certificate.getNotAfter())), - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - constraints.insets = titleInsets; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS")), - constraints); - constraints.insets = valueInsets; + addTitle(sb, R.getI18NString("service.gui.CERT_INFO_VALIDITY")); + addField(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_ON"), + certificate.getNotBefore().toString()); + addField(sb, R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON"), + certificate.getNotAfter().toString()); + addTitle(sb, R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS")); try { String sha1String = getThumbprint(certificate, "SHA1"); String md5String = getThumbprint(certificate, "MD5"); - JTextArea sha1Area = new JTextArea(sha1String); - sha1Area.setLineWrap(false); - sha1Area.setOpaque(false); - sha1Area.setWrapStyleWord(true); - sha1Area.setEditable(false); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel("SHA1:"), - constraints); - - constraints.gridx = 1; - add( - sha1Area, - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel("MD5:"), - constraints); - - JTextArea md5Area = new JTextArea(md5String); - md5Area.setLineWrap(false); - md5Area.setOpaque(false); - md5Area.setWrapStyleWord(true); - md5Area.setEditable(false); - - constraints.gridx = 1; - add( - md5Area, - constraints); + addField(sb, "SHA1:", sha1String); + addField(sb, "MD5:", md5String); } - catch (Exception e) + catch (CertificateException e) { // do nothing as we cannot show this value } - constraints.gridy = currentRow++; - constraints.gridx = 0; - constraints.insets = titleInsets; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS")), - constraints); - constraints.insets = valueInsets; - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_SER_NUM")), - constraints); - constraints.gridx = 1; - add( - new JLabel(certificate.getSerialNumber().toString()), - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_VER")), - constraints); - constraints.gridx = 1; - add( - new JLabel(String.valueOf(certificate.getVersion())), - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_SIGN_ALG")), - constraints); - constraints.gridx = 1; - add( - new JLabel(String.valueOf(certificate.getSigAlgName())), - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - constraints.insets = titleInsets; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO")), - constraints); - constraints.insets = valueInsets; - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_ALG")), - constraints); - constraints.gridx = 1; - add( - new JLabel(certificate.getPublicKey().getAlgorithm()), - constraints); + addTitle(sb, R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS")); + + addField(sb, R.getI18NString("service.gui.CERT_INFO_SER_NUM"), + certificate.getSerialNumber().toString()); + + addField(sb, R.getI18NString("service.gui.CERT_INFO_VER"), + String.valueOf(certificate.getVersion())); + + addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN_ALG"), + String.valueOf(certificate.getSigAlgName())); + + addTitle(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO")); + + addField(sb, R.getI18NString("service.gui.CERT_INFO_ALG"), + certificate.getPublicKey().getAlgorithm()); if(certificate.getPublicKey().getAlgorithm().equals("RSA")) { RSAPublicKey key = (RSAPublicKey)certificate.getPublicKey(); - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_PUB_KEY")), - constraints); - - JTextArea pubkeyArea = new JTextArea( + addField(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY"), R.getI18NString( "service.gui.CERT_INFO_KEY_BYTES_PRINT", new String[]{ String.valueOf(key.getModulus().toByteArray().length-1), key.getModulus().toString(16) })); - pubkeyArea.setLineWrap(false); - pubkeyArea.setOpaque(false); - pubkeyArea.setWrapStyleWord(true); - pubkeyArea.setEditable(false); - - constraints.gridx = 1; - add( - pubkeyArea, - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_EXP")), - constraints); - constraints.gridx = 1; - add( - new JLabel(key.getPublicExponent().toString()), - constraints); - - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_KEY_SIZE")), - constraints); - constraints.gridx = 1; - add( - new JLabel(R.getI18NString( + + addField(sb, R.getI18NString("service.gui.CERT_INFO_EXP"), + key.getPublicExponent().toString()); + + addField(sb, R.getI18NString("service.gui.CERT_INFO_KEY_SIZE"), + R.getI18NString( "service.gui.CERT_INFO_KEY_BITS_PRINT", new String[]{ - String.valueOf(key.getModulus().bitLength())})), - constraints); + String.valueOf(key.getModulus().bitLength())})); } else if(certificate.getPublicKey().getAlgorithm().equals("DSA")) { DSAPublicKey key = (DSAPublicKey)certificate.getPublicKey(); - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel("Y:"), constraints); - - JTextArea yArea = new JTextArea(key.getY().toString(16)); - yArea.setLineWrap(false); - yArea.setOpaque(false); - yArea.setWrapStyleWord(true); - yArea.setEditable(false); - - constraints.gridx = 1; - add( - yArea, - constraints); + addField(sb, "Y:", key.getY().toString(16)); } - constraints.gridy = currentRow++; - constraints.gridx = 0; - add(new JLabel( - R.getI18NString("service.gui.CERT_INFO_SIGN")), - constraints); - - JTextArea signArea = new JTextArea( + addField(sb, R.getI18NString("service.gui.CERT_INFO_SIGN"), R.getI18NString( "service.gui.CERT_INFO_KEY_BYTES_PRINT", new String[]{ String.valueOf(certificate.getSignature().length), getHex(certificate.getSignature()) })); - signArea.setLineWrap(false); - signArea.setOpaque(false); - signArea.setWrapStyleWord(true); - signArea.setEditable(false); - - constraints.gridx = 1; - add( - signArea, - constraints); + + sb.append("
\n"); + } + + /** + * Add a title. + * + * @param sb StringBuilder to append to + * @param title to print + */ + private void addTitle(StringBuilder sb, String title) + { + sb.append("

") + .append(title).append("

\n"); + } + + /** + * Add a field. + * @param sb StringBuilder to append to + * @param field name of the certificate field + * @param value to print + */ + private void addField(StringBuilder sb, String field, String value) + { + sb.append("") + .append("") + .append(field).append("") + .append("").append(value).append("") + .append("\n"); } /** @@ -450,4 +432,62 @@ private static String getThumbprint(X509Certificate cert, String algorithm) } return sb.toString(); } + + /** + * Construct a "simplified name" based on the subject DN from the + * certificate. The purpose is to have something shorter to display in the + * list. The name used is one of the following DN parts, if + * available, otherwise the complete DN: + * 'CN', 'OU' or else 'O'. + * @param cert to read subject DN from + * @return the simplified name + */ + private static String getSimplifiedName(X509Certificate cert) + { + final HashMap parts = new HashMap(); + try + { + for (Rdn name : new LdapName( + cert.getSubjectX500Principal().getName()).getRdns()) + { + if (name.getType() != null && name.getValue() != null) + { + parts.put(name.getType(), name.getValue().toString()); + } + } + } + catch (InvalidNameException ignored) // NOPMD + { + } + + String result = parts.get("CN"); + if (result == null) + { + result = parts.get("OU"); + } + if (result == null) + { + result = parts.get("O"); + } + if (result == null) + { + result = cert.getSubjectX500Principal().getName(); + } + return result; + } + + /** + * Called when the selection changed in the tree. + * Loads the selected certificate. + * @param e the event + */ + private void valueChangedPerformed(TreeSelectionEvent e) + { + Object o = e.getNewLeadSelectionPath().getLastPathComponent(); + if (o instanceof DefaultMutableTreeNode) + { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) o; + infoTextPane.setText(toString(node.getUserObject())); + } + } }