Backport fix for PR1161 to icedtea-web 1.3

Deepak Bhole dbhole at redhat.com
Wed Oct 10 14:18:23 PDT 2012


Hi,

I would like to backport the fix for PR1161 to icedtea-web 1.3 in order
to do a new release. The issue affects icedtea-web running on Java 7:

http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-September/020228.html
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1161

I am attaching the final approved version that went into head. It
applies to 1.3 with some fuzz. OK for 1.3?

ChangeLog:

    PR1161: X509VariableTrustManager does not work correctly with OpenJDK7
    * Makefile.am: If building with JDK 6, don't build
    VariableX509TrustManagerJDK7.
    * NEWS: Updated.
    * acinclude.m4: In addition to setting VERSION_DEFS, also set HAVE_JAVA7
    if building with JDK7.
    * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java (initialize): Use new
    getSSLSocketTrustManager() method to get the trust manager.
    (getSSLSocketTrustManager): New method. Depending on runtime JRE version,
    returns the appropriate trust manager.
    * netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java: Removed
    unused tm variable.
    * netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java: No
    longer extends com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager.
    (checkClientTrusted): Renamed to checkTrustClient and removed overloaded
    implementations.
    (checkServerTrusted): Renamed to checkTrustServer. Also, modified to
    accept socket and engine (may be null). Assume that CN is mismatched by
    default, rather than matched. If explicitly trusted, bypass other checks,
    including CN mismatch.
    (checkAllManagers): Modified to accept socket and engine. Modified to work
    for both JDK6 and JDK7.
    (getAcceptedIssuers): Make protected (called by others in package).
    * netx/net/sourceforge/jnlp/security/VariableX509TrustManagerJDK6.java:
    New class -- X509TrustManager for JDK6.
    * netx/net/sourceforge/jnlp/security/VariableX509TrustManagerJDK7.java:
    New class -- X509TrustManager for JDK7.


Thanks,
Deepak
-------------- next part --------------
diff -r 439f0b1cee5c Makefile.am
--- a/Makefile.am	Fri Sep 07 17:06:08 2012 -0400
+++ b/Makefile.am	Mon Sep 17 15:12:13 2012 -0400
@@ -348,6 +348,9 @@
 if !WITH_RHINO
 	sed -i '/RhinoBasedPacEvaluator/ d' $@
 endif
+if !HAVE_JAVA7
+	sed -i '/VariableX509TrustManagerJDK7/ d' $@
+endif
 
 stamps/netx.stamp: netx-source-files.txt stamps/bootstrap-directory.stamp
 	mkdir -p $(NETX_DIR)
diff -r 439f0b1cee5c NEWS
--- a/NEWS	Fri Sep 07 17:06:08 2012 -0400
+++ b/NEWS	Mon Sep 17 15:12:13 2012 -0400
@@ -17,6 +17,7 @@
 * Common
   - PR1049: Extension jnlp's signed jar with the content of only META-INF/* is considered
   - PR955: regression: SweetHome3D fails to run
+  - PR1161: X509VariableTrustManager does not work correctly with OpenJDK7
 
 New in release 1.3 (2012-XX-XX):
 * NetX
diff -r 439f0b1cee5c acinclude.m4
--- a/acinclude.m4	Fri Sep 07 17:06:08 2012 -0400
+++ b/acinclude.m4	Mon Sep 17 15:12:13 2012 -0400
@@ -715,9 +715,12 @@
   AC_MSG_RESULT(${JAVA})
   AC_SUBST(JAVA)
   JAVA_VERSION=`$JAVA -version 2>&1 | sed -n '1s/@<:@^"@:>@*"\(.*\)"$/\1/p'`
-  case "${JAVA_VERSION}" in
-    1.7*) VERSION_DEFS='-DHAVE_JAVA7';;
-  esac
+  HAVE_JAVA7=`echo $JAVA_VERSION | awk '{if ($(0) >= 1.7) print "yes"}'`
+  if  ! test -z "$HAVE_JAVA7" ; then
+    VERSION_DEFS='-DHAVE_JAVA7'
+  fi
+
+  AM_CONDITIONAL([HAVE_JAVA7], test x"${HAVE_JAVA7}" = "xyes" )
   AC_SUBST(VERSION_DEFS)
 ])
 
diff -r 439f0b1cee5c netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Fri Sep 07 17:06:08 2012 -0400
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Mon Sep 17 15:12:13 2012 -0400
@@ -16,38 +16,59 @@
 
 package net.sourceforge.jnlp.runtime;
 
