From 58f41a926a73bd5c49beb91991b486d4e0b544f5 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 5 Jun 2009 14:59:26 +0000 Subject: Updates from 1.0.0-stable --- ssl/d1_both.c | 8 ++++++-- ssl/d1_clnt.c | 2 +- ssl/d1_pkt.c | 10 ++++++++++ ssl/d1_srvr.c | 2 ++ ssl/dtls1.h | 1 + 5 files changed, 20 insertions(+), 3 deletions(-) (limited to 'ssl') diff --git a/ssl/d1_both.c b/ssl/d1_both.c index ebc03482f0..a56586f4e9 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -569,9 +569,13 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) item = pqueue_find(s->d1->buffered_messages, seq64be); /* Discard the message if sequence number was already there, is - * too far in the future or the fragment is already in the queue */ + * too far in the future, already in the queue or if we received + * a FINISHED before the SERVER_HELLO, which then must be a stale + * retransmit. + */ if (msg_hdr->seq <= s->d1->handshake_read_seq || - msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL) + msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || + (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) { unsigned char devnull [256]; diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index 2364ad2f8d..a4a438ac79 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c @@ -442,7 +442,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: - + s->d1->change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); if (ret <= 0) goto end; diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index a89edbc7a7..394daf6258 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -1102,6 +1102,16 @@ start: s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, s->msg_callback_arg); + /* We can't process a CCS now, because previous handshake + * messages are still missing, so just drop it. + */ + if (!s->d1->change_cipher_spec_ok) + { + goto start; + } + + s->d1->change_cipher_spec_ok = 0; + s->s3->change_cipher_spec=1; if (!ssl3_do_change_cipher_spec(s)) goto err; diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 6d6363f04f..ac09b45ef1 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -497,6 +497,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: + s->d1->change_cipher_spec_ok = 1; /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; @@ -508,6 +509,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: + s->d1->change_cipher_spec_ok = 1; ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; diff --git a/ssl/dtls1.h b/ssl/dtls1.h index 2fe0405011..73af56d45c 100644 --- a/ssl/dtls1.h +++ b/ssl/dtls1.h @@ -231,6 +231,7 @@ typedef struct dtls1_state_st unsigned int handshake_fragment_len; unsigned int retransmitting; + unsigned int change_cipher_spec_ok; } DTLS1_STATE; -- cgit v1.2.3