changeset 39:e82455c47f08

integrate support for multiple KeyStores into the various validators 2010-11-11 Omair Majid <omajid@redhat.com> * netx/net/sourceforge/jnlp/runtime/Boot.java (main): Move trust manager initialization code into JNLPRuntime.initialize. * plugin/icedteanp/java/sun/applet/PluginMain.java (init): Likewise. * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java (initialize): Set the default SSL TrustManager here. * netx/net/sourceforge/jnlp/security/CertWarningPane.java (CheckBoxListener.actionPerformed): Add this certificate into user's trusted certificate store. * netx/net/sourceforge/jnlp/tools/KeyTool.java (addToKeyStore(File,KeyStore)): Move to CertificateUtils. (addToKeyStore(X509Certificate,KeyStore)): Likewise. (dumpCert): Likewise. * netx/net/sourceforge/jnlp/security/CertificateUtils.java: New class. (addToKeyStore(File,KeyStore)): Moved from KeyTool. (addToKeyStore(X509Certificate,KeyStore)): Likewise. (dumpCert): Likewise. (inKeyStores): New method. * netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java (getRootInCacerts): Check all available CA store to check if root is in CA certificates. * netx/net/sourceforge/jnlp/security/KeyStores.java (getKeyStore(Level,Type,boolean)): Add security check. (getClientKeyStores): New method. * netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java (VariableX509TrustManager): Initialize multiple CA, certificate and client trust managers. (checkClientTrusted): Check all the client TrustManagers if certificate is trusted. (checkAllManagers): Check multiple CA certificates and trusted certificates to determine if the certificate chain can be trusted. (isExplicitlyTrusted): Check with multiple TrustManagers. (getAcceptedIssuers): Gather results from multiple TrustManagers. * netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java (ImportButtonListener): Use CertificateUtils instead of KeyTool. * netx/net/sourceforge/jnlp/tools/JarSigner.java (checkTrustedCerts): Use multiple key stores to check if certificate is directly trusted and if the root is trusted.
author Omair Majid <omajid@redhat.com>
date Thu, 11 Nov 2010 11:43:13 -0500
parents 44d47c366e5f
children 4e288938e2a3
files ChangeLog netx/net/sourceforge/jnlp/runtime/Boot.java netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java netx/net/sourceforge/jnlp/security/CertWarningPane.java netx/net/sourceforge/jnlp/security/CertificateUtils.java netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java netx/net/sourceforge/jnlp/security/KeyStores.java netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java netx/net/sourceforge/jnlp/tools/JarSigner.java netx/net/sourceforge/jnlp/tools/KeyTool.java plugin/icedteanp/java/sun/applet/PluginMain.java
diffstat 12 files changed, 418 insertions(+), 187 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Nov 10 16:24:53 2010 -0500
+++ b/ChangeLog	Thu Nov 11 11:43:13 2010 -0500
@@ -1,3 +1,45 @@
+2010-11-11  Omair Majid  <omajid@redhat.com>
+
+	* netx/net/sourceforge/jnlp/runtime/Boot.java (main): Move trust
+	manager initialization code into JNLPRuntime.initialize.
+	* plugin/icedteanp/java/sun/applet/PluginMain.java
+	(init): Likewise.
+	* netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java (initialize):
+	Set the default SSL TrustManager here.
+	* netx/net/sourceforge/jnlp/security/CertWarningPane.java
+	(CheckBoxListener.actionPerformed): Add this certificate into
+	user's trusted certificate store.
+	* netx/net/sourceforge/jnlp/tools/KeyTool.java
+	(addToKeyStore(File,KeyStore)): Move to CertificateUtils.
+	(addToKeyStore(X509Certificate,KeyStore)): Likewise.
+	(dumpCert): Likewise.
+	* netx/net/sourceforge/jnlp/security/CertificateUtils.java: New
+	class.
+	(addToKeyStore(File,KeyStore)): Moved from KeyTool.
+	(addToKeyStore(X509Certificate,KeyStore)): Likewise.
+	(dumpCert): Likewise.
+	(inKeyStores): New method.
+	* netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java
+	(getRootInCacerts): Check all available CA store to check if
+	root is in CA certificates.
+	* netx/net/sourceforge/jnlp/security/KeyStores.java
+	(getKeyStore(Level,Type,boolean)): Add security check.
+	(getClientKeyStores): New method.
+	* netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java
+	(VariableX509TrustManager): Initialize multiple CA, certificate and
+	client trust managers.
+	(checkClientTrusted): Check all the client TrustManagers if
+	certificate is trusted.
+	(checkAllManagers): Check multiple CA certificates and trusted
+	certificates to determine if the certificate chain can be trusted.
+	(isExplicitlyTrusted): Check with multiple TrustManagers.
+	(getAcceptedIssuers): Gather results from multiple TrustManagers.
+	* netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java
+	(ImportButtonListener): Use CertificateUtils instead of KeyTool.
+	* netx/net/sourceforge/jnlp/tools/JarSigner.java
+	(checkTrustedCerts): Use multiple key stores to check if certificate
+	is directly trusted and if the root is trusted.
+
 2010-11-09  Omair Majid  <omajid@redhat.com>
 
 	* netx/net/sourceforge/jnlp/resources/Messages.properties: Add
