From 0a89c575de613ff6fa3506b6ec025e786f9d0097 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Sun, 30 Sep 2007 21:20:59 +0000 Subject: [PATCH] Make ChangeCipherSpec compliant with DTLS RFC4347. From HEAD with a twist: server interoperates with non-compliant pre-0.9.8f. --- ssl/d1_both.c | 12 ++++++---- ssl/d1_pkt.c | 65 +++++++++++++++++++++++---------------------------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 7e6d300377..a17ebfa925 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -816,9 +816,14 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) *p++=SSL3_MT_CCS; s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; s->d1->next_handshake_write_seq++; - s2n(s->d1->handshake_write_seq,p); - s->init_num=DTLS1_CCS_HEADER_LENGTH; + + if (s->client_version == DTLS1_BAD_VER) + { + s2n(s->d1->handshake_write_seq,p); + s->init_num+=2; + } + s->init_off=0; dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, @@ -1056,7 +1061,7 @@ dtls1_buffer_message(SSL *s, int is_ccs) if ( is_ccs) { OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_CCS_HEADER_LENGTH == (unsigned int)s->init_num); + DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); } else { @@ -1259,5 +1264,4 @@ dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); ccs_hdr->type = *(data++); - n2s(data, ccs_hdr->seq); } diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index 24ef9ec3d2..333a26c0c2 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -974,47 +974,40 @@ start: } if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) - { - struct ccs_header_st ccs_hdr; + { + struct ccs_header_st ccs_hdr; dtls1_get_ccs_header(rr->data, &ccs_hdr); - if ( ccs_hdr.seq == s->d1->handshake_read_seq) - { - /* 'Change Cipher Spec' is just a single byte, so we know - * exactly what the record payload has to look like */ - /* XDTLS: check that epoch is consistent */ - if ( (rr->length != DTLS1_CCS_HEADER_LENGTH) || - (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) - { - i=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto err; - } - - rr->length=0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - rr->data, 1, s, s->msg_callback_arg); - - s->s3->change_cipher_spec=1; - if (!ssl3_do_change_cipher_spec(s)) - goto err; - - /* do this whenever CCS is processed */ - dtls1_reset_seq_numbers(s, SSL3_CC_READ); - - /* handshake read seq is reset upon handshake completion */ - s->d1->handshake_read_seq++; - - goto start; - } - else + /* 'Change Cipher Spec' is just a single byte, so we know + * exactly what the record payload has to look like */ + /* XDTLS: check that epoch is consistent */ + if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) || + (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) || + (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - rr->length = 0; - goto start; + i=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto err; } + + rr->length=0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, + rr->data, 1, s, s->msg_callback_arg); + + s->s3->change_cipher_spec=1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + + /* do this whenever CCS is processed */ + dtls1_reset_seq_numbers(s, SSL3_CC_READ); + + /* handshake read seq is reset upon handshake completion */ + s->d1->handshake_read_seq++; + + goto start; } /* Unexpected handshake message (Client Hello, or protocol violation) */ -- 2.25.1