diff options
author | Emilia Kasper <emilia@openssl.org> | 2014-11-19 17:01:36 +0100 |
---|---|---|
committer | Emilia Kasper <emilia@openssl.org> | 2014-11-20 15:17:36 +0100 |
commit | e5f261df7369a8d1734045ed59e12b42142a9147 (patch) | |
tree | 7a149a3254d47240c1de4424e913f7ad4dd10fca /ssl/s3_clnt.c | |
parent | 9baee0216fe3bf572435a867963bdeea8ad95b59 (diff) |
Ensure SSL3_FLAGS_CCS_OK (or d1->change_cipher_spec_ok for DTLS) is reset
once the ChangeCipherSpec message is received. Previously, the server would
set the flag once at SSL3_ST_SR_CERT_VRFY and again at SSL3_ST_SR_FINISHED.
This would allow a second CCS to arrive and would corrupt the server state.
(Because the first CCS would latch the correct keys and subsequent CCS
messages would have to be encrypted, a MitM attacker cannot exploit this,
though.)
Thanks to Joeri de Ruiter for reporting this issue.
Reviewed-by: Matt Caswell <matt@openssl.org>
(cherry picked from commit e94a6c0ede623960728415b68650a595e48f5a43)
Diffstat (limited to 'ssl/s3_clnt.c')
-rw-r--r-- | ssl/s3_clnt.c | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index f8d76781f2..c9b5ee1831 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -273,6 +273,9 @@ int ssl3_connect(SSL *s) s->state=SSL3_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; s->init_num=0; + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + /* Should have been reset by ssl3_get_finished, too. */ + s->s3->change_cipher_spec = 0; break; case SSL3_ST_CW_CLNT_HELLO_A: @@ -421,12 +424,10 @@ int ssl3_connect(SSL *s) else { s->state=SSL3_ST_CW_CHANGE_A; - s->s3->change_cipher_spec=0; } if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { s->state=SSL3_ST_CW_CHANGE_A; - s->s3->change_cipher_spec=0; } s->init_num=0; @@ -438,7 +439,6 @@ int ssl3_connect(SSL *s) if (ret <= 0) goto end; s->state=SSL3_ST_CW_CHANGE_A; s->init_num=0; - s->s3->change_cipher_spec=0; break; case SSL3_ST_CW_CHANGE_A: @@ -498,7 +498,6 @@ int ssl3_connect(SSL *s) s->method->ssl3_enc->client_finished_label, s->method->ssl3_enc->client_finished_label_len); if (ret <= 0) goto end; - s->s3->flags |= SSL3_FLAGS_CCS_OK; s->state=SSL3_ST_CW_FLUSH; /* clear flags */ @@ -547,7 +546,6 @@ int ssl3_connect(SSL *s) case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: - s->s3->flags |= SSL3_FLAGS_CCS_OK; ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); @@ -986,7 +984,6 @@ int ssl3_get_server_hello(SSL *s) s->session->cipher = pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s, p+j); s->hit = 1; - s->s3->flags |= SSL3_FLAGS_CCS_OK; } } #endif /* OPENSSL_NO_TLSEXT */ @@ -1002,7 +999,6 @@ int ssl3_get_server_hello(SSL *s) SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); goto f_err; } - s->s3->flags |= SSL3_FLAGS_CCS_OK; s->hit=1; } /* a miss or crap from the other end */ |