8

I am using openssl to connect to servers to detect if they require a client certificate.

Currently I am using this command:

openssl s_client -connect pokyloky.com:5222 -state 2>&1 | grep 'server certificate request' 

SSL_connect:SSLv3 read server certificate request A

I am surprised that simply using:

openssl s_client -connect pokyloky.com:5222 

doesn't indicate directly that a client certificate has been requested. There is a handshake error:

139843101763232:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1262:SSL alert number 40
139843101763232:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:

But it doesn't explicitly state why the handshake has failed.

Why does openssl s_connect not indicate clearly that the server requested a certificate and the handshake has failed because of this?

1
  • The server may send alert 40 (handshake failed) because it requested a client cert and didn't receive one, but it may do so for many other reasons, and many servers request a client cert but do continue and do not fail when the client chooses not to provide one, so s_client can't know for sure which reason or combination of reasons the server had. Sep 30 '15 at 18:38
4

That behaviour is not part of TLS v1.2

But it doesn't explicitly state why the handshake has failed.

It can't. It's not defined as part of the (TLS v1.2) protocol.

When the server or client decides to abort a connection, they can choose from one out of several alert messages.

An Alert message looks like this:

struct {
      AlertLevel level;
      AlertDescription description;
} Alert;

AlertLevel is one byte wide and only has two states:

enum { warning(1), fatal(2), (255) } AlertLevel;

And AlertDescription is one byte wide as well. But out of the 256 possible reason codes only about 30 are assigned and used. And of these 30, there simply is none, that fits the "Hey, I told you I wanted a client certificate, why didn't you give me one?!?"-bill.

(And although it sounds like it might fit, no_certificate_RESERVED(41) was used for something else. Namely in SSLv3.0 it was used for the other direction: for the CLIENT to tell the server "Sorry, I can't give you a client certificate.")

Now for the deeper question "Wouldn't it make sense to define such a reason code if there are plenty unused code points left? Instead of just hard, largely unexplained failure?" my answer is simply: "I don't know."

I don't see how having such an alert could make the protocol weaker, but crypto is tricky, and I'm not sure.

Loadbalancer to give friendly error message

But what if you want to give a friendly error message?

AFAIK, then you must do somewhat complicated things with loadbalancer like logic and just initially allow the clientcert-less connection, but then immediately redirect to an error page. Apache can do such a thing with a rule similar to this:

RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
RewriteRule .* /help/ssl-client-auth-required.html [L]

IIS defines a HTTP eror message called 403.7 Forbidden: Client Certificate Required. I think this is a smart move (better than just failing, at least), even though the .7 of 403.7 is non-standard and I think the error message belongs on the TLS layer and not the HTTP layer.

1

You can view the verbose output of the protocol by adding the flag -trace. The documentation states that:

-trace

show verbose trace output of protocol messages. OpenSSL needs to be compiled with enable-ssl-trace for this option to work.

You can, of course, use the flags -state, -debug and -msg to retrieve extensive information on how the selected protocol works as well as the states openssl goes through:

-state

prints out the SSL session states.

-debug

print extensive debugging information including a hex dump of all traffic.

-msg

show all protocol messages with hex dump.
2
  • Yes the -state option shows that a certificate was requested. But I would expect that, without any options, you would be warned that the handshake failed because a certificate was not provided. Sep 30 '15 at 12:27
  • What is the output when running with -trace set?
    – Sebi
    Sep 30 '15 at 12:39

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.