summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2009-06-05 14:59:26 +0000
committerDr. Stephen Henson <steve@openssl.org>2009-06-05 14:59:26 +0000
commit58f41a926a73bd5c49beb91991b486d4e0b544f5 (patch)
tree8d2cd903536ebd79dfb8c315727c6583fef3157d /ssl
parent81d06ef2fd64512e3833a13bedc004802003fbfa (diff)
Updates from 1.0.0-stable
Diffstat (limited to 'ssl')
-rw-r--r--ssl/d1_both.c8
-rw-r--r--ssl/d1_clnt.c2
-rw-r--r--ssl/d1_pkt.c10
-rw-r--r--ssl/d1_srvr.c2
-rw-r--r--ssl/dtls1.h1
5 files changed, 20 insertions, 3 deletions
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;