diff --git a/ChangeLog.d/uniformize_bounds_checks.txt b/ChangeLog.d/uniformize_bounds_checks.txt new file mode 100644 index 000000000..210ab1051 --- /dev/null +++ b/ChangeLog.d/uniformize_bounds_checks.txt @@ -0,0 +1,9 @@ +Bugfix + * Add additional bounds checks in ssl_write_client_hello() preventing + output buffer overflow if the configuration declared a buffer that was + too small. +Changes + * Abort the ClientHello writing function as soon as some extension doesn't + fit into the record buffer. Previously, such extensions were silently + dropped. As a consequence, the TLS handshake now fails when the output + buffer is not large enough to hold the ClientHello. diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 2fb86c7eb..428800188 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -101,7 +101,7 @@ * ECP 4 10 (Started from top) * MD 5 5 * HKDF 5 1 (Started from top) - * SSL 5 1 (Started from 0x5F00) + * SSL 5 2 (Started from 0x5F00) * CIPHER 6 8 (Started from 0x6080) * SSL 6 24 (Started from top, plus 0x6000) * SSL 7 32 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 65424d6d0..98264f9c2 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -129,6 +129,7 @@ #define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000 /**< An encrypted DTLS-frame with an unexpected CID was received. */ #define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00 /**< An operation failed due to an unexpected version or configuration. */ #define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */ +#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 /**< Invalid value in SSL config */ /* * Various constants @@ -144,6 +145,9 @@ #define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ #define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ +#define MBEDTLS_SSL_MAX_ALPN_NAME_LEN 255 /*!< Maximum size in bytes of a protocol name in alpn ext., RFC 7301 */ + +#define MBEDTLS_SSL_MAX_ALPN_LIST_LEN 65535 /*!< Maximum size in bytes of list in alpn ext., RFC 7301 */ /* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c * NONE must be zero so that memset()ing structure to zero works */ diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index cd881eb02..c68038c7b 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -207,6 +207,12 @@ : ( MBEDTLS_SSL_IN_CONTENT_LEN ) \ ) +/* Maximum size in bytes of list in sig-hash algorithm ext., RFC 5246 */ +#define MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN 65534 + +/* Maximum size in bytes of list in supported elliptic curve ext., RFC 4492 */ +#define MBEDTLS_SSL_MAX_CURVE_LIST_LEN 65535 + /* * Check that we obey the standard's message size bounds */ @@ -299,6 +305,41 @@ static inline uint32_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context * #define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) #define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) +/** + * \brief This function checks if the remaining size in a buffer is + * greater or equal than a needed space. + * + * \param cur Pointer to the current position in the buffer. + * \param end Pointer to one past the end of the buffer. + * \param need Needed space in bytes. + * + * \return Zero if the needed space is available in the buffer, non-zero + * otherwise. + */ +static inline int mbedtls_ssl_chk_buf_ptr( const uint8_t *cur, + const uint8_t *end, size_t need ) +{ + return( ( cur > end ) || ( need > (size_t)( end - cur ) ) ); +} + +/** + * \brief This macro checks if the remaining size in a buffer is + * greater or equal than a needed space. If it is not the case, + * it returns an SSL_BUFFER_TOO_SMALL error. + * + * \param cur Pointer to the current position in the buffer. + * \param end Pointer to one past the end of the buffer. + * \param need Needed space in bytes. + * + */ +#define MBEDTLS_SSL_CHK_BUF_PTR( cur, end, need ) \ + do { \ + if( mbedtls_ssl_chk_buf_ptr( ( cur ), ( end ), ( need ) ) != 0 ) \ + { \ + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); \ + } \ + } while( 0 ) + #ifdef __cplusplus extern "C" { #endif diff --git a/library/error.c b/library/error.c index be60798ce..57171b311 100644 --- a/library/error.c +++ b/library/error.c @@ -526,6 +526,8 @@ const char * mbedtls_high_level_strerr( int error_code ) return( "SSL - An operation failed due to an unexpected version or configuration" ); case -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS): return( "SSL - A cryptographic operation is in progress. Try again later" ); + case -(MBEDTLS_ERR_SSL_BAD_CONFIG): + return( "SSL - Invalid value in SSL config" ); #endif /* MBEDTLS_SSL_TLS_C */ #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 553e2b6a3..48ef30de2 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -95,29 +95,26 @@ static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf ) #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t hostname_len; *olen = 0; if( ssl->hostname == NULL ) - return; + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", - ssl->hostname ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding server name extension: %s", + ssl->hostname ) ); hostname_len = strlen( ssl->hostname ); - if( end < p || (size_t)( end - p ) < hostname_len + 9 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, hostname_len + 9 ); /* * Sect. 3, RFC 6066 (TLS Extensions Definitions) @@ -161,16 +158,18 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, memcpy( p, ssl->hostname, hostname_len ); *olen = hostname_len + 9; + + return( 0 ); } #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #if defined(MBEDTLS_SSL_RENEGOTIATION) -static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; @@ -178,21 +177,20 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, * initial ClientHello, in which case also adding the renegotiation * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - return; + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding renegotiation extension" ) ); - if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 + ssl->verify_data_len ); /* * Secure renegotiation */ - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) + & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) + & 0xFF ); *p++ = 0x00; *p++ = ( ssl->verify_data_len + 1 ) & 0xFF; @@ -201,6 +199,8 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); *olen = 5 + ssl->verify_data_len; + + return( 0 ); } #endif /* MBEDTLS_SSL_RENEGOTIATION */ @@ -209,14 +209,15 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) -static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t sig_alg_len = 0; const int *md; + #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) unsigned char *sig_alg_list = buf + 6; #endif @@ -224,9 +225,13 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, *olen = 0; if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - return; + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding signature_algorithms extension" ) ); + + if( ssl->conf->sig_hashes == NULL ) + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) { @@ -236,13 +241,19 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_RSA_C) sig_alg_len += 2; #endif + if( sig_alg_len > MBEDTLS_SSL_MAX_SIG_HASH_ALG_LIST_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "length in bytes of sig-hash-alg extension too big" ) ); + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); + } } - if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + /* Empty signature algorithms list, this is a configuration error. */ + if( sig_alg_len == 0 ) + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); + + MBEDTLS_SSL_CHK_BUF_PTR( p, end, sig_alg_len + 6 ); /* * Prepare signature_algorithms extension (TLS 1.2) @@ -288,75 +299,75 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF ); *olen = 6 + sig_alg_len; + + return( 0 ); } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; unsigned char *elliptic_curve_list = p + 6; size_t elliptic_curve_len = 0; const mbedtls_ecp_curve_info *info; -#if defined(MBEDTLS_ECP_C) const mbedtls_ecp_group_id *grp_id; -#else - ((void) ssl); -#endif *olen = 0; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding supported_elliptic_curves extension" ) ); -#if defined(MBEDTLS_ECP_C) - for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) -#else - for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) -#endif + if( ssl->conf->curve_list == NULL ) + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); + + for( grp_id = ssl->conf->curve_list; + *grp_id != MBEDTLS_ECP_DP_NONE; + grp_id++ ) { -#if defined(MBEDTLS_ECP_C) info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); -#endif if( info == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) ); - return; + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "invalid curve in ssl configuration" ) ); + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); } - elliptic_curve_len += 2; + + if( elliptic_curve_len > MBEDTLS_SSL_MAX_CURVE_LIST_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "malformed supported_elliptic_curves extension in config" ) ); + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); + } } - if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + /* Empty elliptic curve list, this is a configuration error. */ + if( elliptic_curve_len == 0 ) + return( MBEDTLS_ERR_SSL_BAD_CONFIG ); + + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + elliptic_curve_len ); elliptic_curve_len = 0; -#if defined(MBEDTLS_ECP_C) - for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) -#else - for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) -#endif + for( grp_id = ssl->conf->curve_list; + *grp_id != MBEDTLS_ECP_DP_NONE; + grp_id++ ) { -#if defined(MBEDTLS_ECP_C) info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); -#endif elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; } - if( elliptic_curve_len == 0 ) - return; - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) + & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) + & 0xFF ); *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF ); @@ -365,27 +376,28 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); *olen = 6 + elliptic_curve_len; + + return( 0 ); } -static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + (void) ssl; /* ssl used for debugging only */ *olen = 0; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding supported_point_formats extension" ) ); + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 ); - if( end < p || (size_t)( end - p ) < 6 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) + & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) + & 0xFF ); *p++ = 0x00; *p++ = 2; @@ -394,33 +406,32 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; *olen = 6; + + return( 0 ); } #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t kkpp_len; *olen = 0; /* Skip costly extension if we can't use EC J-PAKE anyway */ if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - return; + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding ecjpake_kkpp extension" ) ); - if( end - p < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); @@ -436,19 +447,20 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, - p + 2, end - p - 2, &kkpp_len, - ssl->conf->f_rng, ssl->conf->p_rng ); + p + 2, end - p - 2, &kkpp_len, + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); - return; + MBEDTLS_SSL_DEBUG_RET( 1 , + "mbedtls_ecjpake_write_round_one", ret ); + return( ret ); } ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len ); if( ssl->handshake->ecjpake_cache == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) ); - return; + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len ); @@ -459,12 +471,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) ); kkpp_len = ssl->handshake->ecjpake_cache_len; - - if( (size_t)( end - p - 2 ) < kkpp_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p + 2, end, kkpp_len ); memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len ); } @@ -473,17 +480,19 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); *olen = kkpp_len + 4; + + return( 0 ); } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_cid_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; size_t ext_len; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; /* * Quoting draft-ietf-tls-dtls-connection-id-05 @@ -498,17 +507,13 @@ static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) { - return; + return( 0 ); } MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding CID extension" ) ); /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX * which is at most 255, so the increment cannot overflow. */ - if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, (unsigned)( ssl->own_cid_len + 5 ) ); /* Add extension ID + size */ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID >> 8 ) & 0xFF ); @@ -521,33 +526,33 @@ static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, memcpy( p, ssl->own_cid, ssl->own_cid_len ); *olen = ssl->own_cid_len + 5; + + return( 0 ); } #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) +static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; - if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) { - return; - } + if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding max_fragment_length extension" ) ); - if( end < p || (size_t)( end - p ) < 5 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) + & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) + & 0xFF ); *p++ = 0x00; *p++ = 1; @@ -555,30 +560,28 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, *p++ = ssl->conf->mfl_code; *olen = 5; + + return( 0 ); } #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) +static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) - { - return; - } + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding truncated_hmac extension" ) ); - if( end < p || (size_t)( end - p ) < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); @@ -587,32 +590,29 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, *p++ = 0x00; *olen = 4; + + return( 0 ); } #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) +static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - return; - } + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " - "extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding encrypt_then_mac extension" ) ); - if( end < p || (size_t)( end - p ) < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); @@ -621,65 +621,63 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, *p++ = 0x00; *olen = 4; + + return( 0 ); } #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) +static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - return; - } + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " - "extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding extended_master_secret extension" ) ); - if( end < p || (size_t)( end - p ) < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) + & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) + & 0xFF ); *p++ = 0x00; *p++ = 0x00; *olen = 4; + + return( 0 ); } #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) -static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) +static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t tlen = ssl->session_negotiate->ticket_len; *olen = 0; if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) - { - return; - } + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, adding session ticket extension" ) ); - if( end < p || (size_t)( end - p ) < 4 + tlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + /* The addition is safe here since the ticket length is 16 bit. */ + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 + tlen ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); @@ -690,44 +688,40 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, *olen = 4; if( ssl->session_negotiate->ticket == NULL || tlen == 0 ) - { - return; - } + return( 0 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "sending session ticket of length %d", tlen ) ); memcpy( p, ssl->session_negotiate->ticket, tlen ); *olen += tlen; + + return( 0 ); } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ #if defined(MBEDTLS_SSL_ALPN) -static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) +static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t alpnlen = 0; const char **cur; *olen = 0; if( ssl->conf->alpn_list == NULL ) - { - return; - } + return( 0 ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) - alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1; + alpnlen += strlen( *cur ) + 1; - if( end < p || (size_t)( end - p ) < 6 + alpnlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + alpnlen ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); @@ -745,7 +739,11 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) { - *p = (unsigned char)( strlen( *cur ) & 0xFF ); + /* + * mbedtls_ssl_conf_set_alpn_protocols() checked that the length of + * protocol names is less than 255. + */ + *p = (unsigned char)strlen( *cur ); memcpy( p + 1, *cur, *p ); p += 1 + *p; } @@ -759,6 +757,8 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); + + return( 0 ); } #endif /* MBEDTLS_SSL_ALPN */ @@ -815,9 +815,10 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) * * \return 0 if valid, else 1 */ -static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info, - const mbedtls_ssl_context * ssl, - int min_minor_ver, int max_minor_ver ) +static int ssl_validate_ciphersuite( + const mbedtls_ssl_ciphersuite_t * suite_info, + const mbedtls_ssl_context * ssl, + int min_minor_ver, int max_minor_ver ) { (void) ssl; if( suite_info == NULL ) @@ -861,8 +862,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t i, n, olen, ext_len = 0; + unsigned char *buf; unsigned char *p, *q; + const unsigned char *end; + unsigned char offer_compress; const int *ciphersuites; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; @@ -889,23 +893,41 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) if( ssl->conf->max_major_ver == 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, " - "consider using mbedtls_ssl_config_defaults()" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "configured max major version is invalid, consider using mbedtls_ssl_config_defaults()" ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } + buf = ssl->out_msg; + end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN; + /* - * 0 . 0 handshake type - * 1 . 3 handshake length + * Check if there's enough space for the first part of the ClientHello + * consisting of the 38 bytes described below, the session identifier (at + * most 32 bytes) and its length (1 byte). + * + * Use static upper bounds instead of the actual values + * to allow the compiler to optimize this away. + */ + MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 38 + 1 + 32 ); + + /* + * The 38 first bytes of the ClientHello: + * 0 . 0 handshake type (written later) + * 1 . 3 handshake length (written later) * 4 . 5 highest version supported * 6 . 9 current UNIX time * 10 . 37 random bytes + * + * The current UNIX time (4 bytes) and following 28 random bytes are written + * by ssl_generate_random() into ssl->handshake->randbytes buffer and then + * copied from there into the output buffer. */ - buf = ssl->out_msg; - p = buf + 4; - mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, - ssl->conf->transport, p ); + p = buf + 4; + mbedtls_ssl_write_version( ssl->conf->max_major_ver, + ssl->conf->max_minor_ver, + ssl->conf->transport, p ); p += 2; MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", @@ -925,7 +947,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) * 38 . 38 session id length * 39 . 39+n session id * 39+n . 39+n DTLS only: cookie length (1 byte) - * 40+n . .. DTSL only: cookie + * 40+n . .. DTLS only: cookie * .. . .. ciphersuitelist length (2 bytes) * .. . .. ciphersuitelist * .. . .. compression methods length (1 byte) @@ -956,7 +978,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) if( ssl->session_negotiate->ticket != NULL && ssl->session_negotiate->ticket_len != 0 ) { - ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 ); + ret = ssl->conf->f_rng( ssl->conf->p_rng, + ssl->session_negotiate->id, 32 ); if( ret != 0 ) return( ret ); @@ -966,6 +989,12 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ + /* + * The first check of the output buffer size above ( + * MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 38 + 1 + 32 );) + * has checked that there is enough space in the output buffer for the + * session identifier length byte and the session identifier (n <= 32). + */ *p++ = (unsigned char) n; for( i = 0; i < n; i++ ) @@ -974,12 +1003,27 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); + /* + * With 'n' being the length of the session identifier + * + * 39+n . 39+n DTLS only: cookie length (1 byte) + * 40+n . .. DTLS only: cookie + * .. . .. ciphersuitelist length (2 bytes) + * .. . .. ciphersuitelist + * .. . .. compression methods length (1 byte) + * .. . .. compression methods + * .. . .. extensions length (2 bytes) + * .. . .. extensions + */ + /* * DTLS cookie */ #if defined(MBEDTLS_SSL_PROTO_DTLS) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 1 ); + if( ssl->handshake->verify_cookie == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) ); @@ -992,6 +1036,9 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ssl->handshake->verify_cookie_len ); *p++ = ssl->handshake->verify_cookie_len; + + MBEDTLS_SSL_CHK_BUF_PTR( p, end, + ssl->handshake->verify_cookie_len ); memcpy( p, ssl->handshake->verify_cookie, ssl->handshake->verify_cookie_len ); p += ssl->handshake->verify_cookie_len; @@ -1007,6 +1054,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) /* Skip writing ciphersuite length for now */ n = 0; q = p; + + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); p += 2; for( i = 0; ciphersuites[i] != 0; i++ ) @@ -1026,12 +1075,15 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info ); #endif + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); + n++; *p++ = (unsigned char)( ciphersuites[i] >> 8 ); *p++ = (unsigned char)( ciphersuites[i] ); } - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) ); /* * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV @@ -1041,6 +1093,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) #endif { MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); n++; @@ -1051,6 +1104,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) ); + + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ); *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ); n++; @@ -1081,8 +1136,10 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d", - MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) ); + MBEDTLS_SSL_COMPRESS_DEFLATE, + MBEDTLS_SSL_COMPRESS_NULL ) ); + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 3 ); *p++ = 2; *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE; *p++ = MBEDTLS_SSL_COMPRESS_NULL; @@ -1093,27 +1150,45 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", MBEDTLS_SSL_COMPRESS_NULL ) ); + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); *p++ = 1; *p++ = MBEDTLS_SSL_COMPRESS_NULL; } - // First write extensions, then the total length - // + /* First write extensions, then the total length */ + + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); + #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_hostname_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_hostname_ext", ret ); + return( ret ); + } ext_len += olen; #endif /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */ #if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_renegotiation_ext", ret ); + return( ret ); + } ext_len += olen; #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_signature_algorithms_ext", ret ); + return( ret ); + } ext_len += olen; #endif @@ -1121,51 +1196,100 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( uses_ec ) { - ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_elliptic_curves_ext", ret ); + return( ret ); + } ext_len += olen; - ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_supported_point_formats_ext", ret ); + return( ret ); + } ext_len += olen; } #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_ecjpake_kkpp_ext", ret ); + return( ret ); + } ext_len += olen; #endif #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_cid_ext( ssl, p + 2 + ext_len, end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_cid_ext", ret ); + return( ret ); + } ext_len += olen; #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_max_fragment_length_ext", ret ); + return( ret ); + } ext_len += olen; #endif #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_truncated_hmac_ext", ret ); + return( ret ); + } ext_len += olen; #endif #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_encrypt_then_mac_ext", ret ); + return( ret ); + } ext_len += olen; #endif #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_extended_ms_ext", ret ); + return( ret ); + } ext_len += olen; #endif #if defined(MBEDTLS_SSL_ALPN) - ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_alpn_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_alpn_ext", ret ); + return( ret ); + } ext_len += olen; #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) - ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); + if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_session_ticket_ext", ret ); + return( ret ); + } ext_len += olen; #endif @@ -1173,10 +1297,12 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ((void) olen); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", - ext_len ) ); + ext_len ) ); if( ext_len > 0 ) { + /* No need to check for space here, because the extension + * writing functions already took care of that. */ *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( ext_len ) & 0xFF ); p += ext_len; @@ -1229,8 +1355,10 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } } @@ -1239,9 +1367,12 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, { if( len != 1 || buf[0] != 0x00 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "non-zero length renegotiation info" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1264,9 +1395,12 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, len != 1 || buf[0] != ssl->conf->mfl_code ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "non-matching max fragment length extension" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1282,9 +1416,12 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED || len != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "non-matching truncated HMAC extension" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1361,9 +1498,12 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || len != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "non-matching encrypt-then-MAC extension" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1384,9 +1524,12 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || len != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "non-matching extended master secret extension" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1406,9 +1549,12 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || len != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "non-matching session ticket extension" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1489,8 +1635,10 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, buf, len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( ret ); } @@ -1509,8 +1657,10 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, if( ssl->conf->alpn_list == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1690,12 +1840,13 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ssl->conf->renego_max_records >= 0 && ssl->renego_records_seen > ssl->conf->renego_max_records ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " - "but not honored by server" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "renegotiation requested, but not honored by server" ) ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "non-handshake message during renegotiation" ) ); ssl->keep_current_message = 1; return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ); @@ -1703,8 +1854,10 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_RENEGOTIATION */ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -1758,11 +1911,13 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->major_ver > ssl->conf->max_major_ver || ssl->minor_ver > ssl->conf->max_minor_ver ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - " - " min: [%d:%d], server: [%d:%d], max: [%d:%d]", - ssl->conf->min_major_ver, ssl->conf->min_minor_ver, - ssl->major_ver, ssl->minor_ver, - ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "server version out of bounds - min: [%d:%d], server: [%d:%d], max: [%d:%d]", + ssl->conf->min_major_ver, + ssl->conf->min_minor_ver, + ssl->major_ver, ssl->minor_ver, + ssl->conf->max_major_ver, + ssl->conf->max_minor_ver ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); @@ -1799,8 +1954,10 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } } @@ -1839,9 +1996,12 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( comp != MBEDTLS_SSL_COMPRESS_NULL ) #endif/* MBEDTLS_ZLIB_SUPPORT */ { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "server hello, bad compression: %d", comp ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); } @@ -1851,7 +2011,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i ); if( ssl->handshake->ciphersuite_info == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "ciphersuite info for %04x not found", i ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -1891,8 +2052,10 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( ret ); } } @@ -1901,7 +2064,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->handshake->resume ? "a" : "no" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", + buf[37 + n] ) ); /* * Perform cipher suite validation in same way as in ssl_write_client_hello. @@ -1912,8 +2076,10 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1924,16 +2090,21 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) } } - suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ); - if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 ) + suite_info = mbedtls_ssl_ciphersuite_from_id( + ssl->session_negotiate->ciphersuite ); + if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, + ssl->minor_ver ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && @@ -1950,15 +2121,18 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } ssl->session_negotiate->compression = comp; ext = buf + 40 + n; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, + ( "server hello, total extension length: %d", ext_len ) ); while( ext_len ) { @@ -1970,8 +2144,9 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ext_size + 4 > ext_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( + ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1991,7 +2166,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "found max_fragment_length extension" ) ); if( ( ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ) ) != 0 ) @@ -2044,7 +2220,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "found extended_master_secret extension" ) ); if( ( ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ) ) != 0 ) @@ -2071,7 +2248,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "found supported_point_formats extension" ) ); if( ( ret = ssl_parse_supported_point_formats_ext( ssl, ext + 4, ext_size ) ) != 0 ) @@ -2107,8 +2285,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_ALPN */ default: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", - ext_id ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "unknown extension found: %d (ignoring)", ext_id ) ); } ext_len -= 4 + ext_size; @@ -2125,9 +2303,11 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) * Renegotiation security checks */ if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + ssl->conf->allow_legacy_renegotiation == + MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "legacy renegotiation, breaking off handshake" ) ); handshake_failure = 1; } #if defined(MBEDTLS_SSL_RENEGOTIATION) @@ -2135,12 +2315,14 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && renegotiation_info_seen == 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "renegotiation_info extension missing (secure)" ) ); handshake_failure = 1; } else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) + ssl->conf->allow_legacy_renegotiation == + MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); handshake_failure = 1; @@ -2149,15 +2331,18 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && renegotiation_info_seen == 1 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "renegotiation_info extension present (legacy)" ) ); handshake_failure = 1; } #endif /* MBEDTLS_SSL_RENEGOTIATION */ if( handshake_failure == 1 ) { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -2168,7 +2353,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p, +static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, + unsigned char **p, unsigned char *end ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; @@ -2182,7 +2368,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char * * opaque dh_Ys<1..2^16-1>; * } ServerDHParams; */ - if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 ) + if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, + p, end ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret ); return( ret ); @@ -2340,7 +2527,8 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, if( ssl_check_server_ecdh_params( ssl ) != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "bad server key exchange message (ECDHE curve)" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } @@ -2366,8 +2554,8 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, */ if( end - (*p) < 2 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " - "(psk_identity_hint length)" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "bad server key exchange message (psk_identity_hint length)" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } len = (*p)[0] << 8 | (*p)[1]; @@ -2375,8 +2563,8 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, if( end - (*p) < len ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " - "(psk_identity_hint length)" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "bad server key exchange message (psk_identity_hint length)" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } @@ -2419,8 +2607,9 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, * opaque random[46]; * } PreMasterSecret; */ - mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, - ssl->conf->transport, p ); + mbedtls_ssl_write_version( ssl->conf->max_major_ver, + ssl->conf->max_minor_ver, + ssl->conf->transport, p ); if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 ) { @@ -2506,20 +2695,22 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, /* * Get hash algorithm */ - if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE ) + if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) + == MBEDTLS_MD_NONE ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported " - "HashAlgorithm %d", *(p)[0] ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } /* * Get signature algorithm */ - if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE ) + if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) + == MBEDTLS_PK_NONE ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported " - "SignatureAlgorithm %d", (*p)[1] ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } @@ -2528,13 +2719,15 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, */ if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm %d that was not offered", - *(p)[0] ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "server used HashAlgorithm %d that was not offered", *(p)[0] ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", + (*p)[1] ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", + (*p)[0] ) ); *p += 2; return( 0 ); @@ -2625,8 +2818,10 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( ret ); } @@ -2656,8 +2851,10 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -2676,10 +2873,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) goto exit; } - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must " - "not be skipped" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "server key exchange message must not be skipped" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -2703,8 +2902,10 @@ start_processing: if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } /* FALLTROUGH */ @@ -2726,8 +2927,10 @@ start_processing: if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2743,8 +2946,10 @@ start_processing: if( ssl_parse_server_ecdh_params_psa( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2762,8 +2967,10 @@ start_processing: if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2779,8 +2986,10 @@ start_processing: if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2813,17 +3022,24 @@ start_processing: if( ssl_parse_signature_algorithm( ssl, &p, end, &md_alg, &pk_alg ) != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } - if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) + if( pk_alg != + mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2853,8 +3069,10 @@ start_processing: if( p > end - 2 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } sig_len = ( p[0] << 8 ) | p[1]; @@ -2863,8 +3081,10 @@ start_processing: if( p != end - sig_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } @@ -2924,8 +3144,10 @@ start_processing: if( !mbedtls_pk_can_do( peer_pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); } @@ -2940,8 +3162,10 @@ start_processing: #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) #endif - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) @@ -3013,8 +3237,10 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -3090,8 +3316,9 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) - | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); + size_t sig_alg_len = + ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) + | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); #if defined(MBEDTLS_DEBUG_C) unsigned char* sig_alg; size_t i; @@ -3109,11 +3336,14 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) * buf[...hdr_len + 3 + n + sig_alg_len], * which is one less than we need the buf to be. */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len ) + if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + + 3 + n + sig_alg_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } @@ -3121,8 +3351,9 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n; for( i = 0; i < sig_alg_len; i += 2 ) { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d" - ",%d", sig_alg[i], sig_alg[i + 1] ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "Supported Signature Algorithm found: %d,%d", + sig_alg[i], sig_alg[i + 1] ) ); } #endif @@ -3213,9 +3444,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) header_len = 6; ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - &ssl->out_msg[header_len], content_len, - ssl->conf->f_rng, ssl->conf->p_rng ); + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + &ssl->out_msg[header_len], content_len, + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); @@ -3226,10 +3457,10 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + ssl->handshake->premaster, + MBEDTLS_PREMASTER_SIZE, + &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); return( ret ); @@ -3379,10 +3610,10 @@ ecdh_calc_secret: content_len = ssl->handshake->ecrs_n; #endif if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + &ssl->handshake->pmslen, + ssl->handshake->premaster, + MBEDTLS_MPI_MAX_SIZE, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) @@ -3419,8 +3650,8 @@ ecdh_calc_secret: if( header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or " - "SSL buffer too short" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "psk identity too long or SSL buffer too short" ) ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } @@ -3471,8 +3702,8 @@ ecdh_calc_secret: if( header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" - " or SSL buffer too short" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "psk identity or DHM size too long or SSL buffer too short" ) ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } @@ -3530,7 +3761,8 @@ ecdh_calc_secret: ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && ssl_conf_has_static_raw_psk( ssl->conf ) == 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "skip PMS generation for opaque PSK" ) ); } else #endif /* MBEDTLS_USE_PSA_CRYPTO && @@ -3538,7 +3770,8 @@ ecdh_calc_secret: if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, ciphersuite_info->key_exchange ) ) != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, + "mbedtls_ssl_psk_derive_premaster", ret ); return( ret ); } } @@ -3736,8 +3969,9 @@ sign: * Until we encounter a server that does not, we will take this * shortcut. * - * Reason: Otherwise we should have running hashes for SHA512 and SHA224 - * in order to satisfy 'weird' needs from the server side. + * Reason: Otherwise we should have running hashes for SHA512 and + * SHA224 in order to satisfy 'weird' needs from the server + * side. */ if( ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) { @@ -3821,8 +4055,10 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c index 4bf9058af..323784c26 100644 --- a/library/ssl_cookie.c +++ b/library/ssl_cookie.c @@ -134,8 +134,7 @@ static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx, { unsigned char hmac_out[COOKIE_MD_OUTLEN]; - if( (size_t)( end - *p ) < COOKIE_HMAC_LEN ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + MBEDTLS_SSL_CHK_BUF_PTR( *p, end, COOKIE_HMAC_LEN ); if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 || mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 || @@ -165,8 +164,7 @@ int mbedtls_ssl_cookie_write( void *p_ctx, if( ctx == NULL || cli_id == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( (size_t)( end - *p ) < COOKIE_LEN ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + MBEDTLS_SSL_CHK_BUF_PTR( *p, end, COOKIE_LEN ); #if defined(MBEDTLS_HAVE_TIME) t = (unsigned long) mbedtls_time( NULL ); diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c index 8a76b42b6..6b50b55ec 100644 --- a/library/ssl_ticket.c +++ b/library/ssl_ticket.c @@ -35,6 +35,7 @@ #define mbedtls_free free #endif +#include "mbedtls/ssl_internal.h" #include "mbedtls/ssl_ticket.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" @@ -224,8 +225,7 @@ int mbedtls_ssl_ticket_write( void *p_ticket, /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag, * in addition to session itself, that will be checked when writing it. */ - if( end - start < TICKET_MIN_LEN ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + MBEDTLS_SSL_CHK_BUF_PTR( start, end, TICKET_MIN_LEN ); #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 30c917bb1..77d2757ac 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4665,7 +4665,9 @@ int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **prot cur_len = strlen( *p ); tot_len += cur_len; - if( cur_len == 0 || cur_len > 255 || tot_len > 65535 ) + if( ( cur_len == 0 ) || + ( cur_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN ) || + ( tot_len > MBEDTLS_SSL_MAX_ALPN_LIST_LEN ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); }