summaryrefslogtreecommitdiffstats
path: root/ssl/s3_clnt.c
diff options
context:
space:
mode:
authorEmilia Kasper <emilia@openssl.org>2014-11-19 17:01:36 +0100
committerEmilia Kasper <emilia@openssl.org>2014-11-20 14:57:15 +0100
commite94a6c0ede623960728415b68650a595e48f5a43 (patch)
tree9ac092e0c94be7bbaeab1a766d4015dbe65896ca /ssl/s3_clnt.c
parentde2c7504ebd4ec15334ae151a31917753468f86f (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>
Diffstat (limited to 'ssl/s3_clnt.c')
-rw-r--r--ssl/s3_clnt.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 64439c164a..ee0493f576 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -280,6 +280,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:
@@ -428,12 +431,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;
@@ -445,7 +446,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:
@@ -505,7 +505,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 */
@@ -554,7 +553,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);
@@ -992,7 +990,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 */
@@ -1008,7 +1005,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 */