-import java.io.*;
+import java.awt.EventQueue;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 import java.net.Authenticator;
 import java.net.ProxySelector;
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
-import java.awt.*;
-import java.text.*;
-import java.util.*;
+import java.security.AllPermission;
+import java.security.KeyStore;
+import java.security.Policy;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.text.MessageFormat;
 import java.util.List;
-import java.security.*;
-import javax.jnlp.*;
+import java.util.ResourceBundle;
+
+import javax.jnlp.ServiceManager;
 import javax.naming.ConfigurationException;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
 import javax.swing.UIManager;
 import javax.swing.text.html.parser.ParserDelegator;
 
-import sun.net.www.protocol.jar.URLJarFile;
-
-import net.sourceforge.jnlp.*;
+import net.sourceforge.jnlp.DefaultLaunchHandler;
+import net.sourceforge.jnlp.GuiLaunchHandler;
+import net.sourceforge.jnlp.LaunchHandler;
+import net.sourceforge.jnlp.Launcher;
 import net.sourceforge.jnlp.browser.BrowserAwareProxySelector;
-import net.sourceforge.jnlp.cache.*;
+import net.sourceforge.jnlp.cache.CacheUtil;
+import net.sourceforge.jnlp.cache.DefaultDownloadIndicator;
+import net.sourceforge.jnlp.cache.DownloadIndicator;
+import net.sourceforge.jnlp.cache.UpdatePolicy;
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.security.JNLPAuthenticator;
 import net.sourceforge.jnlp.security.KeyStores;
 import net.sourceforge.jnlp.security.SecurityDialogMessageHandler;
 import net.sourceforge.jnlp.security.VariableX509TrustManager;
-import net.sourceforge.jnlp.services.*;
-import net.sourceforge.jnlp.util.*;
+import net.sourceforge.jnlp.services.XServiceManagerStub;
+import net.sourceforge.jnlp.util.FileUtils;
+import net.sourceforge.jnlp.util.TeeOutputStream;
+import sun.net.www.protocol.jar.URLJarFile;
 
 /**
  * Configure and access the runtime environment.  This class
@@ -223,7 +244,7 @@
             KeyStore ks = KeyStores.getKeyStore(KeyStores.Level.USER, KeyStores.Type.CLIENT_CERTS);
             KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
             kmf.init(ks, KeyStores.getPassword());
-            TrustManager[] trust = new TrustManager[] { VariableX509TrustManager.getInstance() };
+            TrustManager[] trust = new TrustManager[] { getSSLSocketTrustManager() };
             context.init(kmf.getKeyManagers(), trust, null);
             sslSocketFactory = context.getSocketFactory();
 
@@ -248,6 +269,52 @@
     }
 
     /**
+     * Returns a TrustManager ideal for the running VM.
+     *
+     * @return TrustManager the trust manager to use for verifying https certificates
+     */
+    private static TrustManager getSSLSocketTrustManager() throws
+                                ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
+
+        try {
+
+            Class<?> trustManagerClass;
+            Constructor<?> tmCtor = null;
+
+            if (System.getProperty("java.version").startsWith("1.6")) { // Java 6
+                try {
+                    trustManagerClass = Class.forName("net.sourceforge.jnlp.security.VariableX509TrustManagerJDK6");
+                 } catch (ClassNotFoundException cnfe) {
+                     System.err.println("Unable to find class net.sourceforge.jnlp.security.VariableX509TrustManagerJDK6");
+                     return null;
+                 }
+            } else { // Java 7 or more (technically could be <= 1.5 but <= 1.5 is unsupported)
+                try {
+                    trustManagerClass = Class.forName("net.sourceforge.jnlp.security.VariableX509TrustManagerJDK7");
+                 } catch (ClassNotFoundException cnfe) {
+                     System.err.println("Unable to find class net.sourceforge.jnlp.security.VariableX509TrustManagerJDK7");
+                     return null;
+                 }
+            }
+
+            Constructor<?>[] tmCtors = trustManagerClass.getDeclaredConstructors();
+            tmCtor = tmCtors[0];
+
+            for (Constructor<?> ctor : tmCtors) {
+                if (tmCtor.getGenericParameterTypes().length == 0) {
+                    tmCtor = ctor;
+                    break;
+                }
+            }
+
+            return (TrustManager) tmCtor.newInstance();
+        } catch (RuntimeException e) {
+            System.err.println("Unable to load JDK-specific TrustManager. Was this version of IcedTea-Web compiled with JDK6?");
+            throw e;
+        }
+    }
+
+    /**
      * This must NOT be called form the application ThreadGroup. An application
      * can inject events into its {@link EventQueue} and bypass the security
      * dialogs.
diff -r 439f0b1cee5c netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java
--- a/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java	Fri Sep 07 17:06:08 2012 -0400
+++ b/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java	Mon Sep 17 15:12:13 2012 -0400
@@ -59,7 +59,6 @@
 
 public class HttpsCertVerifier implements CertVerifier {
 
-    private VariableX509TrustManager tm;
     private X509Certificate[] chain;
     private String authType;
     private String hostName;
@@ -67,11 +66,9 @@
     private boolean hostMatched;
     private ArrayList<String> details = new ArrayList<String>();
 
-    public HttpsCertVerifier(VariableX509TrustManager tm,
-                             X509Certificate[] chain, String authType,
+    public HttpsCertVerifier(X509Certificate[] chain, String authType,
                              boolean isTrusted, boolean hostMatched,
                              String hostName) {
-        this.tm = tm;
         this.chain = chain;
         this.authType = authType;
         this.hostName = hostName;
diff -r 439f0b1cee5c netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java
--- a/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java	Fri Sep 07 17:06:08 2012 -0400
+++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java	Mon Sep 17 15:12:13 2012 -0400
@@ -37,6 +37,9 @@
 
 package net.sourceforge.jnlp.security;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.Socket;
 import java.security.AccessController;
 import java.security.KeyStore;
 import java.security.PrivilegedAction;
@@ -47,25 +50,24 @@
 import java.util.Arrays;
 import java.util.List;
 
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.security.SecurityDialogs.AccessType;
 import sun.security.util.HostnameChecker;
 import sun.security.validator.ValidatorException;
 
-import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
-import net.sourceforge.jnlp.runtime.JNLPRuntime;
-
-import net.sourceforge.jnlp.security.SecurityDialogs.AccessType;
-
 /**
  * This class implements an X509 Trust Manager. The certificates it trusts are
  * "variable", in the sense that it can dynamically, and temporarily support
  * different certificates that are not in the keystore.
  */
 
