diff --git a/ChangeLog.d/feature-dtls-srtp.txt b/ChangeLog.d/feature-dtls-srtp.txt new file mode 100644 index 000000000..8b9186bb9 --- /dev/null +++ b/ChangeLog.d/feature-dtls-srtp.txt @@ -0,0 +1,2 @@ +Features +* Add support for DTLS-SRTP as defined in RFC 5764. Contributed by Johan Pascal, improved by Ron Eldor. diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 120c1d32f..fd979db84 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -871,6 +871,10 @@ #endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites" +#endif + /* * Avoid warning from -pedantic. This is a convenient place for this * workaround since this is included by every single file before the diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 48e8855e8..2ac2cc696 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1812,6 +1812,37 @@ */ #define MBEDTLS_SSL_DTLS_HELLO_VERIFY +/** + * \def MBEDTLS_SSL_DTLS_SRTP + * + * Enable support for negotation of DTLS-SRTP (RFC 5764) + * through the use_srtp extension. + * + * \note This feature provides the minimum functionality required + * to negotiate the use of DTLS-SRTP and to allow the derivation of + * the associated SRTP packet protection key material. + * In particular, the SRTP packet protection itself, as well as the + * demultiplexing of RTP and DTLS packets at the datagram layer + * (see Section 5 of RFC 5764), are not handled by this feature. + * Instead, after successful completion of a handshake negotiating + * the use of DTLS-SRTP, the extended key exporter API + * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement + * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 + * (this is implemented in the SSL example programs). + * The resulting key should then be passed to an SRTP stack. + * + * Setting this option enables the runtime API + * mbedtls_ssl_conf_dtls_srtp_protection_profiles() + * through which the supported DTLS-SRTP protection + * profiles can be configured. You must call this API at + * runtime if you wish to negotiate the use of DTLS-SRTP. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment this to enable support for use_srtp extension. + */ +//#define MBEDTLS_SSL_DTLS_SRTP + /** * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index a0912614f..1b4e163f6 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -214,6 +214,9 @@ #define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 #define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 +#define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED 0 +#define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED 1 + /* * Default range for DTLS retransmission timer value, in milliseconds. * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. @@ -393,6 +396,8 @@ #define MBEDTLS_TLS_EXT_SIG_ALG 13 +#define MBEDTLS_TLS_EXT_USE_SRTP 14 + #define MBEDTLS_TLS_EXT_ALPN 16 #define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */ @@ -851,6 +856,41 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + +#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 + * + * 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 +{ + /*! The SRTP profile that was negotiated. */ + mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile; + /*! The length of mki_value. */ + uint16_t mki_len; + /*! The mki_value used, with max size of 256 bytes. */ + unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH]; +} +mbedtls_dtls_srtp_info; + +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * This structure is used for storing current session data. * @@ -1057,6 +1097,13 @@ struct mbedtls_ssl_config const char **alpn_list; /*!< ordered list of protocols */ #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + /*! ordered list of supported srtp profile */ + const mbedtls_ssl_srtp_profile *dtls_srtp_profile_list; + /*! number of supported profiles */ + size_t dtls_srtp_profile_list_len; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Numerical settings (int then char) */ @@ -1137,9 +1184,12 @@ struct mbedtls_ssl_config * record with unexpected CID * should lead to failure. */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + unsigned int dtls_srtp_mki_support : 1; /* support having mki_value + in the use_srtp extension */ +#endif }; - struct mbedtls_ssl_context { const mbedtls_ssl_config *conf; /*!< configuration information */ @@ -1298,6 +1348,13 @@ struct mbedtls_ssl_context const char *alpn_chosen; /*!< negotiated protocol */ #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + /* + * use_srtp extension + */ + mbedtls_dtls_srtp_info dtls_srtp_info; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Information for DTLS hello verify */ @@ -2032,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 @@ -3120,6 +3179,105 @@ int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **prot const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +#if defined(MBEDTLS_DEBUG_C) +static inline const char *mbedtls_ssl_get_srtp_profile_as_string( mbedtls_ssl_srtp_profile profile ) +{ + switch( profile ) + { + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: + return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" ); + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: + return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" ); + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: + return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" ); + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: + return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" ); + default: break; + } + return( "" ); +} +#endif /* MBEDTLS_DEBUG_C */ +/** + * \brief Manage support for mki(master key id) value + * in use_srtp extension. + * MKI is an optional part of SRTP used for key management + * and re-keying. See RFC3711 section 3.1 for details. + * The default value is + * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED. + * + * \param conf The SSL configuration to manage mki support. + * \param support_mki_value Enable or disable mki usage. Values are + * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED + * or #MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED. + */ +void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, + int support_mki_value ); + +/** + * \brief Set the supported DTLS-SRTP protection profiles. + * + * \param conf SSL configuration + * \param profiles Pointer to a List of MBEDTLS_TLS_SRTP_UNSET terminated + * supported protection profiles + * in decreasing preference order. + * The pointer to the list is recorded by the library + * for later reference as required, so the lifetime + * of the table must be at least as long as the lifetime + * of the SSL configuration structure. + * The list must not hold more than + * MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements + * (excluding the terminating MBEDTLS_TLS_SRTP_UNSET). + * + * \return 0 on success + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of + * protection profiles is incorrect. + */ +int mbedtls_ssl_conf_dtls_srtp_protection_profiles + ( mbedtls_ssl_config *conf, + const mbedtls_ssl_srtp_profile *profiles ); + +/** + * \brief Set the mki_value for the current DTLS-SRTP session. + * + * \param ssl SSL context to use. + * \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 + */ +int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, + unsigned char *mki_value, + uint16_t mki_len ); +/** + * \brief Get the negotiated DTLS-SRTP informations: + * Protection profile and MKI value. + * + * \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. + * \param dtls_srtp_info The negotiated DTLS-SRTP informations: + * - Protection profile in use. + * 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 + * #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated + * or peer's Hello packet was not parsed yet. + * - mki size and value( if size is > 0 ). + */ +void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl, + mbedtls_dtls_srtp_info *dtls_srtp_info ); +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /** * \brief Set the maximum supported version sent from the client side * and/or accepted at the server side diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 7b78c7310..1dc9648b0 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -1095,6 +1095,23 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, mbedtls_md_type_t md ); #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value + ( const uint16_t srtp_profile_value ) +{ + switch( srtp_profile_value ) + { + 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: + return srtp_profile_value; + default: break; + } + return( MBEDTLS_TLS_SRTP_UNSET ); +} +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) { diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 083b720be..76be8ab07 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -756,6 +756,126 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) +{ + unsigned char *p = buf; + size_t protection_profiles_index = 0, ext_len = 0; + uint16_t mki_len = 0, profile_value = 0; + + *olen = 0; + + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->conf->dtls_srtp_profile_list == NULL ) || + ( ssl->conf->dtls_srtp_profile_list_len == 0 ) ) + { + return( 0 ); + } + + /* RFC 5764 section 4.1.1 + * uint8 SRTPProtectionProfile[2]; + * + * struct { + * SRTPProtectionProfiles SRTPProtectionProfiles; + * opaque srtp_mki<0..255>; + * } UseSRTPData; + * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; + */ + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) + { + mki_len = ssl->dtls_srtp_info.mki_len; + } + /* Extension length = 2 bytes for profiles length, + * ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ), + * 1 byte for srtp_mki vector length and the mki_len value + */ + ext_len = 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) ); + + /* Check there is room in the buffer for the extension + 4 bytes + * - the extension tag (2 bytes) + * - the extension length (2 bytes) + */ + MBEDTLS_SSL_CHK_BUF_PTR( p, end, ext_len + 4 ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP ) & 0xFF ); + + + *p++ = (unsigned char)( ( ( ext_len & 0xFF00 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ext_len & 0xFF ); + + /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */ + /* micro-optimization: + * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + * which is lower than 127, so the upper byte of the length is always 0 + * For the documentation, the more generic code is left in comments + * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len ) + * >> 8 ) & 0xFF ); + */ + *p++ = 0; + *p++ = (unsigned char)( ( 2 * ssl->conf->dtls_srtp_profile_list_len ) + & 0xFF ); + + for( protection_profiles_index=0; + protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len; + protection_profiles_index++ ) + { + profile_value = mbedtls_ssl_check_srtp_profile_value + ( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ); + if( profile_value != MBEDTLS_TLS_SRTP_UNSET ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x", + profile_value ) ); + *p++ = ( ( profile_value >> 8 ) & 0xFF ); + *p++ = ( profile_value & 0xFF ); + } + else + { + /* + * Note: we shall never arrive here as protection profiles + * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function + */ + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, " + "illegal DTLS-SRTP protection profile %d", + ssl->conf->dtls_srtp_profile_list[protection_profiles_index] + ) ); + return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED ); + } + } + + *p++ = mki_len & 0xFF; + + if( mki_len != 0 ) + { + memcpy( p, ssl->dtls_srtp_info.mki_value, mki_len ); + /* + * Increment p to point to the current position. + */ + p += mki_len; + MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki", ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } + + /* + * total extension length: extension type (2 bytes) + * + extension length (2 bytes) + * + protection profile length (2 bytes) + * + 2 * number of protection profiles + * + srtp_mki vector length(1 byte) + * + mki value + */ + *olen = p - buf; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Generate random bytes for ClientHello */ @@ -1277,6 +1397,16 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret ); + return( ret ); + } + ext_len += olen; +#endif + #if defined(MBEDTLS_SSL_SESSION_TICKETS) if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, end, &olen ) ) != 0 ) @@ -1710,6 +1840,123 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET; + size_t i, mki_len = 0; + uint16_t server_protection_profile_value = 0; + + /* If use_srtp is not configured, just ignore the extension */ + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->conf->dtls_srtp_profile_list == NULL ) || + ( ssl->conf->dtls_srtp_profile_list_len == 0 ) ) + return( 0 ); + + /* RFC 5764 section 4.1.1 + * uint8 SRTPProtectionProfile[2]; + * + * struct { + * SRTPProtectionProfiles SRTPProtectionProfiles; + * opaque srtp_mki<0..255>; + * } UseSRTPData; + + * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; + * + */ + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) + { + mki_len = ssl->dtls_srtp_info.mki_len; + } + + /* + * 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 != ( buf[4] + 5u ) ) ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* + * get the server protection profile + */ + + /* + * protection profile length must be 0x0002 as we must have only + * one protection profile in server Hello + */ + if( ( buf[0] != 0 ) || ( buf[1] != 2 ) ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + server_protection_profile_value = ( buf[2] << 8 ) | buf[3]; + server_protection = mbedtls_ssl_check_srtp_profile_value( + server_protection_profile_value ); + if( server_protection != MBEDTLS_TLS_SRTP_UNSET ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + server_protection ) ) ); + } + + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; + + /* + * Check we have the server profile in our list + */ + for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++) + { + if( server_protection == ssl->conf->dtls_srtp_profile_list[i] ) + { + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + server_protection ) ) ); + break; + } + } + + /* If no match was found : server problem, it shall never answer with incompatible profile */ + if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) + { + 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 ); + } + + /* If server does not use mki in its reply, make sure the client won't keep + * one as negotiated */ + if( len == 5 ) + { + ssl->dtls_srtp_info.mki_len = 0; + } + + /* + * RFC5764: + * If the client detects a nonzero-length MKI in the server's response + * that is different than the one the client offered, then the client + * MUST abort the handshake and SHOULD send an invalid_parameter alert. + */ + if( len > 5 && ( buf[4] != mki_len || + ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) ) ) + { + 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 ); + } +#if defined (MBEDTLS_DEBUG_C) + if( len > 5 ) + { + MBEDTLS_SSL_DEBUG_BUF( 3, "received mki", ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } +#endif + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Parse HelloVerifyRequest. Only called after verifying the HS type. */ @@ -2278,6 +2525,16 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) break; #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + case MBEDTLS_TLS_EXT_USE_SRTP: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) ); + + if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 ) + return( ret ); + + break; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + default: MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", ext_id ) ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 2e63fced3..070a5915f 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -776,6 +776,126 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET; + size_t i,j; + size_t profile_length; + uint16_t mki_length; + /*! 2 bytes for profile length and 1 byte for mki len */ + const size_t size_of_lengths = 3; + + /* If use_srtp is not configured, just ignore the extension */ + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->conf->dtls_srtp_profile_list == NULL ) || + ( ssl->conf->dtls_srtp_profile_list_len == 0 ) ) + { + return( 0 ); + } + + /* RFC5764 section 4.1.1 + * uint8 SRTPProtectionProfile[2]; + * + * struct { + * SRTPProtectionProfiles SRTPProtectionProfiles; + * opaque srtp_mki<0..255>; + * } UseSRTPData; + + * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; + */ + + /* + * 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 < size_of_lengths ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; + + /* first 2 bytes are protection profile length(in bytes) */ + profile_length = ( buf[0] << 8 ) | buf[1]; + buf += 2; + + /* 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, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + /* + * 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 ) + { + 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 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + client_protection ) ) ); + } + else + { + continue; + } + /* check if suggested profile is in our list */ + for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) + { + if( client_protection == ssl->conf->dtls_srtp_profile_list[i] ) + { + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + client_protection ) ) ); + break; + } + } + if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET ) + break; + } + buf += profile_length; /* buf points to the mki length */ + mki_length = *buf; + buf++; + + if( mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH || + mki_length + profile_length + size_of_lengths != len ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Parse the mki only if present and mki is supported locally */ + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED && + mki_length > 0 ) + { + ssl->dtls_srtp_info.mki_len = mki_length; + + 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 ); + } + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Auxiliary functions for ServerHello parsing and related actions */ @@ -1942,6 +2062,16 @@ read_record_header: break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + 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 ); + break; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + default: MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", ext_id ) ); @@ -2500,6 +2630,78 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS) +static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + size_t mki_len = 0, ext_len = 0; + uint16_t profile_value = 0; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + + *olen = 0; + + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) ); + + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) + { + mki_len = ssl->dtls_srtp_info.mki_len; + } + + /* The extension total size is 9 bytes : + * - 2 bytes for the extension tag + * - 2 bytes for the total size + * - 2 bytes for the protection profile length + * - 2 bytes for the protection profile + * - 1 byte for the mki length + * + the actual mki length + * Check we have enough room in the output buffer */ + if( (size_t)( end - buf ) < mki_len + 9 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + /* extension */ + buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF ); + buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP ) & 0xFF ); + /* + * total length 5 and mki value: only one profile(2 bytes) + * and length(2 bytes) and srtp_mki ) + */ + ext_len = 5 + mki_len; + buf[2] = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ext_len & 0xFF ); + + /* protection profile length: 2 */ + buf[4] = 0x00; + buf[5] = 0x02; + profile_value = mbedtls_ssl_check_srtp_profile_value( + ssl->dtls_srtp_info.chosen_dtls_srtp_profile ); + if( profile_value != MBEDTLS_TLS_SRTP_UNSET ) + { + buf[6] = (unsigned char)( ( profile_value >> 8 ) & 0xFF ); + buf[7] = (unsigned char)( profile_value & 0xFF ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "use_srtp extension invalid profile" ) ); + return; + } + + buf[8] = mki_len & 0xFF; + memcpy( &buf[9], ssl->dtls_srtp_info.mki_value, mki_len ); + + *olen = 9 + mki_len; +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) { @@ -2788,6 +2990,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + 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 ) ); if( ext_len > 0 ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 34953f269..7cb5b8ccf 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3859,6 +3859,10 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, mbedtls_ssl_reset_in_out_pointers( ssl ); +#if defined(MBEDTLS_SSL_DTLS_SRTP) + memset( &ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info) ); +#endif + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) goto error; @@ -4685,6 +4689,86 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, + int support_mki_value ) +{ + conf->dtls_srtp_mki_support = support_mki_value; +} + +int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, + unsigned char *mki_value, + uint16_t mki_len ) +{ + if( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED ) + { + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len ); + ssl->dtls_srtp_info.mki_len = mki_len; + return( 0 ); +} + +int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, + const mbedtls_ssl_srtp_profile *profiles ) +{ + const mbedtls_ssl_srtp_profile *p; + size_t list_size = 0; + + /* check the profiles list: all entry must be valid, + * its size cannot be more than the total number of supported profiles, currently 4 */ + for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET && + list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH; + p++ ) + { + if( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET ) + { + 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; + } + } + + if( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH ) + { + conf->dtls_srtp_profile_list = NULL; + conf->dtls_srtp_profile_list_len = 0; + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + conf->dtls_srtp_profile_list = profiles; + conf->dtls_srtp_profile_list_len = list_size; + + return( 0 ); +} + +void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl, + mbedtls_dtls_srtp_info *dtls_srtp_info ) +{ + dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile; + /* do not copy the mki value if there is no chosen profile */ + if( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) + { + dtls_srtp_info->mki_len = 0; + } + else + { + dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len; + memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) { conf->max_major_ver = major; diff --git a/library/version_features.c b/library/version_features.c index 62b05537c..42ccaf954 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -534,6 +534,9 @@ static const char * const features[] = { #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) "MBEDTLS_SSL_DTLS_HELLO_VERIFY", #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + "MBEDTLS_SSL_DTLS_SRTP", +#endif /* MBEDTLS_SSL_DTLS_SRTP */ #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index b9047df1d..54cdd7d32 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -150,6 +150,9 @@ int main( void ) #define DFL_NSS_KEYLOG_FILE NULL #define DFL_SKIP_CLOSE_NOTIFY 0 #define DFL_QUERY_CONFIG_MODE 0 +#define DFL_USE_SRTP 0 +#define DFL_SRTP_FORCE_PROFILE 0 +#define DFL_SRTP_MKI "" #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: " #define GET_REQUEST_END "\r\n\r\n" @@ -254,10 +257,26 @@ int main( void ) " This cannot be used with eap_tls=1\n" #define USAGE_NSS_KEYLOG_FILE \ " nss_keylog_file=%%s\n" -#else +#if defined(MBEDTLS_SSL_DTLS_SRTP) +#define USAGE_SRTP \ + " use_srtp=%%d default: 0 (disabled)\n" \ + " This cannot be used with eap_tls=1 or "\ + " nss_keylog=1\n" \ + " srtp_force_profile=%%d default: 0 (all enabled)\n" \ + " available profiles:\n" \ + " 1 - SRTP_AES128_CM_HMAC_SHA1_80\n" \ + " 2 - SRTP_AES128_CM_HMAC_SHA1_32\n" \ + " 3 - SRTP_NULL_HMAC_SHA1_80\n" \ + " 4 - SRTP_NULL_HMAC_SHA1_32\n" \ + " mki=%%s default: \"\" (in hex, without 0x)\n" +#else /* MBEDTLS_SSL_DTLS_SRTP */ +#define USAGE_SRTP "" +#endif +#else /* MBEDTLS_SSL_EXPORT_KEYS */ #define USAGE_EAP_TLS "" #define USAGE_NSS_KEYLOG "" #define USAGE_NSS_KEYLOG_FILE "" +#define USAGE_SRTP "" #endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) @@ -407,6 +426,7 @@ int main( void ) "\n" \ USAGE_DTLS \ USAGE_CID \ + USAGE_SRTP \ "\n" #define USAGE2 \ " auth_mode=%%s default: (library default: none)\n" \ @@ -541,6 +561,9 @@ struct options int reproducible; /* make communication reproducible */ int skip_close_notify; /* skip sending the close_notify alert */ int query_config_mode; /* whether to read config */ + int use_srtp; /* Support SRTP */ + int force_srtp_profile; /* SRTP protection profile to use or all */ + const char *mki; /* The dtls mki value to use */ } opt; int query_config( const char *config ); @@ -655,7 +678,49 @@ exit: sizeof( nss_keylog_line ) ); return( ret ); } -#endif + +#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]; + unsigned char randbytes[64]; + mbedtls_tls_prf_types tls_prf_type; +} dtls_srtp_keys; + +static int dtls_srtp_key_derivation( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) +{ + dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; + + ( ( void ) kb ); + memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); + memcpy( keys->randbytes, client_random, 32 ); + memcpy( keys->randbytes + 32, server_random, 32 ); + keys->tls_prf_type = tls_prf_type; + + if( opt.debug_level > 2 ) + { + mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen ); + mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen ); + mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen ); + } + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ static void my_debug( void *ctx, int level, const char *file, int line, @@ -1134,6 +1199,10 @@ int main( int argc, char *argv[] ) mbedtls_ecp_group_id curve_list[CURVE_LIST_SIZE]; const mbedtls_ecp_curve_info *curve_cur; #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + unsigned char mki[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH]; + size_t mki_len=0; +#endif const char *pers = "ssl_client2"; @@ -1177,7 +1246,20 @@ int main( int argc, char *argv[] ) unsigned char eap_tls_iv[8]; const char* eap_tls_label = "client EAP encryption"; eap_tls_keys eap_tls_keying; -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + /*! master keys and master salt for SRTP generated during handshake */ + unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH]; + const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp"; + dtls_srtp_keys dtls_srtp_keying; + const mbedtls_ssl_srtp_profile default_profiles[] = { + 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 + }; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); @@ -1304,6 +1386,9 @@ int main( int argc, char *argv[] ) opt.nss_keylog_file = DFL_NSS_KEYLOG_FILE; opt.skip_close_notify = DFL_SKIP_CLOSE_NOTIFY; opt.query_config_mode = DFL_QUERY_CONFIG_MODE; + opt.use_srtp = DFL_USE_SRTP; + opt.force_srtp_profile = DFL_SRTP_FORCE_PROFILE; + opt.mki = DFL_SRTP_MKI; for( i = 1; i < argc; i++ ) { @@ -1730,6 +1815,18 @@ int main( int argc, char *argv[] ) if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 ) goto usage; } + else if( strcmp( p, "use_srtp" ) == 0 ) + { + opt.use_srtp = atoi ( q ); + } + else if( strcmp( p, "srtp_force_profile" ) == 0 ) + { + opt.force_srtp_profile = atoi( q ); + } + else if( strcmp( p, "mki" ) == 0 ) + { + opt.mki = q; + } else goto usage; } @@ -1837,7 +1934,6 @@ int main( int argc, char *argv[] ) opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED; } - #if defined(MBEDTLS_USE_PSA_CRYPTO) if( opt.psk_opaque != 0 ) { @@ -2240,6 +2336,36 @@ int main( int argc, char *argv[] ) } #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + if( opt.use_srtp == 1 ) + { + if( opt.force_srtp_profile != 0 ) + { + const mbedtls_ssl_srtp_profile forced_profile[] = + { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET }; + ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, forced_profile ); + } + else + { + ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, default_profiles ); + } + + if( ret != 0 ) + { + mbedtls_printf( " failed\n ! " + "mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n", + ret ); + goto exit; + } + + } + else if( opt.force_srtp_profile != 0 ) + { + mbedtls_printf( " failed\n ! must enable use_srtp to force srtp profile\n\n" ); + goto exit; + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) if( opt.trunc_hmac != DFL_TRUNC_HMAC ) mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac ); @@ -2267,7 +2393,14 @@ int main( int argc, char *argv[] ) nss_keylog_export, NULL ); } -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation, + &dtls_srtp_keying ); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) if( opt.recsplit != DFL_RECSPLIT ) @@ -2476,6 +2609,26 @@ int main( int argc, char *argv[] ) mbedtls_ecp_set_max_ops( opt.ec_max_ops ); #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + if( opt.use_srtp != 0 && strlen( opt.mki ) != 0 ) + { + if( mbedtls_test_unhexify( mki, sizeof( mki ), + opt.mki,&mki_len ) != 0 ) + { + mbedtls_printf( "mki value not valid hex\n" ); + goto exit; + } + + mbedtls_ssl_conf_srtp_mki_value_supported( &conf, MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ); + if( ( ret = mbedtls_ssl_dtls_srtp_set_mki_value( &ssl, mki, + (uint16_t) strlen( opt.mki ) / 2 ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret ); + goto exit; + } + } +#endif + mbedtls_printf( " ok\n" ); /* @@ -2597,7 +2750,74 @@ int main( int argc, char *argv[] ) } mbedtls_printf("\n"); } -#endif + +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + size_t j = 0; + mbedtls_dtls_srtp_info dtls_srtp_negotiation_result; + mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result ); + + if( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile + == MBEDTLS_TLS_SRTP_UNSET ) + { + mbedtls_printf( " Unable to negotiate " + "the use of DTLS-SRTP\n" ); + } + else + { + if( ( ret = mbedtls_ssl_tls_prf( dtls_srtp_keying.tls_prf_type, + dtls_srtp_keying.master_secret, + sizeof( dtls_srtp_keying.master_secret ), + dtls_srtp_label, + dtls_srtp_keying.randbytes, + sizeof( dtls_srtp_keying.randbytes ), + dtls_srtp_key_material, + sizeof( dtls_srtp_key_material ) ) ) + != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n", + (unsigned int) -ret ); + goto exit; + } + + mbedtls_printf( " DTLS-SRTP key material is:" ); + for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf( "\n " ); + mbedtls_printf( "%02x ", dtls_srtp_key_material[j] ); + } + mbedtls_printf( "\n" ); + + /* produce a less readable output used to perform automatic checks + * - compare client and server output + * - interop test with openssl which client produces this kind of output + */ + mbedtls_printf( " Keying material: " ); + for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ ) + { + mbedtls_printf( "%02X", dtls_srtp_key_material[j] ); + } + mbedtls_printf( "\n" ); + + if ( dtls_srtp_negotiation_result.mki_len > 0 ) + { + mbedtls_printf( " DTLS-SRTP mki value: " ); + for( j = 0; j < dtls_srtp_negotiation_result.mki_len; j++ ) + { + mbedtls_printf( "%02X", dtls_srtp_negotiation_result.mki_value[j] ); + } + } + else + { + mbedtls_printf( " DTLS-SRTP no mki value negotiated" ); + } + mbedtls_printf( "\n" ); + } + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ if( opt.reconnect != 0 ) { mbedtls_printf(" . Saving session for reuse..." ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index a98aec119..ec3d6ade5 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -183,6 +183,9 @@ int main( void ) #define DFL_NSS_KEYLOG 0 #define DFL_NSS_KEYLOG_FILE NULL #define DFL_QUERY_CONFIG_MODE 0 +#define DFL_USE_SRTP 0 +#define DFL_SRTP_FORCE_PROFILE 0 +#define DFL_SRTP_SUPPORT_MKI 0 #define LONG_RESPONSE "
01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \ "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \ @@ -325,10 +328,24 @@ int main( void ) " This cannot be used with eap_tls=1\n" #define USAGE_NSS_KEYLOG_FILE \ " nss_keylog_file=%%s\n" -#else +#if defined(MBEDTLS_SSL_DTLS_SRTP) +#define USAGE_SRTP \ + " use_srtp=%%d default: 0 (disabled)\n" \ + " srtp_force_profile=%%d default: 0 (all enabled)\n" \ + " available profiles:\n" \ + " 1 - SRTP_AES128_CM_HMAC_SHA1_80\n" \ + " 2 - SRTP_AES128_CM_HMAC_SHA1_32\n" \ + " 3 - SRTP_NULL_HMAC_SHA1_80\n" \ + " 4 - SRTP_NULL_HMAC_SHA1_32\n" \ + " support_mki=%%d default: 0 (not supported)\n" +#else /* MBEDTLS_SSL_DTLS_SRTP */ +#define USAGE_SRTP "" +#endif +#else /* MBEDTLS_SSL_EXPORT_KEYS */ #define USAGE_EAP_TLS "" #define USAGE_NSS_KEYLOG "" #define USAGE_NSS_KEYLOG_FILE "" +#define USAGE_SRTP "" #endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_CACHE_C) @@ -490,6 +507,7 @@ int main( void ) " read_timeout=%%d default: 0 ms (no timeout)\n" \ "\n" \ USAGE_DTLS \ + USAGE_SRTP \ USAGE_COOKIES \ USAGE_ANTI_REPLAY \ USAGE_BADMAC_LIMIT \ @@ -645,6 +663,9 @@ struct options * after renegotiation */ int reproducible; /* make communication reproducible */ int query_config_mode; /* whether to read config */ + int use_srtp; /* Support SRTP */ + int force_srtp_profile; /* SRTP protection profile to use or all */ + int support_mki; /* The dtls mki mki support */ } opt; int query_config( const char *config ); @@ -760,7 +781,49 @@ exit: return( ret ); } -#endif +#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]; + unsigned char randbytes[64]; + mbedtls_tls_prf_types tls_prf_type; +} dtls_srtp_keys; + +static int dtls_srtp_key_derivation( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) +{ + dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; + + ( ( void ) kb ); + memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); + memcpy( keys->randbytes, client_random, 32 ); + memcpy( keys->randbytes + 32, server_random, 32 ); + keys->tls_prf_type = tls_prf_type; + + if( opt.debug_level > 2 ) + { + mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen ); + mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen ); + mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen ); + } + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ static void my_debug( void *ctx, int level, const char *file, int line, @@ -1792,7 +1855,6 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) unsigned char alloc_buf[MEMORY_HEAP_SIZE]; #endif - #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) unsigned char cid[MBEDTLS_SSL_CID_IN_LEN_MAX]; unsigned char cid_renego[MBEDTLS_SSL_CID_IN_LEN_MAX]; @@ -1815,7 +1877,20 @@ int main( int argc, char *argv[] ) unsigned char eap_tls_iv[8]; const char* eap_tls_label = "client EAP encryption"; eap_tls_keys eap_tls_keying; -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + /*! master keys and master salt for SRTP generated during handshake */ + unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH]; + const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp"; + dtls_srtp_keys dtls_srtp_keying; + const mbedtls_ssl_srtp_profile default_profiles[] = { + 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 + }; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); @@ -1976,6 +2051,9 @@ int main( int argc, char *argv[] ) opt.nss_keylog = DFL_NSS_KEYLOG; opt.nss_keylog_file = DFL_NSS_KEYLOG_FILE; opt.query_config_mode = DFL_QUERY_CONFIG_MODE; + opt.use_srtp = DFL_USE_SRTP; + opt.force_srtp_profile = DFL_SRTP_FORCE_PROFILE; + opt.support_mki = DFL_SRTP_SUPPORT_MKI; for( i = 1; i < argc; i++ ) { @@ -2424,6 +2502,18 @@ int main( int argc, char *argv[] ) { opt.nss_keylog_file = q; } + else if( strcmp( p, "use_srtp" ) == 0 ) + { + opt.use_srtp = atoi ( q ); + } + else if( strcmp( p, "srtp_force_profile" ) == 0 ) + { + opt.force_srtp_profile = atoi( q ); + } + else if( strcmp( p, "support_mki" ) == 0 ) + { + opt.support_mki = atoi( q ); + } else goto usage; } @@ -3028,7 +3118,7 @@ int main( int argc, char *argv[] ) { mbedtls_printf( " failed\n ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret ); goto exit; - }; + } #endif #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) @@ -3058,6 +3148,38 @@ int main( int argc, char *argv[] ) } #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + if( opt.use_srtp == 1 ) + { + if( opt.force_srtp_profile != 0 ) + { + const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET }; + ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile ); + } + else + { + ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, default_profiles ); + } + + if( ret != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n", ret ); + goto exit; + } + + mbedtls_ssl_conf_srtp_mki_value_supported( &conf, + opt.support_mki ? + MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED : + MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED ); + + } + else if( opt.force_srtp_profile != 0 ) + { + mbedtls_printf( " failed\n ! must enable use_srtp to force srtp profile\n\n" ); + goto exit; + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) if( opt.trunc_hmac != DFL_TRUNC_HMAC ) mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac ); @@ -3085,7 +3207,14 @@ int main( int argc, char *argv[] ) nss_keylog_export, NULL ); } -#endif +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation, + &dtls_srtp_keying ); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) @@ -3731,7 +3860,75 @@ handshake: } mbedtls_printf("\n"); } -#endif + +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + size_t j = 0; + mbedtls_dtls_srtp_info dtls_srtp_negotiation_result; + mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result ); + + if( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile + == MBEDTLS_TLS_SRTP_UNSET ) + { + mbedtls_printf( " Unable to negotiate " + "the use of DTLS-SRTP\n" ); + } + else + { + if( ( ret = mbedtls_ssl_tls_prf( dtls_srtp_keying.tls_prf_type, + dtls_srtp_keying.master_secret, + sizeof( dtls_srtp_keying.master_secret ), + dtls_srtp_label, + dtls_srtp_keying.randbytes, + sizeof( dtls_srtp_keying.randbytes ), + dtls_srtp_key_material, + sizeof( dtls_srtp_key_material ) ) ) + != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n", + (unsigned int) -ret ); + goto exit; + } + + mbedtls_printf( " DTLS-SRTP key material is:" ); + for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ ) + { + if( j % 8 == 0 ) + mbedtls_printf( "\n " ); + mbedtls_printf( "%02x ", dtls_srtp_key_material[j] ); + } + mbedtls_printf( "\n" ); + + /* produce a less readable output used to perform automatic checks + * - compare client and server output + * - interop test with openssl which client produces this kind of output + */ + mbedtls_printf( " Keying material: " ); + for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ ) + { + mbedtls_printf( "%02X", dtls_srtp_key_material[j] ); + } + mbedtls_printf( "\n" ); + + if ( dtls_srtp_negotiation_result.mki_len > 0 ) + { + mbedtls_printf( " DTLS-SRTP mki value: " ); + for( j = 0; j < dtls_srtp_negotiation_result.mki_len; j++ ) + { + mbedtls_printf( "%02X", dtls_srtp_negotiation_result.mki_value[j] ); + } + } + else + { + mbedtls_printf( " DTLS-SRTP no mki value negotiated" ); + } + mbedtls_printf( "\n" ); + + } + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) ret = report_cid_usage( &ssl, "initial handshake" ); diff --git a/programs/test/query_config.c b/programs/test/query_config.c index c35502fa4..1345b11fe 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -1480,6 +1480,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + if( strcmp( "MBEDTLS_SSL_DTLS_SRTP", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_DTLS_SRTP ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) if( strcmp( "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", config ) == 0 ) { diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 653d88da7..59e79744f 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -634,6 +634,23 @@ detect_dtls() { fi } +# Compare file content +# Usage: find_in_both pattern file1 file2 +# extract from file1 the first line matching the pattern +# check in file2 that the same line can be found +find_in_both() { + srv_pattern=$(grep -m 1 "$1" "$2"); + if [ -z "$srv_pattern" ]; then + return 1; + fi + + if grep "$srv_pattern" $3 >/dev/null; then : + return 0; + else + return 1; + fi +} + # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]] # Options: -s pattern pattern that must be present in server output # -c pattern pattern that must be present in client output @@ -643,6 +660,7 @@ detect_dtls() { # -C pattern pattern that must be absent in client output # -U pattern lines after pattern must be unique in server output # -F call shell function on server output +# -g call shell function on server and client output run_test() { NAME="$1" shift 1 @@ -865,6 +883,12 @@ run_test() { return fi ;; + "-g") + if ! eval "$2 '$SRV_OUT' '$CLI_OUT'"; then + fail "function call to '$2' failed on Server and Client output" + return + fi + ;; *) echo "Unknown test: $1" >&2 @@ -8713,6 +8737,539 @@ run_test "DTLS fragmenting: 3d, openssl client, DTLS 1.0" \ 0 \ -s "fragmenting handshake message" +# Tests for DTLS-SRTP (RFC 5764) +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP all profiles supported" \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -C "error" + + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports all profiles. Client supports one profile." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=5 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \ + -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports one profile. Client supports all profiles." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server and Client support only one matching profile." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -s "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server and Client support only one different profile." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \ + -S "selected srtp profile" \ + -S "server hello, adding use_srtp extension" \ + -S "DTLS-SRTP key material is"\ + -c "client hello, adding use_srtp extension" \ + -C "found use_srtp extension" \ + -C "found srtp profile" \ + -C "selected srtp profile" \ + -C "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server doesn't support use_srtp extension." \ + "$P_SRV dtls=1 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -S "server hello, adding use_srtp extension" \ + -S "DTLS-SRTP key material is"\ + -c "client hello, adding use_srtp extension" \ + -C "found use_srtp extension" \ + -C "found srtp profile" \ + -C "selected srtp profile" \ + -C "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP all profiles supported. mki used" \ + "$P_SRV dtls=1 use_srtp=1 support_mki=1 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "dumping 'using mki' (8 bytes)" \ + -s "DTLS-SRTP key material is"\ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile" \ + -c "dumping 'sending mki' (8 bytes)" \ + -c "dumping 'received mki' (8 bytes)" \ + -c "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -g "find_in_both '^ *DTLS-SRTP mki value: [0-9A-F]*$'"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP all profiles supported. server doesn't support mki." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -s "DTLS-SRTP no mki value negotiated"\ + -S "dumping 'using mki' (8 bytes)" \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -c "DTLS-SRTP no mki value negotiated"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -c "dumping 'sending mki' (8 bytes)" \ + -C "dumping 'received mki' (8 bytes)" \ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP all profiles supported. openssl client." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_80" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl client." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports all profiles. Client supports one profile. openssl client." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports one profile. Client supports all profiles. openssl client." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server and Client support only one matching profile. openssl client." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\ + -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server and Client support only one different profile. openssl client." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \ + "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -S "selected srtp profile" \ + -S "server hello, adding use_srtp extension" \ + -S "DTLS-SRTP key material is"\ + -C "SRTP Extension negotiated, profile" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server doesn't support use_srtp extension. openssl client" \ + "$P_SRV dtls=1 debug_level=3" \ + "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + 0 \ + -s "found use_srtp extension" \ + -S "server hello, adding use_srtp extension" \ + -S "DTLS-SRTP key material is"\ + -C "SRTP Extension negotiated, profile" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP all profiles supported. openssl server" \ + "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl server." \ + "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports all profiles. Client supports one profile. openssl server." \ + "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server supports one profile. Client supports all profiles. openssl server." \ + "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server and Client support only one matching profile. openssl server." \ + "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server and Client support only one different profile. openssl server." \ + "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -C "found use_srtp extension" \ + -C "found srtp profile" \ + -C "selected srtp profile" \ + -C "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP server doesn't support use_srtp extension. openssl server" \ + "$O_SRV -dtls1" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -C "found use_srtp extension" \ + -C "found srtp profile" \ + -C "selected srtp profile" \ + -C "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +run_test "DTLS-SRTP all profiles supported. server doesn't support mki. openssl server." \ + "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \ + "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -c "DTLS-SRTP no mki value negotiated"\ + -c "dumping 'sending mki' (8 bytes)" \ + -C "dumping 'received mki' (8 bytes)" \ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP all profiles supported. gnutls client." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_80" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls client." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$G_CLI -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "SRTP profile: SRTP_NULL_HMAC_SHA1_80" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls client." \ + "$P_SRV dtls=1 use_srtp=1 debug_level=3" \ + "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -s "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls client." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \ + "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "SRTP profile: SRTP_NULL_SHA1_32" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server and Client support only one matching profile. gnutls client." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -s "selected srtp profile" \ + -s "server hello, adding use_srtp extension" \ + -s "DTLS-SRTP key material is"\ + -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server and Client support only one different profile. gnutls client." \ + "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \ + "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \ + 0 \ + -s "found use_srtp extension" \ + -s "found srtp profile" \ + -S "selected srtp profile" \ + -S "server hello, adding use_srtp extension" \ + -S "DTLS-SRTP key material is"\ + -C "SRTP profile:" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server doesn't support use_srtp extension. gnutls client" \ + "$P_SRV dtls=1 debug_level=3" \ + "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \ + 0 \ + -s "found use_srtp extension" \ + -S "server hello, adding use_srtp extension" \ + -S "DTLS-SRTP key material is"\ + -C "SRTP profile:" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP all profiles supported. gnutls server" \ + "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls server." \ + "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls server." \ + "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls server." \ + "$G_SRV -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server and Client support only one matching profile. gnutls server." \ + "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server and Client support only one different profile. gnutls server." \ + "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \ + "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -C "found use_srtp extension" \ + -C "found srtp profile" \ + -C "selected srtp profile" \ + -C "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP server doesn't support use_srtp extension. gnutls server" \ + "$G_SRV -u" \ + "$P_CLI dtls=1 use_srtp=1 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -C "found use_srtp extension" \ + -C "found srtp profile" \ + -C "selected srtp profile" \ + -C "DTLS-SRTP key material is"\ + -C "error" + +requires_config_enabled MBEDTLS_SSL_DTLS_SRTP +requires_gnutls +run_test "DTLS-SRTP all profiles supported. mki used. gnutls server." \ + "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \ + "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \ + 0 \ + -c "client hello, adding use_srtp extension" \ + -c "found use_srtp extension" \ + -c "found srtp profile" \ + -c "selected srtp profile" \ + -c "DTLS-SRTP key material is"\ + -c "DTLS-SRTP mki value:"\ + -c "dumping 'sending mki' (8 bytes)" \ + -c "dumping 'received mki' (8 bytes)" \ + -C "error" + # Tests for specific things with "unreliable" UDP connection not_with_valgrind # spurious resend due to timeout