diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index f8a99f2e5..243678c62 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1293,6 +1293,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 9e5fb2dbb..d5378df57 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1898,6 +1898,54 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); #endif /* !MBEDTLS_SSL_CONF_READ_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 */ + #if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \ !defined(MBEDTLS_SSL_CONF_GET_TIMER) /** diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3e78e5d95..d04602027 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -122,6 +122,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 0f7251d45..cf10ba18d 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -1210,6 +1210,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 ) {