I have an SSL Server and it can be connected by two types of Clients, one for which Client Authentication is needed and the other for which Client Authentication is not needed.

Is there any mechanism in the SSL Handshake using which I can distinguish between both the clients and decide for which I need to send the certificate request and for which I should not be sending the certificate request?

How do applications commonly deal with such a scenario?


Typically, this scenario is addressed by sending a certificate request anyway and allowing for an empty certificate message (sent by the client) when the certificate is not needed. This is is what mod_ssl's SSLVerifyClient optional does (also the difference between need and want authentication in Java). This is the establish way of dealing with servers for which not all clients may need to present a certificate, and clearly allowed within the TLS specification (Section 7.4.6):

This is the first message the client can send after receiving a server hello done message. This message is only sent if the server requests a certificate. If no suitable certificate is available, the client SHOULD send a certificate message containing no certificates. That is, the certificate_list structure has a length of zero. If client authentication is required by the server for the handshake to continue, it may respond with a fatal handshake failure alert.

You might be able to give an hint using the Client Certificate URLs extension, although I don't think this is the intent of this extension (that would be a bit of a trick). I'm not aware of this extension being widely supported, which would certainly cause practical problems if you want to run this on a production system.

If you really don't want the client to be prompted for a certificate in certain cases, what you may be able to do is to use the Server Name Indication (SNI) extension, which is increasingly supported, thereby offering two distinct server configurations depending on which server name the client is requesting. I haven't tried, but I presume that if you configure two distinct virtual hosts with Apache Httpd using SNI, and only one of them is configured to request a client-certificate, you may be able to achieve your goal.

The downside is that you would need to set up two host names for the same server, but that's not as big a deal as other solutions that may require some programming.

For example, even if you assumed that the source IP address was a sufficient discriminator between your two use cases, in Java, you would probably have to implement the server as listening to a plain ServerSocket (not an SSLServerSocket), check from which IP address it's coming from, convert the accepted socket into an SSLSocket in server mode and configure it at the stage (before the handshake has taken place) to request a client certificate or not, and only then trigger the handshake. (I haven't tried any of this, but that would seem a reasonable way to handle such a case.) This would certainly be more complex than creating an SSLServerSocket and accepting pre-configured SSLSockets from it directly. I would imagine that other SSL/TLS stacks (in C or others) wouldn't handle such a case very cleanly either.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.