From: Matt Caswell Date: Wed, 22 Jun 2016 18:43:46 +0000 (+0100) Subject: Fix SSLv3 alert if no Client Ceritifcate sent after a request for one X-Git-Tag: OpenSSL_1_1_0-pre6~205 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=672f3337c36d932bf214edf0a1a65fd069142282 Fix SSLv3 alert if no Client Ceritifcate sent after a request for one In TLS if the server sends a CertificateRequest and the client does not provide one, if the server cannot continue it should send a HandshakeFailure alert. In SSLv3 the same should happen, but instead we were sending an UnexpectedMessage alert. This is incorrect - the message isn't unexpected - it is valid for the client not to send one - its just that we cannot continue without one. Reviewed-by: Emilia Käsper --- diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index 28483e7944..c34110b0ca 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -531,8 +531,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) { * to that state if so */ if(!transition(s, mt)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_READ_STATE_MACHINE, SSL_R_UNEXPECTED_MESSAGE); + ossl_statem_set_error(s); return SUB_STATE_ERROR; } diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 2ab1f8e3f0..864f76cfcd 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -175,7 +175,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) } else { ske_expected = key_exchange_expected(s); if (ske_expected < 0) - return 0; + goto err; /* SKE is optional for some PSK ciphersuites */ if (ske_expected || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) @@ -210,7 +210,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) case TLS_ST_CR_CERT_STATUS: ske_expected = key_exchange_expected(s); if (ske_expected < 0) - return 0; + goto err; /* SKE is optional for some PSK ciphersuites */ if (ske_expected || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) @@ -219,7 +219,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_CR_KEY_EXCH; return 1; } - return 0; + goto err; } /* Fall through */ @@ -229,7 +229,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_CR_CERT_REQ; return 1; } - return 0; + goto err; } /* Fall through */ @@ -270,7 +270,10 @@ int ossl_statem_client_read_transition(SSL *s, int mt) break; } + err: /* No valid transition found */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_READ_STATE_MACHINE, SSL_R_UNEXPECTED_MESSAGE); return 0; } diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 773591cd38..c011523228 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -114,6 +114,17 @@ int ossl_statem_server_read_transition(SSL *s, int mt) return 1; } } + if (mt == SSL3_MT_CLIENT_KEY_EXCHANGE && s->s3->tmp.cert_request + && s->version == SSL3_VERSION) { + /* + * This isn't an unexpected message as such - we're just not going + * to accept it. + */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_READ_STATE_MACHINE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + return 0; + } break; case TLS_ST_SR_CERT: @@ -197,6 +208,8 @@ int ossl_statem_server_read_transition(SSL *s, int mt) } /* No valid transition found */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_READ_STATE_MACHINE, SSL_R_UNEXPECTED_MESSAGE); return 0; }