diff --git a/library/ssl_misc.h b/library/ssl_misc.h index d8844fcc32..883b98828d 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2150,6 +2150,9 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, unsigned char *buf, const unsigned char *end, size_t *out_len); + +int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, + size_t early_data_len); #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index bc737047a4..a3b4d355b4 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1454,6 +1454,47 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, return 0; } + +#if defined(MBEDTLS_SSL_SRV_C) +int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, + size_t early_data_len) +{ + uint32_t uint32_early_data_len = (uint32_t) early_data_len; + + /* + * This function should be called only while an handshake is in progress + * and thus a session under negotiation. Add a sanity check to detect a + * misuse. + */ + if (ssl->session_negotiate == NULL) { + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + + /* RFC 8446 section 4.6.1 + * + * A server receiving more than max_early_data_size bytes of 0-RTT data + * SHOULD terminate the connection with an "unexpected_message" alert. + */ + if (uint32_early_data_len > + (ssl->session_negotiate->max_early_data_size - + ssl->early_data_count)) { + + MBEDTLS_SSL_DEBUG_MSG( + 2, ("EarlyData: Too many early data received, %u > %u", + ssl->early_data_count + uint32_early_data_len, + ssl->session_negotiate->max_early_data_size)); + + MBEDTLS_SSL_PEND_FATAL_ALERT( + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE, + MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); + return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; + } + + ssl->early_data_count += uint32_early_data_len; + + return 0; +} +#endif /* MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_EARLY_DATA */ /* Reset SSL context and update hash for handling HRR. diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 2391915357..449fa380f1 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -2913,17 +2913,14 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl) } if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data")); - /* RFC 8446 section 4.6.1 - * - * A server receiving more than max_early_data_size bytes of 0-RTT data - * SHOULD terminate the connection with an "unexpected_message" alert. - * - * TODO: Add received data size check here. - */ if (ssl->in_offt == NULL) { + MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data")); /* Set the reading pointer */ ssl->in_offt = ssl->in_msg; + ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen); + if (ret != 0) { + return ret; + } } return SSL_GOT_EARLY_DATA; }