Hello.

I have a specific page in my site that uses ssl client certificates for authentication and the application itself does the cert validation. As the rest of the site does not use them I have clientAuth="false" in my connector otherwise the browsers keep asking for client certificates.

I installed a custom security provider to accept all certificates and built a Valve that requests a SSL renegotiation to try and get a certificate:

req.getCoyoteRequest().action(ActionCode.ACTION_REQ_SSL_CERTIFICATE, null);

Using APR no certificate is requested from the client (probably because of bug 46950). Without APR a SSL renegotiation occurs and a certificate is requested. If a certificate is presented everything works fine and my application sees it, if the client does not send a certificate the connection is promptly closed and the request never makes it to my application to display some kind of error message. This exception is printed to the logs:

javax.net.ssl.SSLProtocolException: handshake alert: no_certificate
at com .sun .net .ssl .internal.ssl.ServerHandshaker.handshakeAlert(ServerHandshaker.java: 1167) at com .sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java: 1675) at com .sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java: 932) at com .sun .net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java: 746) at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
        at java.io.InputStream.read(InputStream.java:85)
at org.apache.tomcat.util.net.jsse.JSSESupport.handShake(JSSESupport.java: 162) at org .apache .tomcat .util.net.jsse.JSSESupport.getPeerCertificateChain(JSSESupport.java:138) at org.apache.coyote.http11.Http11Processor.action(Http11Processor.java: 1099)
        at org.apache.coyote.Request.action(Request.java:350)
at pt.sapo.tomcat.valve.SSLClientRequestor.invoke(SSLClientRequestor.java: 31)

This happens because the code in JSSESupport::handshake() sets the needClientAuth flag when clientAuth != "want":

        if( ssl.getWantClientAuth() ) {
            log.debug("No client cert sent for want");
        } else {
            ssl.setNeedClientAuth(true);
        }

If I set clientAuth="want" in my connector this process works but then the browser always asks for a certificate which is not what I want. Wouldn't it be better to just set the "want" flag in the SSLSocket instead of "need"?

Best regards,
André Cruz


Reply via email to