-final public class VariableX509TrustManager extends X509ExtendedTrustManager {
+final public class VariableX509TrustManager {
 
     /** TrustManagers containing trusted CAs */
     private X509TrustManager[] caTrustManagers = null;
@@ -164,8 +166,8 @@
     /**
      * Check if client is trusted (no support for custom here, only system/user)
      */
-    public void checkClientTrusted(X509Certificate[] chain, String authType,
-                                   String hostName, String algorithm)
+    public void checkTrustClient(X509Certificate[] chain, String authType,
+                                   String hostName)
             throws CertificateException {
 
         boolean trusted = false;
@@ -186,99 +188,125 @@
         throw savedException;
     }
 
-    public void checkClientTrusted(X509Certificate[] chain, String authType)
-            throws CertificateException {
-        checkClientTrusted(chain, authType, null, null);
-    }
-
-    public void checkServerTrusted(X509Certificate[] chain, String authType,
-                                   String hostName, String algorithm)
-            throws CertificateException {
-        checkServerTrusted(chain, authType, hostName, false);
-    }
-
-    public void checkServerTrusted(X509Certificate[] chain, String authType)
-            throws CertificateException {
-        checkServerTrusted(chain, authType, null, null);
-    }
-
     /**
-     * Check if the server is trusted
+     * Check if the server is trusted.
+     *
+     * First, existing stores are checked to see if the certificate is trusted.
+     * Next, if the certificate is not explicitly trusted by the user, a host
+     * name check is performed. The user is them prompted as needed.
      *
      * @param chain The cert chain
      * @param authType The auth type algorithm
-     * @param checkOnly Whether to "check only" i.e. no user prompt, or to prompt for permission
+     * @param hostName The expected hostName that the server should have
+     * @param socket The SSLSocket in use (may be null)
+     * @param ending The SSLEngine in use (may be null)
      */
-    public synchronized void checkServerTrusted(X509Certificate[] chain,
+    public synchronized void checkTrustServer(X509Certificate[] chain,
                              String authType, String hostName,
-                             boolean checkOnly) throws CertificateException {
+                             SSLSocket socket, SSLEngine engine) throws CertificateException {
         CertificateException ce = null;
         boolean trusted = true;
-        boolean CNMatched = true;
+        boolean CNMatched = false;
 
+        // Check trust stores
         try {
-            checkAllManagers(chain, authType);
+            checkAllManagers(chain, authType, socket, engine);
         } catch (CertificateException e) {
             trusted = false;
             ce = e;
         }
 
         // If the certificate is not explicitly trusted, we
-        // need to prompt the user
+        // check host match
         if (!isExplicitlyTrusted(chain, authType)) {
-
-            if (hostName == null) {
-                CNMatched = false;
-            } else {
+            if (hostName != null) {
                 try {
                     HostnameChecker checker = HostnameChecker
                             .getInstance(HostnameChecker.TYPE_TLS);
 
-                    checker.match(hostName, chain[0]); // only need to match @ 0 for
-                                                       // CN
+                    checker.match(hostName, chain[0]); // only need to match @ 0 for CN
 
+                    CNMatched = true;
                 } catch (CertificateException e) {
-                    CNMatched = false;
                     ce = e;
                 }
             }
+        } else {
+            // If it is explicitly trusted, just return right away.
+            return;
         }
 
+        // If it is (not explicitly trusted) AND
+        // ((it is not in store) OR (there is a host mismatch))
         if (!trusted || !CNMatched) {
-            if (checkOnly) {
-                throw ce;
-            } else {
-                if (!isTemporarilyUntrusted(chain[0])) {
-                    boolean b = askUser(chain, authType, trusted, CNMatched, hostName);
+            if (!isTemporarilyUntrusted(chain[0])) {
+                boolean b = askUser(chain, authType, trusted, CNMatched, hostName);
 
-                    if (b) {
-                        temporarilyTrust(chain[0]);
-                    } else {
-                        temporarilyUntrust(chain[0]);
-                    }
+                if (b) {
+                    temporarilyTrust(chain[0]);
+                    return;
+                } else {
+                    temporarilyUntrust(chain[0]);
                 }
+            }
 
-                checkAllManagers(chain, authType);
-            }
+            throw ce;
         }
     }
 
     /**
-     * Check system, user and custom trust manager
+     * Check system, user and custom trust manager.
+     *
+     * This method is intended to work with both, JRE6 and JRE7. If socket
+     * and engine are null, it assumes that the call is for JRE6 (i.e. not
+     * javax.net.ssl.X509ExtendedTrustManager which is Java 7 specific). If
+     * either of those are not null, it will assume that the caTrustManagers
+     * are javax.net.ssl.X509ExtendedTrustManager instances and will
+     * invoke their check methods.
+     *
+     * @param chain The certificate chain
+     * @param authType The authentication type
+     * @param socket the SSLSocket being used for the connection
+     * @param engine the SSLEngine being used for the connection
      */
-    private void checkAllManagers(X509Certificate[] chain, String authType) throws CertificateException {
+    private void checkAllManagers(X509Certificate[] chain, String authType, Socket socket, SSLEngine engine) throws CertificateException {
+
         // first try CA TrustManagers
         boolean trusted = false;
         ValidatorException savedException = null;
         for (int i = 0; i < caTrustManagers.length; i++) {
             try {
-                caTrustManagers[i].checkServerTrusted(chain, authType);
+                if (socket == null && engine == null) {
+                    caTrustManagers[i].checkServerTrusted(chain, authType);
+                } else {
+
+                    try {
+                        Class<?> x509ETMClass = Class.forName("javax.net.ssl.X509ExtendedTrustManager");
+                        if (engine == null) {
+                            Method mcheckServerTrusted = x509ETMClass.getDeclaredMethod("checkServerTrusted", X509Certificate[].class, String.class, Socket.class);
+                            mcheckServerTrusted.invoke(caTrustManagers[i], chain, authType, socket);
+                        } else {
+                            Method mcheckServerTrusted = x509ETMClass.getDeclaredMethod("checkServerTrusted", X509Certificate[].class, String.class, SSLEngine.class);
+                            mcheckServerTrusted.invoke(caTrustManagers[i], chain, authType, engine);
+                        }
+                    } catch (NoSuchMethodException nsme) {
+                        throw new ValidatorException(nsme.getMessage());
+                    } catch (InvocationTargetException ite) {
+                        throw new ValidatorException(ite.getMessage());
+                    } catch (IllegalAccessException iae) {
+                        throw new ValidatorException(iae.getMessage());
+                    } catch (ClassNotFoundException cnfe) {
+                        throw new ValidatorException(cnfe.getMessage());
+                    }
+                }
+
                 trusted = true;
                 break;
             } catch (ValidatorException caex) {
                 savedException = caex;
             }
         }
+
         if (trusted) {
             return;
         }
@@ -332,7 +360,7 @@
         return explicitlyTrusted;
     }
 
-    public X509Certificate[] getAcceptedIssuers() {
+    protected X509Certificate[] getAcceptedIssuers() {
         List<X509Certificate> issuers = new ArrayList<X509Certificate>();
 
         for (int i = 0; i < caTrustManagers.length; i++) {
@@ -394,7 +422,7 @@
             public Boolean run() {
                 return SecurityDialogs.showCertWarningDialog(
                         AccessType.UNVERIFIED, null,
-                        new HttpsCertVerifier(trustManager, chain, authType,
+                        new HttpsCertVerifier(chain, authType,
                                               isTrusted, hostMatched,
                                               hostName));
             }
diff -r 439f0b1cee5c netx/net/sourceforge/jnlp/security/VariableX509TrustManagerJDK6.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManagerJDK6.java	Mon Sep 17 15:12:13 2012 -0400
@@ -0,0 +1,75 @@
+/* VariableX509TrustManagerJDK6.java
+   Copyright (C) 2012 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.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
+
+public class VariableX509TrustManagerJDK6 extends X509ExtendedTrustManager {
+
+    private VariableX509TrustManager vX509TM = VariableX509TrustManager.getInstance();
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+        checkClientTrusted(chain, authType, null, null);
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+        vX509TM.checkTrustServer(chain, authType, null /* hostname*/, null /* socket */, null /* engine */);
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return vX509TM.getAcceptedIssuers();
+    }
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType, String hostname, String algorithm) throws CertificateException {
+        vX509TM.checkTrustClient(chain, authType, hostname); // We don't need algorithm, we will always use this for TLS only
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType, String hostname, String algorithm) throws CertificateException {
+        // We don't need to pass algorithm, we will always use this for TLS only
+        vX509TM.checkTrustServer(chain, authType, hostname, null /* socket */, null /* engine */);
+    }
+
+}
diff -r 439f0b1cee5c netx/net/sourceforge/jnlp/security/VariableX509TrustManagerJDK7.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManagerJDK7.java	Mon Sep 17 15:12:13 2012 -0400
@@ -0,0 +1,136 @@
+/* VariableX509TrustManagerJDK7.java
+   Copyright (C) 2012 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.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.Socket;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.X509ExtendedTrustManager;
+
+public class VariableX509TrustManagerJDK7 extends X509ExtendedTrustManager {
+
+    private VariableX509TrustManager vX509TM = VariableX509TrustManager.getInstance();
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+        vX509TM.checkTrustClient(chain, authType, null /* hostname*/);
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+        vX509TM.checkTrustServer(chain, authType, null /* hostname*/, null /* socket */, null /* engine */);
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return vX509TM.getAcceptedIssuers();
+    }
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
+        checkTrustClient(chain, authType, socket, null);
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
+        checkTrustServer(chain, authType, socket, null);
+
+    }
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
+        checkTrustClient(chain, authType, null, engine);
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
+        checkTrustServer(chain, authType, null, engine);
+    }
+
+    /**
+     * Check if the server is trusted
+     *
+     * @param chain The cert chain
+     * @param authType The auth type algorithm
+     * @param socket the SSLSocket, may be null
+     * @param engine the SSLEngine, may be null
+     */
+    private void checkTrustServer(X509Certificate[] chain,
+                             String authType, Socket socket,
+                             SSLEngine engine) throws CertificateException {
+
+        String hostName = null;
+
+        if (socket != null) {
+            hostName = ((SSLSocket) socket).getHandshakeSession().getPeerHost();
+        } else if (engine != null) {
+            hostName = engine.getHandshakeSession().getPeerHost();
+        }
+
+        vX509TM.checkTrustServer(chain, authType, hostName, (SSLSocket) socket, engine);
+    }
+
+    /**
+     * Check if the client is trusted
+     *
+     * @param chain The cert chain
+     * @param authType The auth type algorithm
+     * @param socket the SSLSocket, if provided
+     * @param engine the SSLEngine, if provided
+     */
+    private void checkTrustClient(X509Certificate[] chain,
+                             String authType, Socket socket,
+                             SSLEngine engine) throws CertificateException {
+
+        String hostName = null;
+
+        if (socket != null) {
+            hostName = ((SSLSocket) socket).getHandshakeSession().getPeerHost();
+        } else if (engine != null) {
+            hostName = engine.getHandshakeSession().getPeerHost();
+        }
+
+        vX509TM.checkTrustClient(chain, authType, hostName);
+    }
+}


More information about the distro-pkg-dev mailing list