Author: markt Date: Fri Jul 17 10:58:30 2009 New Revision: 795038 URL: http://svn.apache.org/viewvc?rev=795038&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=39637 AJP connectors do not handle certificate chains Patch by Patrik Schnellmann
Modified: tomcat/connectors/trunk/jk/java/org/apache/ajp/RequestHandler.java tomcat/connectors/trunk/jk/java/org/apache/coyote/ajp/AjpAprProcessor.java tomcat/connectors/trunk/jk/java/org/apache/jk/core/MsgContext.java tomcat/container/tc5.5.x/webapps/docs/changelog.xml Modified: tomcat/connectors/trunk/jk/java/org/apache/ajp/RequestHandler.java URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/java/org/apache/ajp/RequestHandler.java?rev=795038&r1=795037&r2=795038&view=diff ============================================================================== --- tomcat/connectors/trunk/jk/java/org/apache/ajp/RequestHandler.java (original) +++ tomcat/connectors/trunk/jk/java/org/apache/ajp/RequestHandler.java Fri Jul 17 10:58:30 2009 @@ -351,21 +351,33 @@ break; case SC_A_SSL_CERT : - isSSL = true; + isSSL = true; // Transform the string into certificate. String certString = msg.getString(); byte[] certData = certString.getBytes(); ByteArrayInputStream bais = new ByteArrayInputStream(certData); - // Fill the first element. + // Fill all elements. X509Certificate jsseCerts[] = null; try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate) - cf.generateCertificate(bais); - jsseCerts = new X509Certificate[1]; - jsseCerts[0] = cert; + int i = 0; + while (bais.available() > 0) { + X509Certificate cert = (X509Certificate) + cf.generateCertificate(bais); + if (jsseCerts == null) { + jsseCerts = new X509Certificate[1]; + } else { + X509Certificate tmpJsseCerts[] = + new X509Certificate[jsseCerts.length + 1]; + System.arraycopy(jsseCerts, 0, + tmpJsseCerts, 0, + jsseCerts.length); + jsseCerts = tmpJsseCerts; + } + jsseCerts[i++] = cert; + } } catch(java.security.cert.CertificateException e) { log("Certificate convertion failed" + e ); } Modified: tomcat/connectors/trunk/jk/java/org/apache/coyote/ajp/AjpAprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/java/org/apache/coyote/ajp/AjpAprProcessor.java?rev=795038&r1=795037&r2=795038&view=diff ============================================================================== --- tomcat/connectors/trunk/jk/java/org/apache/coyote/ajp/AjpAprProcessor.java (original) +++ tomcat/connectors/trunk/jk/java/org/apache/coyote/ajp/AjpAprProcessor.java Fri Jul 17 10:58:30 2009 @@ -568,19 +568,28 @@ new ByteArrayInputStream(certData.getBytes(), certData.getStart(), certData.getLength()); - // Fill the first element. + // Fill the elements. try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate) - cf.generateCertificate(bais); - jsseCerts = new X509Certificate[1]; - jsseCerts[0] = cert; - request.setAttribute(AprEndpoint.CERTIFICATE_KEY, jsseCerts); + while(bais.available() > 0) { + X509Certificate cert = (X509Certificate) + cf.generateCertificate(bais); + if(jsseCerts == null) { + jsseCerts = new X509Certificate[1]; + jsseCerts[0] = cert; + } else { + X509Certificate [] temp = new X509Certificate[jsseCerts.length+1]; + System.arraycopy(jsseCerts,0,temp,0,jsseCerts.length); + temp[jsseCerts.length] = cert; + jsseCerts = temp; + } + } } catch (java.security.cert.CertificateException e) { log.error(sm.getString("ajpprocessor.certs.fail"), e); return; } + request.setAttribute(AprEndpoint.CERTIFICATE_KEY, jsseCerts); } } else if (actionCode == ActionCode.ACTION_REQ_HOST_ATTRIBUTE) { Modified: tomcat/connectors/trunk/jk/java/org/apache/jk/core/MsgContext.java URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/java/org/apache/jk/core/MsgContext.java?rev=795038&r1=795037&r2=795038&view=diff ============================================================================== --- tomcat/connectors/trunk/jk/java/org/apache/jk/core/MsgContext.java (original) +++ tomcat/connectors/trunk/jk/java/org/apache/jk/core/MsgContext.java Fri Jul 17 10:58:30 2009 @@ -325,15 +325,27 @@ certData.getStart(), certData.getLength()); - // Fill the first element. + // Fill all elements. X509Certificate jsseCerts[] = null; try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate) - cf.generateCertificate(bais); - jsseCerts = new X509Certificate[1]; - jsseCerts[0] = cert; + int i = 0; + while (bais.available() > 0) { + X509Certificate cert = (X509Certificate) + cf.generateCertificate(bais); + if (jsseCerts == null) { + jsseCerts = new X509Certificate[1]; + } else { + X509Certificate tmpJsseCerts[] = + new X509Certificate[jsseCerts.length + 1]; + System.arraycopy(jsseCerts, 0, + tmpJsseCerts, 0, + jsseCerts.length); + jsseCerts = tmpJsseCerts; + } + jsseCerts[i++] = cert; + } } catch(java.security.cert.CertificateException e) { log.error("Certificate convertion failed" , e ); return; 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=795038&r1=795037&r2=795038&view=diff ============================================================================== --- tomcat/container/tc5.5.x/webapps/docs/changelog.xml (original) +++ tomcat/container/tc5.5.x/webapps/docs/changelog.xml Fri Jul 17 10:58:30 2009 @@ -351,6 +351,11 @@ <bug>37869</bug>: Correctly extract client certificates, including the full certificate chain when using the APR/native HTTP connector. (markt) </fix> + <fix> + <bug>39637</bug>: Correctly extract client certificates, including the + full certificate chain when using the AJP connectors. Patch by Patrik + Schnellmann. (markt) + </fix> <update> Set remote port for AJP connectors from the optional request attribute AJP_REMOTE_PORT. (rjung) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org