--- a/netx/net/sourceforge/jnlp/runtime/Boot.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/runtime/Boot.java	Thu Nov 11 11:43:13 2010 -0500
@@ -29,11 +29,6 @@
 import java.util.Arrays;
 import java.util.List;
 
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
 import net.sourceforge.jnlp.AppletDesc;
 import net.sourceforge.jnlp.ApplicationDesc;
 import net.sourceforge.jnlp.JNLPFile;
@@ -44,7 +39,6 @@
 import net.sourceforge.jnlp.ResourcesDesc;
 import net.sourceforge.jnlp.cache.CacheUtil;
 import net.sourceforge.jnlp.cache.UpdatePolicy;
-import net.sourceforge.jnlp.security.VariableX509TrustManager;
 import net.sourceforge.jnlp.security.viewer.CertificateViewer;
 import net.sourceforge.jnlp.services.ServiceUtil;
 
@@ -172,20 +166,6 @@
             JNLPRuntime.setForksAllowed(false);
         }
 
-        // wire in custom authenticator
-        try {
-            SSLSocketFactory sslSocketFactory;
-            SSLContext context = SSLContext.getInstance("SSL");
-            TrustManager[] trust = new TrustManager[] { VariableX509TrustManager.getInstance() };
-            context.init(null, trust, null);
-            sslSocketFactory = context.getSocketFactory();
-
-            HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
-        } catch (Exception e) {
-            System.err.println("Unable to set SSLSocketfactory (may _prevent_ access to sites that should be trusted)! Continuing anyway...");
-            e.printStackTrace();
-        }
-
         JNLPRuntime.setInitialArgments(Arrays.asList(argsIn));
 
         // do in a privileged action to clear the security context of
--- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Thu Nov 11 11:43:13 2010 -0500
@@ -26,12 +26,17 @@
 import java.security.*;
 import javax.jnlp.*;
 import javax.naming.ConfigurationException;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
 import javax.swing.UIManager;
 import javax.swing.text.html.parser.ParserDelegator;
 
 import net.sourceforge.jnlp.*;
 import net.sourceforge.jnlp.cache.*;
 import net.sourceforge.jnlp.security.SecurityDialogMessageHandler;
+import net.sourceforge.jnlp.security.VariableX509TrustManager;
 import net.sourceforge.jnlp.services.*;
 import net.sourceforge.jnlp.util.*;
 
@@ -223,6 +228,20 @@
 
         securityDialogMessageHandler = startSecurityThreads();
 
+        // wire in custom authenticator for SSL connections
+        try {
+            SSLSocketFactory sslSocketFactory;
+            SSLContext context = SSLContext.getInstance("SSL");
+            TrustManager[] trust = new TrustManager[] { VariableX509TrustManager.getInstance() };
+            context.init(null, trust, null);
+            sslSocketFactory = context.getSocketFactory();
+
+            HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
+        } catch (Exception e) {
+            System.err.println("Unable to set SSLSocketfactory (may _prevent_ access to sites that should be trusted)! Continuing anyway...");
+            e.printStackTrace();
+        }
+
         initialized = true;
 
     }
