diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 977a5b2bc..9ae336a72 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2027,10 +2027,18 @@ int ssl_write_record( ssl_context *ssl ) ssl->out_msglen += 8; len += 8; - /* Write message_seq and update it */ - ssl->out_msg[4] = ( ssl->handshake->msg_seq >> 8 ) & 0xFF; - ssl->out_msg[5] = ( ssl->handshake->msg_seq ) & 0xFF; - ++( ssl->handshake->msg_seq ); + /* Write message_seq and update it, except for HelloRequest */ + if( ssl->out_msg[0] != SSL_HS_HELLO_REQUEST ) + { + ssl->out_msg[4] = ( ssl->handshake->msg_seq >> 8 ) & 0xFF; + ssl->out_msg[5] = ( ssl->handshake->msg_seq ) & 0xFF; + ++( ssl->handshake->msg_seq ); + } + else + { + ssl->out_msg[4] = 0; + ssl->out_msg[5] = 0; + } /* We don't fragment, so frag_offset = 0 and frag_len = len */ memset( ssl->out_msg + 6, 0x00, 3 ); @@ -2137,12 +2145,15 @@ static int ssl_prepare_handshake_record( ssl_context *ssl ) ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); /* - * For DTLS, we move data so that is looks like - * TLS handshake format to other functions. + * For DTLS, we move data so that is looks like TLS handshake format to + * other functions. + * Except on server after the initial handshake (wait until after + * update_checksum() in ssl_parse_client_hello()). */ #if defined(POLARSSL_SSL_PROTO_DTLS) if( ssl->transport == SSL_TRANSPORT_DATAGRAM && - ssl->state != SSL_HANDSHAKE_OVER ) + ! ( ssl->endpoint == SSL_IS_SERVER && + ssl->state == SSL_HANDSHAKE_OVER ) ) { // TODO: DTLS: check message_seq diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index cea5790e0..1dac6d63b 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -868,6 +868,19 @@ run_test "Renegotiation: DTLS, client-initiated" \ -s "=> renegotiate" \ -S "write hello request" +run_test "Renegotiation: DTLS, server-initiated" \ + "$P_SRV debug_level=3 dtls=1 exchanges=2 renegotiation=1 renegotiate=1" \ + "$P_CLI debug_level=3 dtls=1 exchanges=2 renegotiation=1" \ + 0 \ + -c "client hello, adding renegotiation extension" \ + -s "received TLS_EMPTY_RENEGOTIATION_INFO" \ + -s "found renegotiation extension" \ + -s "server hello, secure renegotiation extension" \ + -c "found renegotiation extension" \ + -c "=> renegotiate" \ + -s "=> renegotiate" \ + -s "write hello request" + # Tests for auth_mode run_test "Authentication: server badcert, client required" \