Author: markt Date: Sun Mar 13 14:01:34 2011 New Revision: 1081117 URL: http://svn.apache.org/viewvc?rev=1081117&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50887 Add support for configuring the JSSE provider used to convert client certificates. Based on a patch by pknopp.
Modified: tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java tomcat/trunk/webapps/docs/changelog.xml tomcat/trunk/webapps/docs/config/ajp.xml tomcat/trunk/webapps/docs/config/http.xml Modified: tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties Sun Mar 13 14:01:34 2011 @@ -41,6 +41,8 @@ errorReportValve.rootCauseInLogs=The ful # Remote IP valve remoteIpValve.syntax=Invalid regular expressions [{0}] provided. +sslValve.invalidProvider=The SSL provider specified on the connector associated with this request of [{0}] is invalid. The certificate data could not be processed. + # HTTP status reports http.100=The client may continue ({0}). http.101=The server is switching protocols according to the "Upgrade" header ({0}). Modified: tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java Sun Mar 13 14:01:34 2011 @@ -19,6 +19,7 @@ package org.apache.catalina.valves; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.security.NoSuchProviderException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; @@ -27,6 +28,8 @@ import javax.servlet.ServletException; import org.apache.catalina.Globals; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; /** * When using mod_proxy_http, the client SSL information is not included in the @@ -59,6 +62,8 @@ import org.apache.catalina.connector.Res */ public class SSLValve extends ValveBase { + private static final Log log = LogFactory.getLog(SSLValve.class); + //------------------------------------------------------ Constructor public SSLValve() { @@ -91,14 +96,24 @@ public class SSLValve extends ValveBase // ByteArrayInputStream bais = new ByteArrayInputStream(strcerts.getBytes("UTF-8")); ByteArrayInputStream bais = new ByteArrayInputStream(strcerts.getBytes()); X509Certificate jsseCerts[] = null; + String providerName = (String) request.getConnector().getProperty( + "clientCertProvider"); try { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); + CertificateFactory cf; + if (providerName == null) { + cf = CertificateFactory.getInstance("X.509"); + } else { + cf = CertificateFactory.getInstance("X.509", providerName); + } X509Certificate cert = (X509Certificate) cf.generateCertificate(bais); jsseCerts = new X509Certificate[1]; jsseCerts[0] = cert; } catch (java.security.cert.CertificateException e) { System.out.println("SSLValve failed " + strcerts); System.out.println("SSLValve failed " + e); + } catch (NoSuchProviderException e) { + log.error(sm.getString( + "sslValve.invalidProvider", providerName), e); } request.setAttribute(Globals.CERTIFICATES_ATTR, jsseCerts); } Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java (original) +++ tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java Sun Mar 13 14:01:34 2011 @@ -109,6 +109,20 @@ public abstract class AbstractProtocolHa } + /** + * When client certificate information is presented in a form other than + * instances of {@link java.security.cert.X509Certificate} it needs to be + * converted before it can be used and this property controls which JSSE + * provider is used to perform the conversion. For example it is used with + * the AJP connectors, the HTTP APR connector and with the + * {@link org.apache.catalina.valves.SSLValve}. If not specified, the + * default provider will be used. + */ + protected String clientCertProvider = null; + public String getClientCertProvider() { return clientCertProvider; } + public void setClientCertProvider(String s) { this.clientCertProvider = s; } + + // ---------------------- Properties that are passed through to the EndPoint @Override Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Sun Mar 13 14:01:34 2011 @@ -20,6 +20,7 @@ package org.apache.coyote.ajp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.InetAddress; +import java.security.NoSuchProviderException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.concurrent.Executor; @@ -205,6 +206,19 @@ public abstract class AbstractAjpProcess } + /** + * When client certificate information is presented in a form other than + * instances of {@link java.security.cert.X509Certificate} it needs to be + * converted before it can be used and this property controls which JSSE + * provider is used to perform the conversion. For example it is used with + * the AJP connectors, the HTTP APR connector and with the + * {@link org.apache.catalina.valves.SSLValve}. If not specified, the + * default provider will be used. + */ + protected String clientCertProvider = null; + public String getClientCertProvider() { return clientCertProvider; } + public void setClientCertProvider(String s) { this.clientCertProvider = s; } + // --------------------------------------------------------- Public Methods @@ -294,8 +308,13 @@ public abstract class AbstractAjpProcess certData.getLength()); // Fill the elements. try { - CertificateFactory cf = - CertificateFactory.getInstance("X.509"); + CertificateFactory cf; + if (clientCertProvider == null) { + cf = CertificateFactory.getInstance("X.509"); + } else { + cf = CertificateFactory.getInstance("X.509", + clientCertProvider); + } while(bais.available() > 0) { X509Certificate cert = (X509Certificate) cf.generateCertificate(bais); @@ -312,6 +331,9 @@ public abstract class AbstractAjpProcess } catch (java.security.cert.CertificateException e) { getLog().error(sm.getString("ajpprocessor.certs.fail"), e); return; + } catch (NoSuchProviderException e) { + getLog().error(sm.getString("ajpprocessor.certs.fail"), e); + return; } request.setAttribute(SSLSupport.CERTIFICATE_KEY, jsseCerts); } Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java Sun Mar 13 14:01:34 2011 @@ -266,6 +266,7 @@ public class AjpAprProtocol extends Abst processor.setAdapter(proto.adapter); processor.setTomcatAuthentication(proto.tomcatAuthentication); processor.setRequiredSecret(proto.requiredSecret); + processor.setClientCertProvider(proto.getClientCertProvider()); register(processor); return processor; } Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java Sun Mar 13 14:01:34 2011 @@ -221,6 +221,7 @@ public class AjpProtocol extends Abstrac processor.setTomcatAuthentication(proto.tomcatAuthentication); processor.setRequiredSecret(proto.requiredSecret); processor.setKeepAliveTimeout(proto.getKeepAliveTimeout()); + processor.setClientCertProvider(proto.getClientCertProvider()); register(processor); return processor; } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Sun Mar 13 14:01:34 2011 @@ -139,6 +139,21 @@ public class Http11AprProcessor extends return endpoint; } + + /** + * When client certificate information is presented in a form other than + * instances of {@link java.security.cert.X509Certificate} it needs to be + * converted before it can be used and this property controls which JSSE + * provider is used to perform the conversion. For example it is used with + * the AJP connectors, the HTTP APR connector and with the + * {@link org.apache.catalina.valves.SSLValve}. If not specified, the + * default provider will be used. + */ + protected String clientCertProvider = null; + public String getClientCertProvider() { return clientCertProvider; } + public void setClientCertProvider(String s) { this.clientCertProvider = s; } + + // --------------------------------------------------------- Public Methods @@ -531,7 +546,13 @@ public class Http11AprProcessor extends X509Certificate[] certs = null; if (clientCert != null && certLength > -1) { certs = new X509Certificate[certLength + 1]; - CertificateFactory cf = CertificateFactory.getInstance("X.509"); + CertificateFactory cf; + if (clientCertProvider == null) { + cf = CertificateFactory.getInstance("X.509"); + } else { + cf = CertificateFactory.getInstance("X.509", + clientCertProvider); + } certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert)); for (int i = 0; i < certLength; i++) { byte[] data = SSLSocket.getInfoB(socketRef, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i); Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Sun Mar 13 14:01:34 2011 @@ -418,6 +418,7 @@ public class Http11AprProtocol extends A processor.setSocketBuffer(proto.getSocketBuffer()); processor.setMaxSavePostSize(proto.getMaxSavePostSize()); processor.setServer(proto.getServer()); + processor.setClientCertProvider(proto.getClientCertProvider()); register(processor); return processor; } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Sun Mar 13 14:01:34 2011 @@ -56,6 +56,14 @@ </fix> </changelog> </subsection> + <subsection name="Coyote"> + <changelog> + <add> + <bug>50887</bug>: Add support for configuring the JSSE provider used to + convert client certificates. Based on a patch by pknopp. (markt) + </add> + </changelog> + </subsection> <subsection name="Other"> <changelog> <update> Modified: tomcat/trunk/webapps/docs/config/ajp.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/ajp.xml?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/ajp.xml (original) +++ tomcat/trunk/webapps/docs/config/ajp.xml Sun Mar 13 14:01:34 2011 @@ -268,6 +268,17 @@ interface.</p> </attribute> + <attribute name="clientCertProvider" required="false"> + <p>When client certificate information is presented in a form other than + instances of <code>java.security.cert.X509Certificate</code> it needs to + be converted before it can be used and this property controls which JSSE + provider is used to perform the conversion. For example it is used with + the AJP connectors, the <a href="http.html">HTTP APR connector</a> and + with the <a href="valve.html#SSL_Authenticator_Valve"> + org.apache.catalina.valves.SSLValve</a>.If not specified, the default + provider will be used.</p> + </attribute> + <attribute name="connectionLinger" required="false"> <p>The number of milliseconds during which the sockets used by this <strong>Connector</strong> will linger when they are closed. Modified: tomcat/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1081117&r1=1081116&r2=1081117&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/http.xml (original) +++ tomcat/trunk/webapps/docs/config/http.xml Sun Mar 13 14:01:34 2011 @@ -893,6 +893,17 @@ constraint that uses <code>CLIENT-CERT</code> authentication.</p> </attribute> + <attribute name="clientCertProvider" required="false"> + <p>When client certificate information is presented in a form other than + instances of <code>java.security.cert.X509Certificate</code> it needs to + be converted before it can be used and this property controls which JSSE + provider is used to perform the conversion. For example it is used with + the <a href="ajp.html">AJP connectors</a>, the HTTP APR connector and + with the <a href="valve.html#SSL_Authenticator_Valve"> + org.apache.catalina.valves.SSLValve</a>. If not specified, the default + provider will be used.</p> + </attribute> + <attribute name="crlFile" required="false"> <p>The certificate revocation list to be used to verify client certificates. If not defined, client certificates will not be checked --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org