--- a/netx/net/sourceforge/jnlp/security/CertWarningPane.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/security/CertWarningPane.java	Thu Nov 11 11:43:13 2010 -0500
@@ -47,6 +47,9 @@
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 
@@ -62,8 +65,9 @@
 import net.sourceforge.jnlp.JNLPFile;
 import net.sourceforge.jnlp.PluginBridge;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.security.KeyStores.Level;
+import net.sourceforge.jnlp.security.KeyStores.Type;
 import net.sourceforge.jnlp.security.SecurityWarning.AccessType;
-import net.sourceforge.jnlp.tools.KeyTool;
 
 /**
  * Provides the panel for using inside a SecurityWarningDialog. These dialogs are
@@ -232,25 +236,28 @@
                 }
         }
 
-        /**
-         * Updates the user's KeyStore of trusted Certificates.
-         */
-        private class CheckBoxListener implements ActionListener {
-                public void actionPerformed(ActionEvent e) {
-                        if (alwaysTrust != null && alwaysTrust.isSelected()) {
-                                try {
-                                        KeyTool kt = new KeyTool();
-                                        Certificate c = parent.getJarSigner().getPublisher();
-                                        kt.importCert(c);
-                                        if (JNLPRuntime.isDebug()) {
-                                            System.out.println("certificate is now permanently trusted");
-                                        }
-                                } catch (Exception ex) {
-                                        //TODO: Let NetX show a dialog here notifying user
-                                        //about being unable to add cert to keystore
-                                }
-                        }
+    /**
+     * Updates the user's KeyStore of trusted Certificates.
+     */
+    private class CheckBoxListener implements ActionListener {
+        public void actionPerformed(ActionEvent e) {
+            if (alwaysTrust != null && alwaysTrust.isSelected()) {
+                try {
+                    KeyStore ks = KeyStores.getKeyStore(Level.USER, Type.CERTS);
+                    X509Certificate c = (X509Certificate) parent.getJarSigner().getPublisher();
+                    CertificateUtils.addToKeyStore(c, ks);
+                    OutputStream os = new FileOutputStream(KeyStores.getKeyStoreLocation(Level.USER, Type.CERTS));
+                    ks.store(os, KeyStores.getPassword());
+                    if (JNLPRuntime.isDebug()) {
+                        System.out.println("certificate is now permanently trusted");
+                    }
+                } catch (Exception ex) {
+                    // TODO: Let NetX show a dialog here notifying user
+                    // about being unable to add cert to keystore
+                    ex.printStackTrace();
                 }
+            }
         }
+    }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/CertificateUtils.java	Thu Nov 11 11:43:13 2010 -0500
@@ -0,0 +1,151 @@
+/* CertificateUtils.java
+   Copyright (C) 2010 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea 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 General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+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.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Random;
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
+import sun.misc.BASE64Encoder;
+import sun.security.provider.X509Factory;
+
+/**
+ * Common utilities to manipulate certificates. Provides methods to add
+ * Certificates to a KeyStores, check if certificates already exist in a
+ * KeyStore and printing certificates.
+ */
+public class CertificateUtils {
+
+    /**
+     * Adds the X509Certficate in the file to the KeyStore. Note that it does
+     * not update the copy of the KeyStore on disk.
+     */
+    public static final void addToKeyStore(File file, KeyStore ks) throws CertificateException,
+            IOException, KeyStoreException {
+        if (JNLPRuntime.isDebug()) {
+            System.out.println("Importing certificate from " + file + " into " + ks);
+        }
+
+        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+        CertificateFactory cf = CertificateFactory.getInstance("X509");
+        X509Certificate cert = null;
+
+        try {
+            cert = (X509Certificate) cf.generateCertificate(bis);
+        } catch (ClassCastException cce) {
+            throw new CertificateException("Input file is not an X509 Certificate", cce);
+        }
+
+        addToKeyStore(cert, ks);
+    }
+
+    /**
+     * Adds an X509Certificate to the KeyStore. Note that it does not update the
+     * copy of the KeyStore on disk.
+     */
+    public static final void addToKeyStore(X509Certificate cert, KeyStore ks)
+            throws KeyStoreException {
+        if (JNLPRuntime.isDebug()) {
+            System.out.println("Importing " + cert.getSubjectX500Principal().getName());
+        }
+
+        String alias = null;
+
+        // does this certificate already exist?
+        alias = ks.getCertificateAlias(cert);
+        if (alias != null) {
+            return;
+        }
+
+        // create a unique alias for this new certificate
+        Random random = new Random();
+        do {
+            alias = new BigInteger(20, random).toString();
+        } while (ks.getCertificate(alias) != null);
+
+        ks.setCertificateEntry(alias, cert);
+    }
+
+    /**
+     * Checks whether an X509Certificate is already in one of the keystores
+     * @param c the certificate
+     * @param keyStores the KeyStores to check in
+     * @return true if the certificate is present in one of the keystores, false otherwise
+     */
+    public static final boolean inKeyStores(X509Certificate c, KeyStore[] keyStores) {
+        for (int i = 0; i < keyStores.length; i++) {
+            try {
+                if (keyStores[i].getCertificateAlias(c) != null) {
+                    if (JNLPRuntime.isDebug()) {
+                        System.out.println(c.getSubjectX500Principal().getName() + " found in cacerts");
+                    }
+                    return true;
+                }
+            } catch (KeyStoreException e) {
+                e.printStackTrace();
+                // continue
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Writes the certificate in base64 encoded from to the print stream.
+     * See http://tools.ietf.org/html/rfc4945#section-6.1 for more information
+     */
+    public static void dump(Certificate cert, PrintStream out) throws IOException,
+            CertificateException {
+
+        BASE64Encoder encoder = new BASE64Encoder();
+        out.println(X509Factory.BEGIN_CERT);
+        encoder.encodeBuffer(cert.getEncoded(), out);
+        out.println(X509Factory.END_CERT);
+    }
+}
--- a/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java	Thu Nov 11 11:43:13 2010 -0500
@@ -40,6 +40,7 @@
 import static net.sourceforge.jnlp.runtime.Translator.R;
 
 import java.io.IOException;
+import java.security.KeyStore;
 import java.security.cert.CertPath;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
@@ -52,7 +53,6 @@
 import java.util.Collection;
 import java.util.List;
 
-import net.sourceforge.jnlp.tools.KeyTool;
 import sun.security.util.DerValue;
 import sun.security.util.HostnameChecker;
 import sun.security.x509.X500Name;
@@ -213,8 +213,8 @@
 
     public boolean getRootInCacerts() {
         try {
-          KeyTool kt = new KeyTool();
-          return kt.checkCacertsForCertificate(getRoot());
+            KeyStore[] caCertsKeyStores = KeyStores.getCAKeyStores();
+            return CertificateUtils.inKeyStores((X509Certificate)getRoot(), caCertsKeyStores);
         } catch (Exception e) {
         }
         return false;
--- a/netx/net/sourceforge/jnlp/security/KeyStores.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/security/KeyStores.java	Thu Nov 11 11:43:13 2010 -0500
@@ -41,6 +41,7 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.security.AllPermission;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
@@ -111,6 +112,11 @@
      * @return a KeyStore containing certificates from the appropriate
      */
     public static final KeyStore getKeyStore(Level level, Type type, boolean create) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new AllPermission());
+        }
+
         String location = getKeyStoreLocation(level, type);
         KeyStore ks = null;
         try {
@@ -189,6 +195,29 @@
     }
 
     /**
+     * Returns KeyStores containing trusted client certificates
+     *
+     * @return an array of KeyStore objects that can be used to check client
+     * authentication certificates
+     */
+    public static KeyStore[] getClientKeyStores() {
+        List<KeyStore> result = new ArrayList<KeyStore>();
+        KeyStore ks = null;
+
+        ks = getKeyStore(Level.SYSTEM, Type.CLIENT_CERTS);
+        if (ks != null) {
+            result.add(ks);
+        }
+
+        ks = getKeyStore(Level.USER, Type.CLIENT_CERTS);
+        if (ks != null) {
+            result.add(ks);
+        }
+
+        return result.toArray(new KeyStore[result.size()]);
+    }
+
+    /**
      * Returns the location of a KeyStore corresponding to the given level and type.
      * @param level
      * @param type
@@ -336,4 +365,5 @@
         return ks;
     }
 
+
 }
--- a/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java	Thu Nov 11 11:43:13 2010 -0500
@@ -42,6 +42,8 @@
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
@@ -60,59 +62,98 @@
  * different certificates that are not in the keystore.
  */
 
-public class VariableX509TrustManager extends X509ExtendedTrustManager {
+final public class VariableX509TrustManager extends X509ExtendedTrustManager {
 
-    KeyStore userKeyStore = null;
-    KeyStore caKeyStore = null;
+    /** TrustManagers containing trusted CAs */
+    private X509TrustManager[] caTrustManagers = null;
+
+    /** TrustManagers containing trusted certificates */
+    private X509TrustManager[] certTrustManagers = null;
 
-    X509TrustManager userTrustManager = null;
-    X509TrustManager caTrustManager = null;
+    /** TrustManagers containing trusted client certificates */
+    private X509TrustManager[] clientTrustManagers = null;
 
-    ArrayList<Certificate> temporarilyTrusted = new ArrayList<Certificate>();
-    ArrayList<Certificate> temporarilyUntrusted = new ArrayList<Certificate>();
+    private ArrayList<Certificate> temporarilyTrusted = new ArrayList<Certificate>();
+    private ArrayList<Certificate> temporarilyUntrusted = new ArrayList<Certificate>();
 
-    static VariableX509TrustManager instance = null;
+    private static VariableX509TrustManager instance = null;
 
     /**
      * Constructor initializes the system, user and custom stores
      */
     public VariableX509TrustManager() {
 
+        /*
+         * Load TrustManagers for trusted certificates
+         */
         try {
-            userKeyStore = SecurityUtil.getUserKeyStore();
-            TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
-            tmFactory.init(userKeyStore);
+            /** KeyStores containing trusted certificates */
+            KeyStore[] trustedCertKeyStores = KeyStores.getCertKeyStores();
+            certTrustManagers = new X509TrustManager[trustedCertKeyStores.length];
 
-            // tm factory initialized, now get the managers so we can assign the X509 one
-            TrustManager[] trustManagers = tmFactory.getTrustManagers();
+            for (int j = 0; j < trustedCertKeyStores.length; j++) {
+                TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
+                tmFactory.init(trustedCertKeyStores[j]);
 
-            for (int i=0; i < trustManagers.length; i++) {
-                if (trustManagers[i] instanceof X509TrustManager) {
-                    userTrustManager = (X509TrustManager) trustManagers[i];
+                // tm factory initialized, now get the managers so we can assign the X509 one
+                TrustManager[] trustManagers = tmFactory.getTrustManagers();
+
+                for (int i = 0; i < trustManagers.length; i++) {
+                    if (trustManagers[i] instanceof X509TrustManager) {
+                        certTrustManagers[j] = (X509TrustManager) trustManagers[i];
+                    }
                 }
             }
-
         } catch (Exception e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
 
+        /*
+         * Load TrustManagers for trusted CAs
+         */
         try {
-            caKeyStore = SecurityUtil.getCacertsKeyStore();
-            TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
-            tmFactory.init(caKeyStore);
+            /** KeyStores containing trusted CAs */
+            KeyStore[] trustedCAKeyStores = KeyStores.getCAKeyStores();
+            caTrustManagers = new X509TrustManager[trustedCAKeyStores.length];
 
-            // tm factory initialized, now get the managers so we can extract the X509 one
-            TrustManager[] trustManagers = tmFactory.getTrustManagers();
+            for (int j = 0; j < caTrustManagers.length; j++) {
+                TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
+                tmFactory.init(trustedCAKeyStores[j]);
 
-            for (int i=0; i < trustManagers.length; i++) {
-                if (trustManagers[i] instanceof X509TrustManager) {
-                    caTrustManager = (X509TrustManager) trustManagers[i];
+                // tm factory initialized, now get the managers so we can extract the X509 one
+                TrustManager[] trustManagers = tmFactory.getTrustManagers();
+
+                for (int i=0; i < trustManagers.length; i++) {
+                    if (trustManagers[i] instanceof X509TrustManager) {
+                        caTrustManagers[j] = (X509TrustManager) trustManagers[i];
+                    }
                 }
             }
-
         } catch (Exception e) {
-            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        /*
+         * Load TrustManagers for trusted clients certificates
+         */
+        try {
+            KeyStore[] clientKeyStores = KeyStores.getClientKeyStores();
+            clientTrustManagers = new X509TrustManager[clientKeyStores.length];
+
+            for (int j = 0; j < clientTrustManagers.length; j++) {
+                TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
+                tmFactory.init(clientKeyStores[j]);
+
+                // tm factory initialized, now get the managers so we can extract the X509 one
+                TrustManager[] trustManagers = tmFactory.getTrustManagers();
+
+                for (int i=0; i < trustManagers.length; i++) {
+                    if (trustManagers[i] instanceof X509TrustManager) {
+                        clientTrustManagers[j] = (X509TrustManager) trustManagers[i];
+                    }
+                }
+            }
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -123,18 +164,23 @@
     public void checkClientTrusted(X509Certificate[] chain, String authType,
                                    String hostName, String algorithm)
             throws CertificateException {
-        // First try catrustmanager, then try usertrustmanager
-        try {
-            caTrustManager.checkClientTrusted(chain, authType);
-        } catch (Exception caex) {
+
+        boolean trusted = false;
+        ValidatorException savedException = null;
+        for (int i = 0; i < clientTrustManagers.length; i++) {
             try {
-                userTrustManager.checkClientTrusted(chain, authType);
-            } catch (Exception userex) {
-                // Do nothing here. This trust manager is intended to be used
-                // only in the plugin instance vm, which does not act as a
-                // server
+                clientTrustManagers[i].checkClientTrusted(chain, authType);
+                trusted = true;
+                break;
+            } catch (ValidatorException caex) {
+                savedException = caex;
             }
         }
+        if (trusted) {
+            return;
+        }
+
+        throw savedException;
     }
 
     public void checkClientTrusted(X509Certificate[] chain, String authType)
@@ -214,17 +260,45 @@
      * Check system, user and custom trust manager
      */
     private void checkAllManagers(X509Certificate[] chain, String authType) throws CertificateException {
-        // First try catrustmanager, then try usertrustmanager, and finally, check temp trusted certs
-        try {
-            caTrustManager.checkServerTrusted(chain, authType);
-        } catch (ValidatorException caex) {
+        // first try CA TrustManagers
+        boolean trusted = false;
+        ValidatorException savedException = null;
+        for (int i = 0; i < caTrustManagers.length; i++) {
             try {
-                userTrustManager.checkServerTrusted(chain, authType);
-            } catch (ValidatorException uex) {
-                if (!temporarilyTrusted.contains(chain[0]))
-                    throw (CertificateException) uex;
+                caTrustManagers[i].checkServerTrusted(chain, authType);
+                trusted = true;
+                break;
+            } catch (ValidatorException caex) {
+                savedException = caex;
             }
         }
+        if (trusted) {
+            return;
+        }
+
+        // then try certificate TrustManagers
+        for (int i = 0; i < certTrustManagers.length; i++) {
+            try {
+                certTrustManagers[i].checkServerTrusted(chain, authType);
+                trusted = true;
+                break;
+            } catch (ValidatorException caex) {
+                savedException = caex;
+            }
+        }
+        if (trusted) {
+            return;
+        }
+
+        // finally check temp trusted certs
+        if (!temporarilyTrusted.contains(chain[0])) {
+            if (savedException == null) {
+                // System.out.println("IMPOSSIBLE!");
+                throw new ValidatorException(ValidatorException.T_SIGNATURE_ERROR, chain[0]);
+            }
+            throw savedException;
+        }
+
     }
 
     /**
@@ -233,23 +307,32 @@
     private boolean isExplicitlyTrusted(X509Certificate[] chain, String authType) {
         boolean explicitlyTrusted = false;
 
-        try {
-            userTrustManager.checkServerTrusted(chain, authType);
-            explicitlyTrusted = true;
-        } catch (ValidatorException uex) {
-            if (temporarilyTrusted.contains(chain[0]))
+        for (int i = 0; i < certTrustManagers.length; i++) {
+            try {
+                certTrustManagers[i].checkServerTrusted(chain, authType);
                 explicitlyTrusted = true;
-        } catch (CertificateException ce) {
-            // do nothing, this means that the cert is not explicitly trusted
+                break;
+            } catch (ValidatorException uex) {
+                if (temporarilyTrusted.contains(chain[0])) {
+                    explicitlyTrusted = true;
+                    break;
+                }
+            } catch (CertificateException ce) {
+                // not explicitly trusted
+            }
         }
 
         return explicitlyTrusted;
-
     }
 
     public X509Certificate[] getAcceptedIssuers() {
-        // delegate to default
-        return caTrustManager.getAcceptedIssuers();
+        List<X509Certificate> issuers = new ArrayList<X509Certificate>();
+
+        for (int i = 0; i < caTrustManagers.length; i++) {
+            issuers.addAll(Arrays.asList(caTrustManagers[i].getAcceptedIssuers()));
+        }
+
+        return issuers.toArray(new X509Certificate[issuers.size()]);
     }
 
     /**
--- a/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java	Thu Nov 11 11:43:13 2010 -0500
@@ -71,11 +71,11 @@
 import javax.swing.event.ChangeListener;
 import javax.swing.table.DefaultTableModel;
 
+import net.sourceforge.jnlp.security.CertificateUtils;
 import net.sourceforge.jnlp.security.KeyStores;
 import net.sourceforge.jnlp.security.SecurityUtil;
 import net.sourceforge.jnlp.security.SecurityWarningDialog;
 import net.sourceforge.jnlp.security.KeyStores.Level;
-import net.sourceforge.jnlp.tools.KeyTool;
 
 public class CertificatePane extends JPanel {
 
@@ -359,9 +359,8 @@
                 int returnVal = chooser.showOpenDialog(parent);
                 if(returnVal == JFileChooser.APPROVE_OPTION) {
                         try {
-                                KeyTool kt = new KeyTool();
                                 KeyStore ks = keyStore;
-                                kt.addToKeyStore(chooser.getSelectedFile(), ks);
+                                CertificateUtils.addToKeyStore(chooser.getSelectedFile(), ks);
                                 OutputStream os = new FileOutputStream(
                                         KeyStores.getKeyStoreLocation(currentKeyStoreLevel, currentKeyStoreType));
                                 ks.store(os, KeyStores.getPassword());
@@ -399,7 +398,7 @@
                                         if (alias != null) {
                                                 Certificate c = keyStore.getCertificate(alias);
                                                 PrintStream ps = new PrintStream(chooser.getSelectedFile().getAbsolutePath());
-                                                KeyTool.dumpCert(c, ps);
+                                                CertificateUtils.dump(c, ps);
                                                 repopulateTables();
                                         }
                                 }
--- a/netx/net/sourceforge/jnlp/tools/JarSigner.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/tools/JarSigner.java	Thu Nov 11 11:43:13 2010 -0500
@@ -371,9 +371,12 @@
     private void checkTrustedCerts() throws Exception {
         if (certPath != null) {
                 try {
-                        KeyTool kt = new KeyTool();
-                        alreadyTrustPublisher = kt.isTrusted(getPublisher());
-                                rootInCacerts = kt.checkCacertsForCertificate(getRoot());
+                        X509Certificate publisher = (X509Certificate) getPublisher();
+                        KeyStore[] certKeyStores = KeyStores.getCertKeyStores();
+                        alreadyTrustPublisher = CertificateUtils.inKeyStores(publisher, certKeyStores);
+                        X509Certificate root = (X509Certificate) getRoot();
+                        KeyStore[] caKeyStores = KeyStores.getCAKeyStores();
+                        rootInCacerts = CertificateUtils.inKeyStores(root, caKeyStores);
                 } catch (Exception e) {
                         // TODO: Warn user about not being able to
                         // look through their cacerts/trusted.certs
--- a/netx/net/sourceforge/jnlp/tools/KeyTool.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/netx/net/sourceforge/jnlp/tools/KeyTool.java	Thu Nov 11 11:43:13 2010 -0500
@@ -29,12 +29,8 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.PrintStream;
-import java.math.BigInteger;
 import java.security.KeyStore;
-import java.security.KeyStoreException;
 import java.security.MessageDigest;
 import java.security.PublicKey;
 import java.security.cert.Certificate;
@@ -49,9 +45,6 @@
 
 import net.sourceforge.jnlp.security.SecurityUtil;
 
-import sun.misc.BASE64Encoder;
-import sun.security.provider.X509Factory;
-
 /**
  * This tool manages the user's trusted certificates
  *
@@ -76,11 +69,6 @@
          */
         private boolean trustcacerts = true;
 
-        /**
-         * Whether we print certificates in rfc, base64 encoding.
-         */
-        private boolean rfc = true;
-
         private final char[] password = "changeit".toCharArray();
 
         /**
@@ -119,43 +107,6 @@
                 return importCert((Certificate)cert);
         }
 
-    /**
-     * Adds the X509Certficate in the file to the KeyStore
-     */
-    public final void addToKeyStore(File file, KeyStore ks) throws CertificateException,
-            IOException, KeyStoreException {
-        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
-        CertificateFactory cf = CertificateFactory.getInstance("X509");
-        X509Certificate cert = null;
-
-        try {
-            cert = (X509Certificate) cf.generateCertificate(bis);
-        } catch (ClassCastException cce) {
-            throw new CertificateException("Input file is not an X509 Certificate", cce);
-        }
-
-        addToKeyStore(cert, ks);
-
-    }
-
-    /**
-     * Adds an X509Certificate to the KeyStore
-     */
-    public final void addToKeyStore(X509Certificate cert, KeyStore ks) throws KeyStoreException {
-        String alias = null;
-        Random random = new Random();
-        alias = ks.getCertificateAlias(cert);
-        // already in keystore; done
-        if (alias != null) {
-            return;
-        }
-
-        do {
-            alias = new BigInteger(20, random).toString();
-        } while (ks.getCertificate(alias) != null);
-        ks.setCertificateEntry(alias, cert);
-    }
-
         /**
          * Adds a trusted certificate to the user's keystore.
          * @return true if the add was successful, false otherwise.
@@ -479,20 +430,6 @@
         return false;
     }
 
-    public static void dumpCert(Certificate cert, PrintStream out)
-        throws IOException, CertificateException {
-
-        boolean printRfc = true;
-        if (printRfc) {
-            BASE64Encoder encoder = new BASE64Encoder();
-            out.println(X509Factory.BEGIN_CERT);
-            encoder.encodeBuffer(cert.getEncoded(), out);
-            out.println(X509Factory.END_CERT);
-        } else {
-            out.write(cert.getEncoded()); // binary
-        }
-    }
-
         public static void main(String[] args) throws Exception {
                 KeyTool kt = new KeyTool();
                 kt.doPrintEntries(System.out);
--- a/plugin/icedteanp/java/sun/applet/PluginMain.java	Wed Nov 10 16:24:53 2010 -0500
+++ b/plugin/icedteanp/java/sun/applet/PluginMain.java	Thu Nov 11 11:43:13 2010 -0500
@@ -75,14 +75,8 @@
 import java.util.Enumeration;
 import java.util.Properties;
 
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
 import net.sourceforge.jnlp.runtime.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
-import net.sourceforge.jnlp.security.VariableX509TrustManager;
 
 /**
  * The main entry point into PluginAppletViewer.
@@ -215,20 +209,6 @@
 		// INSTALL THE PROPERTY LIST
 		System.setProperties(avProps);
 
-
-		try {
-		    SSLSocketFactory sslSocketFactory;
-		    SSLContext context = SSLContext.getInstance("SSL");
-		    TrustManager[] trust = new TrustManager[] { VariableX509TrustManager.getInstance() };
-		    context.init(null, trust, null);
-		    sslSocketFactory = context.getSocketFactory();
-		    
-		    HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
-		} catch (Exception e) {
-		    System.err.println("Unable to set SSLSocketfactory (may _prevent_ access to sites that should be trusted)! Continuing anyway...");
-		    e.printStackTrace();
-		}
-
 		// plug in a custom authenticator and proxy selector
         Authenticator.setDefault(new CustomAuthenticator());
         ProxySelector.setDefault(new PluginProxySelector());