[icedtea-web] RFC: integrate support for multiple KeyStores into the various validators
Deepak Bhole
dbhole at redhat.com
Thu Nov 11 05:42:26 PST 2010
* Omair Majid <omajid at redhat.com> [2010-11-10 17:26]:
> Hi,
>
> The attached patch makes the various parts of netx that determine
> which certificates are trusted use the multiple keystores are that
> are now available.
>
> The patch modifies VariableX509TrustManager, HTTPSCertVerfier, and
> JarSigner to use these certificate stores.
>
> The KeyTool class is almost completely unused after this patch. I
> would like to remove it at some point in the future.
>
> ChangeLog:
> 2010-11-09 Omair Majid <omajid at 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
> (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.
>
> Any thoughts or comments?
>
> Cheers,
> Omair
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/runtime/Boot.java
> --- a/netx/net/sourceforge/jnlp/runtime/Boot.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/runtime/Boot.java Tue Nov 09 09:18:48 2010 -0500
> @@ -172,20 +172,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
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java
> --- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Tue Nov 09 09:18:48 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
> + 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;
>
> }
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/security/CertWarningPane.java
> --- a/netx/net/sourceforge/jnlp/security/CertWarningPane.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/security/CertWarningPane.java Tue Nov 09 09:18:48 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,6 +65,8 @@
> 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;
>
> @@ -233,25 +238,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();
> }
> + }
> }
> + }
>
> }
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/security/CertificateUtils.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/jnlp/security/CertificateUtils.java Tue Nov 09 09:18:48 2010 -0500
> @@ -0,0 +1,145 @@
> +/* 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;
> +
> +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;
> + Random random = new Random();
> + alias = ks.getCertificateAlias(cert);
> + if (alias != null) {
> + return;
> + }
> +
> + do {
> + alias = new BigInteger(20, random).toString();
> + } while (ks.getCertificate(alias) != null);
> + ks.setCertificateEntry(alias, cert);
> + }
> +
I don't understand what is happening in the code above.. if I am not
mistaken, isn't it searching for a random string alias and will continue to
loop until something (random?) is found?
Also, those methods should not be public static as untrusted apps could
access them. The keystores shouldn't be either (if they are, either now
or from before).
> + /**
> + * 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
> + */
> + public static void dump(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
> + }
> + }
> +}
What does printRfc represent? And if it's always true, why the else?
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java
> --- a/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java Tue Nov 09 09:18:48 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;
> @@ -213,8 +214,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;
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/security/KeyStores.java
> --- a/netx/net/sourceforge/jnlp/security/KeyStores.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/security/KeyStores.java Tue Nov 09 09:18:48 2010 -0500
> @@ -189,6 +189,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()]);
> + }
> +
Should something like this be public static? Untrusted apps will be able
to access it and modify it...
> + /**
> * Returns the location of a KeyStore corresponding to the given level and type.
> * @param level
> * @param type
> @@ -334,4 +357,5 @@
> return ks;
> }
>
> +
> }
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java
> --- a/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java Tue Nov 09 09:18:48 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,96 @@
> * 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;
> + /** TrustManagers containing trusted client certificates */
> + private X509TrustManager[] clientTrustManagers = null;
>
New lines between decl, as with before please :)
> - X509TrustManager userTrustManager = null;
> - X509TrustManager caTrustManager = null;
> + private ArrayList<Certificate> temporarilyTrusted = new ArrayList<Certificate>();
> + private ArrayList<Certificate> temporarilyUntrusted = new ArrayList<Certificate>();
>
> - ArrayList<Certificate> temporarilyTrusted = new ArrayList<Certificate>();
> - 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) {
> + 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) {
> - // TODO Auto-generated catch block
> e.printStackTrace();
> }
> }
> @@ -123,18 +162,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 +258,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 +305,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()]);
> }
>
> /**
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java
> --- a/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java Tue Nov 09 09:18:48 2010 -0500
> @@ -69,6 +69,7 @@
> 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;
> @@ -357,9 +358,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());
> @@ -397,7 +397,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();
> }
> }
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/tools/JarSigner.java
> --- a/netx/net/sourceforge/jnlp/tools/JarSigner.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/tools/JarSigner.java Tue Nov 09 09:18:48 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
> diff -r f089abbcf019 netx/net/sourceforge/jnlp/tools/KeyTool.java
> --- a/netx/net/sourceforge/jnlp/tools/KeyTool.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/netx/net/sourceforge/jnlp/tools/KeyTool.java Tue Nov 09 09:18:48 2010 -0500
> @@ -119,43 +119,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 +442,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);
> diff -r f089abbcf019 plugin/icedteanp/java/sun/applet/PluginMain.java
> --- a/plugin/icedteanp/java/sun/applet/PluginMain.java Mon Nov 08 16:48:38 2010 -0500
> +++ b/plugin/icedteanp/java/sun/applet/PluginMain.java Tue Nov 09 09:18:48 2010 -0500
> @@ -215,20 +215,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());
Rest looks fine to me.
Cheers,
Deepak
More information about the distro-pkg-dev
mailing list