Author: markt
Date: Tue Sep 15 17:50:54 2009
New Revision: 815418

URL: http://svn.apache.org/viewvc?rev=815418&view=rev
Log:
Fix Tomcat side of https://issues.apache.org/bugzilla/show_bug.cgi?id=46950
- adds new setVerify() method
- uses it before renegotiation to change the cert verification level for the 
connection
- increments minimum tc native version to 1.1.17 as it requires the new 
setVerify() method

Modified:
    tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
    tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java

Modified: tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java?rev=815418&r1=815417&r2=815418&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java Tue 
Sep 15 17:50:54 2009
@@ -58,9 +58,9 @@
 
     protected static final int TCN_REQUIRED_MAJOR = 1;
     protected static final int TCN_REQUIRED_MINOR = 1;
-    protected static final int TCN_REQUIRED_PATCH = 8;
+    protected static final int TCN_REQUIRED_PATCH = 17;
     protected static final int TCN_RECOMMENDED_MIN = 1;
-    protected static final int TCN_RECOMMENDED_PV = 16;
+    protected static final int TCN_RECOMMENDED_PV = 17;
 
 
     // ---------------------------------------------- Properties

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=815418&r1=815417&r2=815418&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Tue Sep 
15 17:50:54 2009
@@ -1118,10 +1118,11 @@
                         request.setAttribute(AprEndpoint.CIPHER_SUITE_KEY, 
sslO);
                     }
                     // Get client certificate and the certificate chain if 
present
+                    // certLength == -1 indicates an error
                     int certLength = SSLSocket.getInfoI(socket, 
SSL.SSL_INFO_CLIENT_CERT_CHAIN);
                     byte[] clientCert = SSLSocket.getInfoB(socket, 
SSL.SSL_INFO_CLIENT_CERT);
                     X509Certificate[] certs = null;
