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 e94a6c0ede
)
This commit is contained in:
@@ -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 */
|
||||
|
Reference in New Issue
Block a user