changeset 1486:28e58481df58

Enhanced itw-settngs' certificate viewer to show what file is backing showed certificate store. * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java: adapted to refactoring of KeyStores * netx/net/sourceforge/jnlp/security/KeyStores.java: getKeyStore now returns wrapper with path alongside with ks itself * netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java: adapted to refactoring of KeyStores * netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java: now shows read-only path to shown ks
author Jiri Vanek <jvanek@redhat.com>
date Mon, 10 Sep 2018 17:38:14 +0200
parents f136f53d661c
children 723ab7fdbc59
files ChangeLog netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java netx/net/sourceforge/jnlp/security/KeyStores.java netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java
diffstat 5 files changed, 79 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Sep 10 17:37:30 2018 +0200
+++ b/ChangeLog	Mon Sep 10 17:38:14 2018 +0200
@@ -1,3 +1,11 @@
+2018-06-20  Jiri Vanek <jvanek@redhat.com>
+
+	Enhanced itw-settngs' certificate viewer to show what file is backing showed certificate store.
+	* netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java: adapted to refactoring of KeyStores
+	* netx/net/sourceforge/jnlp/security/KeyStores.java: getKeyStore now returns wrapper with path alongside with ks itself
+	* netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java: adapted to refactoring of KeyStores
+	* netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java: now shows read-only path to shown ks
+
 2018-06-20  Jiri Vanek <jvanek@redhat.com>
 
 	* netx/net/sourceforge/jnlp/security/dialogs/CertsInfoPane.java: fixed hex output of certificate signature 
--- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Mon Sep 10 17:37:30 2018 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Mon Sep 10 17:38:14 2018 +0200
@@ -275,7 +275,7 @@
         try {
             SSLSocketFactory sslSocketFactory;
             SSLContext context = SSLContext.getInstance("SSL");
-            KeyStore ks = KeyStores.getKeyStore(KeyStores.Level.USER, KeyStores.Type.CLIENT_CERTS);
+            KeyStore ks = KeyStores.getKeyStore(KeyStores.Level.USER, KeyStores.Type.CLIENT_CERTS).getKs();
             KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
             SecurityUtil.initKeyManagerFactory(kmf, ks);
             TrustManager[] trust = new TrustManager[] { getSSLSocketTrustManager() };
--- a/netx/net/sourceforge/jnlp/security/KeyStores.java	Mon Sep 10 17:37:30 2018 +0200
+++ b/netx/net/sourceforge/jnlp/security/KeyStores.java	Mon Sep 10 17:38:14 2018 +0200
@@ -33,8 +33,7 @@
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version.
-*/
-
+ */
 package net.sourceforge.jnlp.security;
 
 import java.io.File;
@@ -64,8 +63,26 @@
  */
 public final class KeyStores {
 
+    public static class KeyStoreWithPath {
+
+        private final KeyStore ks;
+        private final String path;
+
+        public KeyStoreWithPath(KeyStore ks, String path) {
+            this.ks = ks;
+            this.path = path;
+        }
+
+        public KeyStore getKs() {
+            return ks;
+        }
+
+        public String getPath() {
+            return path;
+        }
+    }
+
     /* this gets turned into user-readable strings, see toUserReadableString */
-
     public enum Level {
         USER,
         SYSTEM,
@@ -79,10 +96,10 @@
         CLIENT_CERTS,
     }
 
-    public static final Map<Integer,String> keystoresPaths=new HashMap<>();
+    public static final Map<Integer, String> keystoresPaths = new HashMap<>();
 
     private static final String KEYSTORE_TYPE = "JKS";
-  
+
     /**
      * Returns a KeyStore corresponding to the appropriate level level (user or
      * system) and type.
@@ -92,7 +109,7 @@
      * @param type the type of KeyStore desired
      * @return a KeyStore containing certificates from the appropriate
      */
-    public static final KeyStore getKeyStore(Level level, Type type) {
+    public static final KeyStoreWithPath getKeyStore(Level level, Type type) {
         boolean create;
         if (level == Level.USER) {
             create = true;
@@ -112,7 +129,7 @@
      * @param create true if keystore can be created
      * @return a KeyStore containing certificates from the appropriate
      */
-    public static final KeyStore getKeyStore(Level level, Type type, boolean create) {
+    private static final KeyStoreWithPath getKeyStore(Level level, Type type, boolean create) {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(new AllPermission());
@@ -124,11 +141,11 @@
             ks = createKeyStoreFromFile(new File(location), create);
             //hashcode is used instead of instance so when no references are left
             //to keystore, then this will not be blocker for garbage collection
-            keystoresPaths.put(ks.hashCode(),location);
+            keystoresPaths.put(ks.hashCode(), location);
         } catch (Exception e) {
             OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e);
         }
-        return ks;
+        return new KeyStoreWithPath(ks, location);
     }
 
     public static String getPathToKeystore(int k) {
@@ -148,22 +165,22 @@
     public static final KeyStore[] getCertKeyStores() {
         List<KeyStore> result = new ArrayList<>(10);
         /* System-level JSSE certificates */
-        KeyStore ks = getKeyStore(Level.SYSTEM, Type.JSSE_CERTS);
+        KeyStore ks = getKeyStore(Level.SYSTEM, Type.JSSE_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
         /* System-level certificates */
-        ks = getKeyStore(Level.SYSTEM, Type.CERTS);
+        ks = getKeyStore(Level.SYSTEM, Type.CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
         /* User-level JSSE certificates */
-        ks = getKeyStore(Level.USER, Type.JSSE_CERTS);
+        ks = getKeyStore(Level.USER, Type.JSSE_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
         /* User-level certificates */
-        ks = getKeyStore(Level.USER, Type.CERTS);
+        ks = getKeyStore(Level.USER, Type.CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
@@ -179,22 +196,22 @@
     public static final KeyStore[] getCAKeyStores() {
         List<KeyStore> result = new ArrayList<>(10);
         /* System-level JSSE CA certificates */
-        KeyStore ks = getKeyStore(Level.SYSTEM, Type.JSSE_CA_CERTS);
+        KeyStore ks = getKeyStore(Level.SYSTEM, Type.JSSE_CA_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
         /* System-level CA certificates */
-        ks = getKeyStore(Level.SYSTEM, Type.CA_CERTS);
+        ks = getKeyStore(Level.SYSTEM, Type.CA_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
         /* User-level JSSE CA certificates */
-        ks = getKeyStore(Level.USER, Type.JSSE_CA_CERTS);
+        ks = getKeyStore(Level.USER, Type.JSSE_CA_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
         /* User-level CA certificates */
-        ks = getKeyStore(Level.USER, Type.CA_CERTS);
+        ks = getKeyStore(Level.USER, Type.CA_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
@@ -211,12 +228,12 @@
     public static KeyStore[] getClientKeyStores() {
         List<KeyStore> result = new ArrayList<>();
 
-        KeyStore ks = getKeyStore(Level.SYSTEM, Type.CLIENT_CERTS);
+        KeyStore ks = getKeyStore(Level.SYSTEM, Type.CLIENT_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
 
-        ks = getKeyStore(Level.USER, Type.CLIENT_CERTS);
+        ks = getKeyStore(Level.USER, Type.CLIENT_CERTS).getKs();
         if (ks != null) {
             result.add(ks);
         }
@@ -225,7 +242,8 @@
     }
 
     /**
-     * Returns the location of a KeyStore corresponding to the given level and type.
+     * Returns the location of a KeyStore corresponding to the given level and
+     * type.
      *
      * @param level the specified level of the key store to be returned.
      * @param type the specified type of the key store to be returned.
@@ -242,7 +260,7 @@
                     case JSSE_CERTS:
                         return PathsAndFiles.SYS_JSSECERT;
                     case CERTS:
-                         return PathsAndFiles.SYS_CERT;
+                        return PathsAndFiles.SYS_CERT;
                     case CLIENT_CERTS:
                         return PathsAndFiles.SYS_CLIENTCERT;
                 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java	Mon Sep 10 17:37:30 2018 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java	Mon Sep 10 17:38:14 2018 +0200
@@ -343,7 +343,7 @@
 
     public void saveCert() {
         try {
-            KeyStore ks = KeyStores.getKeyStore(Level.USER, Type.CERTS);
+            KeyStore ks = KeyStores.getKeyStore(Level.USER, Type.CERTS).getKs();
             X509Certificate c = (X509Certificate) parent.getCertVerifier().getPublisher(null);
             CertificateUtils.addToKeyStore(c, ks);
             File keyStoreFile = KeyStores.getKeyStoreLocation(Level.USER, Type.CERTS).getFile();
--- a/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java	Mon Sep 10 17:37:30 2018 +0200
+++ b/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java	Mon Sep 10 17:38:14 2018 +0200
@@ -68,6 +68,7 @@
 import javax.swing.JScrollPane;
 import javax.swing.JTabbedPane;
 import javax.swing.JTable;
+import javax.swing.JTextField;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.table.DefaultTableModel;
@@ -104,6 +105,7 @@
         };
 
     JTabbedPane tabbedPane;
+    JTextField certPath = new JTextField();
     private final JTable userTable;
     private final JTable systemTable;
     private JComboBox<CertificateType> certificateTypeCombo;
@@ -120,7 +122,7 @@
      * The Current KeyStore. Only one table/tab is visible for interaction to
      * the user. This KeyStore corresponds to that.
      */
-    private KeyStore keyStore = null;
+    private KeyStores.KeyStoreWithPath keyStore = null;
 
     public CertificatePane(JDialog parent) {
         super();
@@ -229,8 +231,11 @@
         }
 
         tablePanel.add(tabbedPane, BorderLayout.CENTER);
-        tablePanel.add(buttonPanel, BorderLayout.SOUTH);
-
+        JPanel buttonPanelWrapper = new JPanel(new BorderLayout());
+        certPath.setEditable(false);
+        buttonPanelWrapper.add(certPath, BorderLayout.CENTER);
+        buttonPanelWrapper.add(buttonPanel, BorderLayout.EAST);
+        tablePanel.add(buttonPanelWrapper, BorderLayout.SOUTH);
         main.add(certificateTypePanel, BorderLayout.NORTH);
         main.add(tablePanel, BorderLayout.CENTER);
 
@@ -259,9 +264,9 @@
         try {
 
             //Get all of the X509Certificates and put them into an ArrayList
-            aliases = keyStore.aliases();
+            aliases = keyStore.getKs().aliases();
             while (aliases.hasMoreElements()) {
-                Certificate c = keyStore.getCertificate(aliases.nextElement());
+                Certificate c = keyStore.getKs().getCertificate(aliases.nextElement());
                 if (c instanceof X509Certificate) {
                     certs.add((X509Certificate) c);
                 }
@@ -289,8 +294,20 @@
     private void repopulateTables() {
         initializeKeyStore();
         readKeyStore();
+        try {
+            File src = new File(keyStore.getPath());
+            File resolved = src.getCanonicalFile();
+            if (resolved.equals(src)) {
+                certPath.setText(keyStore.getPath());
+                OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, keyStore.getPath());
+            } else {
+                certPath.setText(keyStore.getPath() + " -> " + resolved.getCanonicalPath());
+                OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, keyStore.getPath() + " -> " + resolved.getCanonicalPath());
+            }
+        } catch (Exception ex) {
+            OutputController.getLogger().log(ex);
+        }
         DefaultTableModel tableModel = new DefaultTableModel(issuedToAndBy, columnNames);
-
         userTable.setModel(tableModel);
 
         tableModel = new DefaultTableModel(issuedToAndBy, columnNames);
@@ -380,7 +397,7 @@
             int returnVal = chooser.showOpenDialog(parent);
             if (returnVal == JFileChooser.APPROVE_OPTION) {
                 try {
-                    KeyStore ks = keyStore;
+                    KeyStore ks = keyStore.getKs();
                     if (currentKeyStoreType == KeyStores.Type.CLIENT_CERTS) {
                         char[] password = getPassword(R("CVImportPasswordMessage"));
                         if (password != null) {
@@ -428,16 +445,16 @@
                     JFileChooser chooser = new JFileChooser();
                     int returnVal = chooser.showOpenDialog(parent);
                     if (returnVal == JFileChooser.APPROVE_OPTION) {
-                        String alias = keyStore.getCertificateAlias(certs
+                        String alias = keyStore.getKs().getCertificateAlias(certs
                                                         .get(selectedRow));
                         if (alias != null) {
                             if (currentKeyStoreType == KeyStores.Type.CLIENT_CERTS) {
                                 char[] password = getPassword(R("CVExportPasswordMessage"));
                                 if (password != null) {
-                                    CertificateUtils.dumpPKCS12(alias, chooser.getSelectedFile(), keyStore, password);
+                                    CertificateUtils.dumpPKCS12(alias, chooser.getSelectedFile(), keyStore.getKs(), password);
                                 }
                             } else {
-                                Certificate c = keyStore.getCertificate(alias);
+                                Certificate c = keyStore.getKs().getCertificate(alias);
                                 PrintStream ps = new PrintStream(chooser.getSelectedFile().getAbsolutePath());
                                 CertificateUtils.dump(c, ps);
                             }
@@ -469,7 +486,7 @@
                 int selectedRow = table.getSelectedRow();
 
                 if (selectedRow != -1) {
-                    String alias = keyStore.getCertificateAlias(certs.get(selectedRow));
+                    String alias = keyStore.getKs().getCertificateAlias(certs.get(selectedRow));
                     if (alias != null) {
 
                         int i = JOptionPane.showConfirmDialog(parent,
@@ -477,12 +494,12 @@
                                                         R("CVRemoveConfirmTitle"),
                                                         JOptionPane.YES_NO_OPTION);
                         if (i == 0) {
-                            keyStore.deleteEntry(alias);
+                            keyStore.getKs().deleteEntry(alias);
                             File keyStoreFile = KeyStores.getKeyStoreLocation(currentKeyStoreLevel, currentKeyStoreType).getFile();
                             if (!keyStoreFile.isFile()) {
                                 FileUtils.createRestrictedFile(keyStoreFile, true);
                             }
-                            SecurityUtil.storeKeyStore(keyStore, keyStoreFile);
+                            SecurityUtil.storeKeyStore(keyStore.getKs(), keyStoreFile);
                         }
                     }
                     repopulateTables();