--- java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java (revision 1078506) +++ java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java (working copy) @@ -577,20 +577,49 @@ if (crlf == null) { TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); tmf.init(trustStore); - tms = tmf.getTrustManagers(); + tms = getTrustManagers(tmf); } else { TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); CertPathParameters params = getParameters(algorithm, crlf, trustStore); ManagerFactoryParameters mfp = new CertPathTrustManagerParameters(params); tmf.init(mfp); - tms = tmf.getTrustManagers(); + tms = getTrustManagers(tmf); } } return tms; } - + /** + * Gets the TrustManagers either from Connector's + * trustManagerClassName attribute (if set) else from the + * {@link TrustManagerFactory}. + * @return The TrustManagers to use for this connector. + * @throws NoSuchAlgorithmException + * @throws ClassNotFoundException + * @throws IllegalAccessException + * @throws InstantiationException + */ + protected TrustManager[] getTrustManagers(TrustManagerFactory tmf) + throws NoSuchAlgorithmException, ClassNotFoundException, + InstantiationException, IllegalAccessException { + + String className = (String) attributes.get("trustManageClassName"); + if(className != null && className.length() > 0) { + ClassLoader classLoader = getClass().getClassLoader(); + Class clazz = classLoader.loadClass(className); + if(!(TrustManager.class.isAssignableFrom(clazz))){ + throw new InstantiationException(sm.getString( + "jsse.invalidTrustManagerClassName", className)); + } + Object trustManagerObject = clazz.newInstance(); + TrustManager trustManager = (TrustManager) trustManagerObject; + return new TrustManager[]{ trustManager }; + } + return tmf.getTrustManagers(); + } + + /** * Return the initialization parameters for the TrustManager. * Currently, only the default PKIX is supported. * --- java/org/apache/tomcat/util/net/jsse/res/LocalStrings.properties (revision 1078506) +++ java/org/apache/tomcat/util/net/jsse/res/LocalStrings.properties (working copy) @@ -16,3 +16,4 @@ jsse.alias_no_key_entry=Alias name {0} does not identify a key entry jsse.keystore_load_failed=Failed to load keystore type {0} with path {1} due to {2} jsse.invalid_truststore_password=The provided trust store password could not be used to unlock and/or validate the trust store. Retrying to access the trust store with a null password which will skip validation. +jsse.invalidTrustManagerClassName=The trustManagerClassName provided [{0}] does not implement javax.net.ssl.TrustManager --- webapps/docs/config/http.xml (revision 1078506) +++ webapps/docs/config/http.xml (working copy) @@ -740,6 +740,14 @@ specified the first key read in the keystore will be used.

+ +

The name of a custom trust manager class to use to validate client + certificates. The class must have a zero argument constructor and must + also implement javax.net.ssl.X509TrustManager. If this + attribute is set, the trust store attributes may be ignored. +

+
+

The trust store file to use to validate client certificates. The default is the value of the javax.net.ssl.trustStore system