-                    if (clientCert != null) {
+                    if (clientCert != null  && certLength > -1) {
                         certs = new X509Certificate[certLength + 1];
                         CertificateFactory cf = 
CertificateFactory.getInstance("X.509");
                         certs[0] = (X509Certificate) 
cf.generateCertificate(new ByteArrayInputStream(clientCert));
@@ -1152,29 +1153,35 @@
         } else if (actionCode == ActionCode.ACTION_REQ_SSL_CERTIFICATE) {
 
             if (ssl && (socket != 0)) {
-                 // Consume and buffer the request body, so that it does not
-                 // interfere with the client's handshake messages
+                // Consume and buffer the request body, so that it does not
+                // interfere with the client's handshake messages
                 InputFilter[] inputFilters = inputBuffer.getFilters();
                 ((BufferedInputFilter) 
inputFilters[Constants.BUFFERED_FILTER]).setLimit(maxSavePostSize);
                 
inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]);
                 try {
-                    // Renegociate certificates
-                    SSLSocket.renegotiate(socket);
-                    // Get client certificate and the certificate chain if 
present
-                    int certLength = SSLSocket.getInfoI(socket, 
SSL.SSL_INFO_CLIENT_CERT_CHAIN);
-                    byte[] clientCert = SSLSocket.getInfoB(socket, 
SSL.SSL_INFO_CLIENT_CERT);
-                    X509Certificate[] certs = null;
-                    if (clientCert != null) {
-                        certs = new X509Certificate[certLength + 1];
-                        CertificateFactory cf = 
CertificateFactory.getInstance("X.509");
-                        certs[0] = (X509Certificate) 
cf.generateCertificate(new ByteArrayInputStream(clientCert));
-                        for (int i = 0; i < certLength; i++) {
-                            byte[] data = SSLSocket.getInfoB(socket, 
SSL.SSL_INFO_CLIENT_CERT_CHAIN + i);
-                            certs[i+1] = (X509Certificate) 
cf.generateCertificate(new ByteArrayInputStream(data));
+                    // Configure connection to require a certificate
+                    SSLSocket.setVerify(socket, SSL.SSL_CVERIFY_REQUIRE,
+                            endpoint.getSSLVerifyDepth());
+                    // Renegotiate certificates
+                    if (SSLSocket.renegotiate(socket) == 0) {
+                        // Don't look for certs unless we know renegotiation 
worked.
+                        // Get client certificate and the certificate chain if 
present
+                        // certLength == -1 indicates an error 
+                        int certLength = 
SSLSocket.getInfoI(socket,SSL.SSL_INFO_CLIENT_CERT_CHAIN);
+                        byte[] clientCert = SSLSocket.getInfoB(socket, 
SSL.SSL_INFO_CLIENT_CERT);
+                        X509Certificate[] certs = null;
+                        if (clientCert != null && certLength > -1) {
+                            certs = new X509Certificate[certLength + 1];
+                            CertificateFactory cf = 
CertificateFactory.getInstance("X.509");
+                            certs[0] = (X509Certificate) 
cf.generateCertificate(new ByteArrayInputStream(clientCert));
+                            for (int i = 0; i < certLength; i++) {
+                                byte[] data = SSLSocket.getInfoB(socket, 
SSL.SSL_INFO_CLIENT_CERT_CHAIN + i);
+                                certs[i+1] = (X509Certificate) 
cf.generateCertificate(new ByteArrayInputStream(data));
+                            }
+                        }
+                        if (certs != null) {
+                            request.setAttribute(AprEndpoint.CERTIFICATE_KEY, 
certs);
                         }
-                    }
-                    if (certs != null) {
-                        request.setAttribute(AprEndpoint.CERTIFICATE_KEY, 
certs);
                     }
                 } catch (Exception e) {
                     log.warn(sm.getString("http11processor.socket.ssl"), e);

Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java?rev=815418&r1=815417&r2=815418&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java Tue Sep 15 17:50:54 
2009
@@ -48,7 +48,7 @@
      * response is sent. In more detail: the renegotiation happens after the
      * request line and MIME headers were read, but _before_ the attached
      * request body is read. The reason simply is that in the HTTP protocol
-     * usually there is no acknowledgment step between the headers and the
+     * usually there is no acknowledgement step between the headers and the
      * body (there is the 100-continue feature and the chunking facility
      * only), so Apache has no API hook for this step.
      *
@@ -57,7 +57,30 @@
     public static native int renegotiate(long thesocket);
 
     /**
-     * Retrun SSL Info parameter as byte array.
+     * Set Type of Client Certificate verification and Maximum depth of CA
+     * Certificates in Client Certificate verification.
+     * <br />
+     * This is used to change the verification level for a connection prior to
+     * starting a re-negotiation.
+     * <br />
+     * The following levels are available for level:
+     * <PRE>
+     * SSL_CVERIFY_NONE           - No client Certificate is required at all
+     * SSL_CVERIFY_OPTIONAL       - The client may present a valid Certificate
+     * SSL_CVERIFY_REQUIRE        - The client has to present a valid
+     *                              Certificate
+     * SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate
+     *                              but it need not to be (successfully)
+     *                              verifiable
+     * </PRE>
+     * <br />
+     * @param sock  The socket to change.
+     * @param level Type of Client Certificate verification.
+     */
+    public static native void setVerify(long sock, int level, int depth);
+    
+    /**    
+     * Return SSL Info parameter as byte array.
      *
      * @param sock The socket to read the data from.
      * @param id Parameter id.
@@ -67,7 +90,7 @@
         throws Exception;
 
     /**
-     * Retrun SSL Info parameter as String.
+     * Return SSL Info parameter as String.
      *
      * @param sock The socket to read the data from.
      * @param id Parameter id.
@@ -77,7 +100,7 @@
         throws Exception;
 
     /**
-     * Retrun SSL Info parameter as integer.
+     * Return SSL Info parameter as integer.
      *
      * @param sock The socket to read the data from.
      * @param id Parameter id.



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to