diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index f30d408230..f9cfff5217 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -115,8 +115,79 @@ static int ssl_tls13_write_key_shares_ext( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ -/* Functions for writing ClientHello message */ +/* Write ciphersuites + * CipherSuite cipher_suites<2..2^16-2>; + */ +static int ssl_tls13_write_client_hello_ciphersuites( + mbedtls_ssl_context *ssl, + unsigned char *buf, + unsigned char *end, + size_t *olen ) +{ + /* Ciphersuite-related variables */ + const int *ciphersuites; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + /* ciphersuite_start points to the start of + the ciphersuite list, i.e. to the length field*/ + unsigned char *ciphersuite_start, *ciphersuite_iter; + size_t buf_len; + *olen = 0 ; + + /* + * Ciphersuite list + * + * This is a list of the symmetric cipher options supported by + * the client, specifically the record protection algorithm + * ( including secret key length ) and a hash to be used with + * HKDF, in descending order of client preference. + */ + ciphersuites = ssl->conf->ciphersuite_list; + + /* Check available spaces for ciphersuite */ + MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 ); + + /* Write ciphersuites */ + ciphersuite_start = buf + 2; + ciphersuite_iter = ciphersuite_start; + + for ( size_t i = 0; ciphersuites[i] != 0; i++ ) + { + ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); + + if( ciphersuite_info == NULL ) + continue; + + if( ciphersuite_info->min_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 || + ciphersuite_info->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ) + continue; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x, %s", + (unsigned int) ciphersuites[i], + ciphersuite_info->name ) ); + + /* Check for available spaces */ + MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 ); + + MBEDTLS_PUT_UINT16_BE( ciphersuites[i], ciphersuite_iter, 0); + ciphersuite_iter += 2; + + } + + buf_len = ciphersuite_iter - ciphersuite_start; + + /* write ciphersuite buf length */ + MBEDTLS_PUT_UINT16_BE( buf_len, buf, 0 ); + + + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, got %" MBEDTLS_PRINTF_SIZET " ciphersuites", + buf_len/2 ) ); + + return( 0 ); +} + +/* Functions for writing ClientHello message */ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, unsigned char *buf, size_t buflen, @@ -139,13 +210,7 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, unsigned char *start = buf; unsigned char *end = buf + buflen; - /* Ciphersuite-related variables */ - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - /* ciphersuite_start points to the start of - the ciphersuite list, i.e. to the length field*/ - unsigned char *ciphersuite_start; - size_t ciphersuite_count; + *len_with_binders = 0; /* Keeping track of the included extensions */ ssl->handshake->extensions_present = MBEDTLS_SSL_EXT_NONE; @@ -169,7 +234,9 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, ssl->major_ver = ssl->conf->min_major_ver; ssl->minor_ver = ssl->conf->min_minor_ver; - /* For TLS 1.3 we use the legacy version number {0x03, 0x03} + /* Write legacy_version + * ProtocolVersion legacy_version = 0x0303; // TLS v1.2 + * For TLS 1.3 we use the legacy version number {0x03, 0x03} * instead of the true version number. * * For DTLS 1.3 we use the legacy version number @@ -180,16 +247,16 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, MBEDTLS_SSL_CHK_BUF_PTR( buf, end, CLIENT_HELLO_LEGACY_VERSION_LEN ); MBEDTLS_PUT_UINT16_BE( 0x0303, buf, 0); buf += CLIENT_HELLO_LEGACY_VERSION_LEN; - buflen -= CLIENT_HELLO_LEGACY_VERSION_LEN; - /* Write random bytes */ + /* Write random bytes + Random random + */ MBEDTLS_SSL_CHK_BUF_PTR( buf, end, CLIENT_HELLO_RANDOM_LEN ); memcpy( buf, ssl->handshake->randbytes, CLIENT_HELLO_RANDOM_LEN ); MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf, CLIENT_HELLO_RANDOM_LEN ); buf += CLIENT_HELLO_RANDOM_LEN; - buflen -= CLIENT_HELLO_RANDOM_LEN; /* Versions of TLS before TLS 1.3 supported a * "session resumption" feature which has been merged with pre-shared @@ -203,74 +270,14 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, * ossification ). Otherwise, it MUST be set as a zero-length vector * ( i.e., a zero-valued single byte length field ). */ - if( buflen < 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - + MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 1 ); *buf++ = 0; /* session id length set to zero */ - buflen -= 1; - /* - * Ciphersuite list - * - * This is a list of the symmetric cipher options supported by - * the client, specifically the record protection algorithm - * ( including secret key length ) and a hash to be used with - * HKDF, in descending order of client preference. - */ - ciphersuites = ssl->conf->ciphersuite_list; - - if( buflen < 2 /* for ciphersuite list length */ ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - /* Skip writing ciphersuite length for now */ - ciphersuite_count = 0; - ciphersuite_start = buf; - buf += 2; - buflen -= 2; - - for ( size_t i = 0; ciphersuites[i] != 0; i++ ) - { - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); - - if( ciphersuite_info == NULL ) - continue; - - if( ciphersuite_info->min_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 || - ciphersuite_info->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ) - continue; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x, %s", - (unsigned int) ciphersuites[i], - ciphersuite_info->name ) ); - - ciphersuite_count++; - - if( buflen < 2 /* for ciphersuite list length */ ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - MBEDTLS_PUT_UINT16_BE( ciphersuites[i], buf, 0); - - buf += 2; - buflen -= 2; - - } - - /* write ciphersuite length now */ - MBEDTLS_PUT_UINT16_BE( ciphersuite_count*2, ciphersuite_start, 0 ); - ciphersuite_start += 2; - - MBEDTLS_SSL_DEBUG_MSG( 3, - ( "client hello, got %" MBEDTLS_PRINTF_SIZET " ciphersuites", - ciphersuite_count ) ); + /* Write ciphersuites */ + ret = ssl_tls13_write_client_hello_ciphersuites( ssl, buf, end, &cur_ext_len ); + if( ret != 0) + return( ret ); + buf += cur_ext_len; /* For every TLS 1.3 ClientHello, this vector MUST contain exactly * one byte set to zero, which corresponds to the 'null' compression @@ -278,20 +285,13 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, * * For cTLS this field is elided. */ - if( buflen < 2 /* for ciphersuite list length */ ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - + MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 ); *buf++ = 1; *buf++ = MBEDTLS_SSL_COMPRESS_NULL; - buflen -= 2; /* First write extensions, then the total length */ extension_start = buf; - total_ext_len = 0; buf += 2; /* Supported Versions Extension is mandatory with TLS 1.3. @@ -302,7 +302,6 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, ret = ssl_tls13_write_supported_versions_ext( ssl, buf, end, &cur_ext_len ); if( ret != 0 ) return( ret ); - total_ext_len += cur_ext_len; buf += cur_ext_len; #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) @@ -312,8 +311,6 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, ret = ssl_tls13_write_supported_groups_ext( ssl, buf, end, &cur_ext_len ); if( ret != 0 ) return( ret ); - - total_ext_len += cur_ext_len; buf += cur_ext_len; /* The supported_signature_algorithms extension is REQUIRED for @@ -321,8 +318,6 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, ret = mbedtls_ssl_tls13_write_sig_alg_ext( ssl, buf, end, &cur_ext_len ); if( ret != 0 ) return( ret ); - - total_ext_len += cur_ext_len; buf += cur_ext_len; /* We need to send the key shares under three conditions: @@ -338,13 +333,13 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, ret = ssl_tls13_write_key_shares_ext( ssl, buf, end, &cur_ext_len ); if( ret != 0 ) return( ret ); - - total_ext_len += cur_ext_len; buf += cur_ext_len; + #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ /* Add more extensions here */ + total_ext_len = buf - extension_start - 2; MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %" MBEDTLS_PRINTF_SIZET , total_ext_len ) ); @@ -354,7 +349,7 @@ static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl, MBEDTLS_PUT_UINT16_BE( total_ext_len, extension_start, 0 ); extension_start += 2; - *len_with_binders = ( extension_start + total_ext_len ) - start; + *len_with_binders = buf - start; return( 0 ); } @@ -390,9 +385,6 @@ static int ssl_tls13_prepare_client_hello( mbedtls_ssl_context *ssl ) * * Structure of this message: * - * uint16 ProtocolVersion; - * opaque Random[32]; - * uint8 CipherSuite[2]; // Cryptographic suite selector * struct { * ProtocolVersion legacy_version = 0x0303; // TLS v1.2 * Random random;