# HG changeset patch # User Deepak Bhole # Date 1354570002 18000 # Node ID c74251bbaffd8e6b1e2eefa4a52b7dfdb2815fb8 # Parent 382db02cb6553c2939f17d407345eaeb33417b18 PR1161: X509VariableTrustManager does not work correctly with OpenJDK7 diff -r 382db02cb655 -r c74251bbaffd ChangeLog --- a/ChangeLog Thu Nov 01 12:27:21 2012 -0400 +++ b/ChangeLog Mon Dec 03 16:26:42 2012 -0500 @@ -1,3 +1,33 @@ +2012-09-17 Deepak Bhole + + 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. + 2012-11-01 Deepak Bhole * configure.ac: Prepare for 1.2.3 diff -r 382db02cb655 -r c74251bbaffd Makefile.am --- a/Makefile.am Thu Nov 01 12:27:21 2012 -0400 +++ b/Makefile.am Mon Dec 03 16:26:42 2012 -0500 @@ -299,6 +299,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 382db02cb655 -r c74251bbaffd NEWS --- a/NEWS Thu Nov 01 12:27:21 2012 -0400 +++ b/NEWS Mon Dec 03 16:26:42 2012 -0500 @@ -9,6 +9,8 @@ CVE-XXXX-YYYY: http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY New in release 1.2.3 (2012-XX-XX): +* Common + - PR1161: X509VariableTrustManager does not work correctly with OpenJDK7 New in release 1.2.2 (2012-11-07): * Security Updates diff -r 382db02cb655 -r c74251bbaffd acinclude.m4 --- a/acinclude.m4 Thu Nov 01 12:27:21 2012 -0400 +++ b/acinclude.m4 Mon Dec 03 16:26:42 2012 -0500 @@ -677,9 +677,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 382db02cb655 -r c74251bbaffd netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java --- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Thu Nov 01 12:27:21 2012 -0400 +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Mon Dec 03 16:26:42 2012 -0500 @@ -16,38 +16,60 @@ package net.sourceforge.jnlp.runtime; -import java.io.*; +import java.awt.EventQueue; +import java.awt.Image; +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 @@ -229,7 +251,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(); @@ -254,6 +276,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 382db02cb655 -r c74251bbaffd netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java --- a/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java Thu Nov 01 12:27:21 2012 -0400 +++ b/netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java Mon Dec 03 16:26:42 2012 -0500 @@ -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 details = new ArrayList(); - 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 382db02cb655 -r c74251bbaffd netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java --- a/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java Thu Nov 01 12:27:21 2012 -0400 +++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java Mon Dec 03 16:26:42 2012 -0500 @@ -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 issuers = new ArrayList(); 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 382db02cb655 -r c74251bbaffd 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 Dec 03 16:26:42 2012 -0500 @@ -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 382db02cb655 -r c74251bbaffd 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 Dec 03 16:26:42 2012 -0500 @@ -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); + } +}