You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2009/07/09 10:22:27 UTC

svn commit: r792442 - in /tomcat: connectors/trunk/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java container/tc5.5.x/webapps/docs/changelog.xml

Author: markt
Date: Thu Jul  9 08:22:26 2009
New Revision: 792442

URL: http://svn.apache.org/viewvc?rev=792442&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=37869
Port extraction of client certs when using APR

Modified:
    tomcat/connectors/trunk/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java
    tomcat/container/tc5.5.x/webapps/docs/changelog.xml

Modified: tomcat/connectors/trunk/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=792442&r1=792441&r2=792442&view=diff
==============================================================================
--- tomcat/connectors/trunk/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java (original)
+++ tomcat/connectors/trunk/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java Thu Jul  9 08:22:26 2009
@@ -1095,37 +1095,33 @@
                     // Cipher suite
                     Object sslO = SSLSocket.getInfoS(socket, SSL.SSL_INFO_CIPHER);
                     if (sslO != null) {
-                        request.setAttribute
-                            (AprEndpoint.CIPHER_SUITE_KEY, sslO);
+                        request.setAttribute(AprEndpoint.CIPHER_SUITE_KEY, sslO);
                     }
-                    // Client certificate chain if present
+                    // 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 (certLength > 0) {
-                        certs = new X509Certificate[certLength];
+                    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);
-                            CertificateFactory cf =
-                                CertificateFactory.getInstance("X.509");
-                            ByteArrayInputStream stream = new ByteArrayInputStream(data);
-                            certs[i] = (X509Certificate) cf.generateCertificate(stream);
+                            certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data));
                         }
                     }
                     if (certs != null) {
-                        request.setAttribute
-                            (AprEndpoint.CERTIFICATE_KEY, certs);
+                        request.setAttribute(AprEndpoint.CERTIFICATE_KEY, certs);
                     }
                     // User key size
                     sslO = new Integer(SSLSocket.getInfoI(socket, SSL.SSL_INFO_CIPHER_USEKEYSIZE));
                     if (sslO != null) {
-                        request.setAttribute
-                            (AprEndpoint.KEY_SIZE_KEY, sslO);
+                        request.setAttribute(AprEndpoint.KEY_SIZE_KEY, sslO);
                     }
                     // SSL session ID
                     sslO = SSLSocket.getInfoS(socket, SSL.SSL_INFO_SESSION_ID);
                     if (sslO != null) {
-                        request.setAttribute
-                            (AprEndpoint.SESSION_ID_KEY, sslO);
+                        request.setAttribute(AprEndpoint.SESSION_ID_KEY, sslO);
                     }
                 } catch (Exception e) {
                     log.warn(sm.getString("http11processor.socket.ssl"), e);
@@ -1138,29 +1134,26 @@
                  // 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]);
+                ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]).setLimit(maxSavePostSize);
+                inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]);
                 try {
                     // Renegociate certificates
                     SSLSocket.renegotiate(socket);
-                    // Client certificate chain if present
+                    // 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 (certLength > 0) {
-                        certs = new X509Certificate[certLength];
+                    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);
-                            CertificateFactory cf =
-                                CertificateFactory.getInstance("X.509");
-                            ByteArrayInputStream stream = new ByteArrayInputStream(data);
-                            certs[i] = (X509Certificate) cf.generateCertificate(stream);
+                            certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data));
                         }
                     }
                     if (certs != null) {
-                        request.setAttribute
-                            (AprEndpoint.CERTIFICATE_KEY, certs);
+                        request.setAttribute(AprEndpoint.CERTIFICATE_KEY, certs);
                     }
                 } catch (Exception e) {
                     log.warn(sm.getString("http11processor.socket.ssl"), e);

Modified: tomcat/container/tc5.5.x/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/webapps/docs/changelog.xml?rev=792442&r1=792441&r2=792442&view=diff
==============================================================================
--- tomcat/container/tc5.5.x/webapps/docs/changelog.xml (original)
+++ tomcat/container/tc5.5.x/webapps/docs/changelog.xml Thu Jul  9 08:22:26 2009
@@ -324,6 +324,10 @@
   </subsection>
   <subsection name="Coyote" >
     <changelog>
+      <fix>
+        <bug>37869</bug>: Correctly extract client certificates, including the
+        full certificate chain when using the APR/native HTTP connector. (markt) 
+      </fix>
       <update>
         Set remote port for AJP connectors from the optional request
         attribute AJP_REMOTE_PORT. (rjung)



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