diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 840722dede..84082f3af5 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -414,19 +414,6 @@ #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 -#if defined(MBEDTLS_SSL_DTLS_SRTP) -/* - * Use_srtp extension protection profiles values as defined in - * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml - */ -#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 0x0001 -#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 0x0002 -#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 0x0005 -#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 0x0006 -/* This one is not iana defined, but for code readability. */ -#define MBEDTLS_TLS_SRTP_UNSET 0x0000 -#endif /* MBEDTLS_SSL_DTLS_SRTP*/ - /* * Size defines */ @@ -871,18 +858,24 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); #if defined(MBEDTLS_SSL_DTLS_SRTP) -#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60 #define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH 255 #define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 4 /* * For code readability use a typedef for DTLS-SRTP profiles - * The supported profiles are defines as macro above: - * MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 - * MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 - * MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 - * MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 - * MBEDTLS_TLS_SRTP_UNSET + * + * Use_srtp extension protection profiles values as defined in + * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml + * + * Reminder: if this list is expanded mbedtls_ssl_check_srtp_profile_value + * must be updated too. */ +#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 ( (uint16_t) 0x0001) +#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 ( (uint16_t) 0x0002) +#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 ( (uint16_t) 0x0005) +#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 ( (uint16_t) 0x0006) +/* This one is not iana defined, but for code readability. */ +#define MBEDTLS_TLS_SRTP_UNSET ( (uint16_t) 0x0000) + typedef uint16_t mbedtls_ssl_srtp_profile; typedef struct mbedtls_dtls_srtp_info_t @@ -2096,6 +2089,8 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, * (Default: none.) * * \note See \c mbedtls_ssl_export_keys_ext_t. + * \warning Exported key material must not be used for any purpose + * before the (D)TLS handshake is completed * * \param conf SSL configuration context * \param f_export_keys_ext Callback for exporting keys @@ -3249,6 +3244,11 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles * \param mki_value The MKI value to set. * \param mki_len The length of the MKI value. * + * \note This function is relevant on client side only. + * The server discovers the mki value during handshake. + * A mki value set on server side using this function + * is ignored. + * * \return 0 on success * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE @@ -3258,12 +3258,17 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, uint16_t mki_len ); /** * \brief Get the negotiated DTLS-SRTP Protection Profile. - * This function should be called after the handshake is - * completed. + * + * \warning This function must be called after the handshake is + * completed. The value returned by this function must + * not be trusted or acted upon before the handshake completes. * * \param ssl The SSL context to query. * - * \return The DTLS SRTP protection profile in use. + * \return The DTLS SRTP protection profile in use. The return type is + * a direct mapping of the iana defined value for protection + * profile on an uint16_t. + * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml * \return #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated * or peer's Hello packet was not parsed yet. */ diff --git a/library/ssl_cli.c b/library/ssl_cli.c index c864cb2c6a..234098a7fb 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -837,13 +837,14 @@ static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl, { /* * Note: we shall never arrive here as protection profiles - * is checked by ssl_set_dtls_srtp_protection_profiles function + * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function */ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, " - "ignore illegal DTLS-SRTP protection profile %d", + "illegal DTLS-SRTP protection profile %d", ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ) ); + return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED ); } } @@ -1872,11 +1873,12 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, } /* - * Length is 5 and optional mki_value : one protection profile(2 bytes) - * + length(2 bytes) + mki_len(1 byte) + * Length is 5 + optional mki_value : one protection profile length (2 bytes) + * + protection profile (2 bytes) + * + mki_len(1 byte) * and optional srtp_mki */ - if( ( len != 5 ) && ( len != ( 5 + mki_len ) ) ) + if( len != ( buf[4] + 5u ) ) return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); /* @@ -2509,8 +2511,11 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) case MBEDTLS_TLS_EXT_ALPN: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); - if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) - return( ret ); + if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) + return( ret ); + } break; #endif /* MBEDTLS_SSL_ALPN */ diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 5c56a70d91..007d9e41af 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -810,8 +810,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, * Min length is 5: at least one protection profile(2 bytes) * and length(2 bytes) + srtp_mki length(1 byte) * Check here that we have at least 2 bytes of protection profiles length + * and one of srtp_mki length */ - if( len < 2 ) + if( len < size_of_lengths ) { mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); @@ -824,8 +825,8 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, profile_length = ( buf[0] << 8 ) | buf[1]; buf += 2; - /* check the buffer size: at least profiles + profile and mki length */ - if( profile_length + size_of_lengths > len || + /* The profile length cannot be bigger than input buffer size - lengths fields */ + if( profile_length > len - size_of_lengths || profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */ { mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, @@ -836,9 +837,9 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, * parse the extension list values are defined in * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */ - for( j=0; j < profile_length; j += 2 ) + for( j = 0; j < profile_length; j += 2 ) { - uint16_t protection_profile_value = buf[j] << 8 | buf[j+1]; + uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1]; client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value ); if( client_protection != MBEDTLS_TLS_SRTP_UNSET ) @@ -884,10 +885,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, { ssl->dtls_srtp_info.mki_len = mki_length; - for( i=0; i < mki_length; i++ ) - { - ssl->dtls_srtp_info.mki_value[i] = buf[i]; - } + memcpy(ssl->dtls_srtp_info.mki_value, buf, mki_length); MBEDTLS_SSL_DEBUG_BUF( 3, "using mki", ssl->dtls_srtp_info.mki_value, ssl->dtls_srtp_info.mki_len ); @@ -2067,9 +2065,12 @@ read_record_header: case MBEDTLS_TLS_EXT_USE_SRTP: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) ); - ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ); - if ( ret != 0 ) - return( ret ); + if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ); + if ( ret != 0 ) + return( ret ); + } break; #endif /* MBEDTLS_SSL_DTLS_SRTP */ @@ -2991,8 +2992,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #endif #if defined(MBEDTLS_SSL_DTLS_SRTP) - ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; + if ( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + } #endif MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 58fcab3dd5..a9e5523f68 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4727,16 +4727,14 @@ int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH; p++ ) { - switch( *p ) + if ( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET ) { - case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: - case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: - case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: - case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: - list_size++; - break; - default: /* unsupported value, stop parsing and set the size to an error value */ - list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1; + list_size++; + } + else + { + /* unsupported value, stop parsing and set the size to an error value */ + list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1; } } diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 759603a8fa..c70346a743 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -680,6 +680,12 @@ exit: } #if defined( MBEDTLS_SSL_DTLS_SRTP ) +/* Supported SRTP mode needs a maximum of : + * - 16 bytes for key (AES-128) + * - 14 bytes SALT + * One for sender, one for receiver context + */ +#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60 typedef struct dtls_srtp_keys { unsigned char master_secret[48]; diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 9cef27523e..97929cd65e 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -782,6 +782,12 @@ exit: } #if defined( MBEDTLS_SSL_DTLS_SRTP ) +/* Supported SRTP mode needs a maximum of : + * - 16 bytes for key (AES-128) + * - 14 bytes SALT + * One for sender, one for receiver context + */ +#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60 typedef struct dtls_srtp_keys { unsigned char master_secret[48];