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

Reply via email to