diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 529c07f1f..6e841c7e6 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1350,6 +1350,19 @@ */ #define MBEDTLS_SSL_ALL_ALERT_MESSAGES +/** + * \def MBEDTLS_SSL_RECORD_CHECKING + * + * Enable the API mbedtls_ssl_check_record() which allows to check the + * validity, freshness and authenticity of an incoming record without + * modifying the externally visible state of the SSL context. + * + * See mbedtls_ssl_check_record() for more information. + * + * Uncomment to enable support for record checking. + */ +#define MBEDTLS_SSL_RECORD_CHECKING + /** * \def MBEDTLS_SSL_DTLS_CONNECTION_ID * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 5f9862b20..ba8d28e5b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1756,6 +1756,54 @@ void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, */ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); +#if defined(MBEDTLS_SSL_RECORD_CHECKING) +/** + * \brief Check whether a buffer contains a valid, fresh + * and authentic application data record (DTLS only). + * + * This function does not change the user-visible state + * of the SSL context. It's sole purpose is to provide + * an indication of the legitimacy of an incoming record. + * + * This can be useful e.g. in distributed server environments + * using the DTLS Connection ID feature, in which connections + * might need to be passed between service instances on a change + * of peer address, but where such disruptive operations should + * only happen after the validity of incoming records has been + * confirmed. + * + * \param ssl The SSL context to use. + * \param buf The address of the buffer holding the record to be checked. + * This must be an R/W buffer of length \p buflen Bytes. + * \param buflen The length of \p buf in Bytes. + * + * \note This routine only checks whether the provided buffer begins + * with a valid, fresh and authentic record, but does not check + * potential data following the initial record. In particular, + * it is possible to pass DTLS datagrams containing records, + * in which case only the first record is checked. + * + * \note This function modifies the input buffer \p buf. If you need + * to preserve the original record, you have to maintain a copy. + * + * \return \c 0 if the record is valid, fresh (DTLS only) and authentic. + * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed + * successfully but the record was found to be not authentic. + * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed + * successfully but the record was found to be invalid for + * a reason different from authenticity checking. + * \return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD if the check completed + * successfully but the record was found to be unexpected + * in the state of the SSL context, including replayed records. + * \return Another negative error code on different kinds of failure. + * In this case, the SSL context becomes unusable and needs + * to be freed or reset before reuse. + */ +int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, + unsigned char *buf, + size_t buflen ); +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + /** * \brief Set the timer callbacks (Mandatory for DTLS.) * diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 68a1e592e..0386ea0e8 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -112,6 +112,18 @@ static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, mbedtls_ssl_transform *transform ); static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ); +#if defined(MBEDTLS_SSL_RECORD_CHECKING) +int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, + unsigned char *buf, + size_t buflen ) +{ + ((void) ssl); + ((void) buf); + ((void) buflen); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +} +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + #define SSL_DONT_FORCE_FLUSH 0 #define SSL_FORCE_FLUSH 1 diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index 98a5df230..c6d19bf09 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -1242,6 +1242,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ +#if defined(MBEDTLS_SSL_RECORD_CHECKING) + if( strcmp( "MBEDTLS_SSL_RECORD_CHECKING", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_RECORD_CHECKING ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) if( strcmp( "MBEDTLS_SSL_DTLS_CONNECTION_ID", config ) == 0 ) {