Thanks for the comprehensive instructions, very useful. Keep in mind the 8KB limit for the AJP header packet. Especially in case you sometime switch to a longer certificate chain, then you might run into it (and will be able to fix it with max_packet_size).
Regards, Rainer On 23.10.2009 18:36, Christopher Schultz wrote: > All, > > I'm following up because I was able to get the following working. In > case anyone else wants to get this all working, the information is all > in (roughly) one place. > > 1. Apache httpd terminates SSL > 2. Apache httpd performs client certificate verification > 3. mod_jk forwards client certificate to Tomcat > 4. My code fetches the client X509Certificate from the request > 5. My code loads the CA used to sign the client certificate from a file > 6. My code verifies the client certificate is valid given the > CA's public key > > Steps 1-2 were taken care of by loosely following the instructions > provided here: > > http://it.toolbox.com/blogs/securitymonkey/howto-securing-a-website-with-client-ssl-certificates-11500 > > Setting "SSLVerifyClient optional" will allow my code to check for the > certificate, verify it, and then take a different action than usual for > authentication purposes (which was the original goal of this exercise). > > Step 3 (getting mod_jk to deliver the client certificate to Tomcat) > required only: > > SSLOptions +ExportCertData > > While technically not a mod_jk option, mod_jk can't actually send the > client cert to Tomcat unless this options is set. "SSLOptions > +StdEnvVars" is not sufficient. > > Steps 4-6 are easy once you get the incantations right. The key to > loading the CA cert was: > > import java.io.FileInputStream; > import java.io.IOException; > import java.security.cert.X509Certificate; > import java.security.cert.CertificateFactory; > > .. > > // Load the CA Certificate > FileInputStream inStream = null; > Certificate caCert = null; > > try > { > // Confusingly, the ca.crt file is in OpenSSL format, not PKCS12 > inStream = new FileInputStream("ca.crt"); > CertificateFactory cf = CertificateFactory.getInstance("X.509"); > caCert = (Certificate)cf.generateCertificate(inStream); > } > finally > { > if(null != inStream) try { inStream.close(); } > catch (IOException ioe) { ioe.printStackTrace(); } > } > > // Load the client certificate > Object cert = > request.getAttribute("javax.servlet.request.X509Certificate"); > > if (cert instanceof X509Certificate[]) > { > X509Certificate[] certs = (X509Certificate[])cert; > > for(int i=0; i<certs.length; ++i) > { > try > { > certs[i].verify(caCert.getPublicKey()); > > // Verified > > } catch (Exception e) { > > // Not verified > > } > } > } > > That's all the Java code that's required, which is pretty cool. > > It seems pretty slow right now, but I'm working remotely, so it could be > network issues. Certainly loading the CA certificate /once/ and caching > it will speed things up. > > Thanks to Rainer for his help figuring out the Apache httpd/mod_jk stuff. > > -chris --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org