From 4128aa71ee553dc08859e50b7ec141fb47ef0f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 21 Mar 2014 09:40:12 +0100 Subject: [PATCH] Add the 'cookie' field of DTLS ClientHello --- library/ssl_cli.c | 37 ++++++++++++++++++++++++++----------- library/ssl_srv.c | 45 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 45d97c99b..9acc1e134 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -520,11 +520,13 @@ static int ssl_write_client_hello( ssl_context *ssl ) /* * 38 . 38 session id length * 39 . 39+n session id - * 40+n . 41+n ciphersuitelist length - * 42+n . .. ciphersuitelist - * .. . .. compression methods length + * 39+n . 39+n DTLS only: cookie length (1 byte) + * 40+n . .. DTSL only: cookie + * .. . .. ciphersuitelist length (2 bytes) + * .. . .. ciphersuitelist + * .. . .. compression methods length (1 byte) * .. . .. compression methods - * .. . .. extensions length + * .. . .. extensions length (2 bytes) * .. . .. extensions */ n = ssl->session_negotiate->length; @@ -561,16 +563,29 @@ static int ssl_write_client_hello( ssl_context *ssl ) SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); - ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; - n = 0; - q = p; - - // Skip writing ciphersuite length for now - p += 2; + /* + * DTLS cookie + */ +#if defined(POLARSSL_SSL_PROTO_DTLS) + if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) + { + /* TODO-DTLS: for now, just send an empty cookie, later on must send + * back the cookie from HelloVerifyRequest */ + *p++ = 0; + } +#endif /* - * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV + * Ciphersuite list */ + ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; + + /* Skip writing ciphersuite length for now */ + n = 0; + q = p; + p += 2; + + /* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) { *p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 25b553532..fd83ef25c 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -1122,6 +1122,9 @@ static int ssl_parse_client_hello( ssl_context *ssl ) unsigned int i, j; unsigned int ciph_offset, comp_offset, ext_offset; unsigned int msg_len, ciph_len, sess_len, comp_len, ext_len; +#if defined(POLARSSL_SSL_PROTO_DTLS) + unsigned int cookie_offset, cookie_len; +#endif unsigned char *buf, *p, *ext; int renegotiation_info_seen = 0; int handshake_failure = 0; @@ -1249,11 +1252,13 @@ static int ssl_parse_client_hello( ssl_context *ssl ) * 0 . 0 handshake type * 1 . 3 handshake length * 4 . 5 protocol version - * 6 . 37 random bytes (starting with 4 byte of Unix time) - * 38 . 38 session id length + * 6 . 37 random bytes (starting with 4 bytes of Unix time) + * 38 . 38 session id length (1 byte) * 39 . 38+x session id - * 39+x . 40+x ciphersuite list length - * 41+x . .. ciphersuite list + * 39+x . 39+x DTLS only: cookie length (1 byte) + * 40+x . .. DTSL only: cookie + * .. . .. ciphersuite list length (2 bytes) + * .. . .. ciphersuite list * .. . .. compression alg. list length (1 byte) * .. . .. compression alg. list * .. . .. extensions length (2 bytes, optional) @@ -1333,7 +1338,7 @@ static int ssl_parse_client_hello( ssl_context *ssl ) sess_len = buf[38]; if( sess_len > sizeof( ssl->session_negotiate->id ) || - sess_len + 39 + 2 > msg_len ) /* 2 for cipherlist length field */ + sess_len + 38 + 2 > msg_len ) /* 2 for cipherlist length field */ { SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -1348,10 +1353,38 @@ static int ssl_parse_client_hello( ssl_context *ssl ) memcpy( ssl->session_negotiate->id, buf + 39, ssl->session_negotiate->length ); + /* + * Check the cookie length and content + */ +#if defined(POLARSSL_SSL_PROTO_DTLS) + if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) + { + cookie_offset = 39 + sess_len; + cookie_len = buf[cookie_offset]; + + if( // cookie_len > || // TODO-DTLS + cookie_offset + 1 + cookie_len + 2 > msg_len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + SSL_DEBUG_BUF( 3, "client hello, cookie", + buf + cookie_offset + 1, cookie_len ); + + // TODO-DTLS: check cookie, reject if invalid! + } +#endif + /* * Check the ciphersuitelist length (will be parsed later) */ - ciph_offset = 39 + sess_len; +#if defined(POLARSSL_SSL_PROTO_DTLS) + if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) + ciph_offset = cookie_offset + 1 + cookie_len; + else +#endif + ciph_offset = 39 + sess_len; ciph_len = ( buf[ciph_offset + 0] << 8 ) | ( buf[ciph_offset + 1] );