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

Reply via email to