diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 226485add..bf5d7243d 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -616,6 +616,9 @@ struct _ssl_handshake_params ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ #endif #endif /* POLARSSL_X509_CRT_PARSE_C */ +#if defined(POLARSSL_SSL_PROTO_DTLS) + unsigned int msg_seq; /*!< DTLS handshake sequence number */ +#endif /* * Checksum contexts diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 07bbd3d7c..9f73c07e5 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -1203,6 +1203,8 @@ static int ssl_parse_client_hello( ssl_context *ssl ) else n = ssl->in_msglen; + SSL_DEBUG_BUF( 4, "record contents", buf, n ); + ssl->handshake->update_checksum( ssl, buf, n ); /* @@ -1211,7 +1213,17 @@ static int ssl_parse_client_hello( ssl_context *ssl ) #if defined(POLARSSL_SSL_PROTO_DTLS) if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) { - // TODO: DTLS: actually use the additional fields before removing them! + // TODO: DTLS: check message_seq + + /* For now we don't support fragmentation, so make sure + * fragment_offset == 0 and fragment_length == length */ + if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || + memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "handshake fragmentation not supported" ) ); + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + } + memmove( buf + 4, buf + 12, n - 12 ); n -= 8; @@ -1233,8 +1245,6 @@ static int ssl_parse_client_hello( ssl_context *ssl ) * 42+y . 41+z compression algs * .. . .. extensions */ - SSL_DEBUG_BUF( 4, "record contents", buf, n ); - SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) ); SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e9ede30c2..e009b9717 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1934,12 +1934,19 @@ int ssl_write_record( ssl_context *ssl ) #if defined(POLARSSL_SSL_PROTO_DTLS) if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) { - memmove( ssl->out_msg + 12, ssl->out_msg + 4, ssl->out_msglen - 4 ); + /* Make room for the additional DTLS fields */ + memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 ); ssl->out_msglen += 8; len += 8; - // TODO: DTLS: fill additional fields correctly - memset( ssl->out_msg + 4, 0x00, 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 ); + + /* We don't fragment, so frag_offset = 0 and frag_len = len */ + memset( ssl->out_msg + 6, 0x00, 3 ); + memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); } #endif /* POLARSSL_SSL_PROTO_DTLS */ @@ -2048,7 +2055,16 @@ static int ssl_prepare_handshake_record( ssl_context *ssl ) #if defined(POLARSSL_SSL_PROTO_DTLS) if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) { - // TODO: DTLS: actually use the additional fields before removing them! + // TODO: DTLS: check message_seq + + /* For now we don't support fragmentation, so make sure + * fragment_offset == 0 and fragment_length == length */ + if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || + memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "handshake fragmentation not supported" ) ); + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + } memmove( ssl->in_msg + 4, ssl->in_msg + 12, ssl->in_hslen - 12 ); ssl->in_hslen -= 8;