From a03a9dbe2a3ac45661568ad809c25ddd7c5e79b7 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 22 Nov 2016 16:23:22 +0000 Subject: [PATCH] Fix SSL_VERIFY_CLIENT_ONCE The flag SSL_VERIFY_CLIENT_ONCE is documented as follows: B only request a client certificate on the initial TLS/SSL handshake. Do not ask for a client certificate again in case of a renegotiation. This flag must be used together with SSL_VERIFY_PEER. B ignored But the implementation actually did nothing. After the server sends its ServerKeyExchange message, the code was checking s->session->peer to see if it is NULL. If it was set then it did not ask for another client certificate. However s->session->peer will only be set in the event of a resumption, but a ServerKeyExchange message is only sent in the event of a full handshake (i.e. no resumption). The documentation suggests that the original intention was for this to have an effect on renegotiation, and resumption doesn't come into it. The fix is to properly check for renegotiation, not whether there is already a client certificate in the session. As far as I can tell this has been broken for a *long* time. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/1982) --- ssl/statem/statem_srvr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index e2d0836b5a..65eeaffe9a 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -353,7 +353,7 @@ static int send_certificate_request(SSL *s) * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert * during re-negotiation: */ - && ((s->session->peer == NULL) || + && (s->s3->tmp.finish_md_len == 0 || !(s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) /* * never request cert in anonymous ciphersuites (see -- 2.25.1