Merge pull request #8692 from ronald-cron-arm/read-early-data

TLS 1.3: SRV: Implement mbedtls_ssl_read_early_data()
This commit is contained in:
Ronald Cron 2024-02-02 14:07:47 +00:00 committed by GitHub
commit b90e695e09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 251 additions and 158 deletions

View File

@ -90,8 +90,18 @@
#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00
/** Not possible to read early data */
#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80
/**
* Early data has been received as part of an on-going handshake.
* This error code can be returned only on server side if and only if early
* data has been enabled by means of the mbedtls_ssl_conf_early_data() API.
* This error code can then be returned by mbedtls_ssl_handshake(),
* mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write() if
* early data has been received as part of the handshake sequence they
* triggered. To read the early data, call mbedtls_ssl_read_early_data().
*/
#define MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA -0x7C00
/** Not possible to write early data */
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C00
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C80
/* Error space gap */
/* Error space gap */
/* Error space gap */
@ -1644,6 +1654,18 @@ struct mbedtls_ssl_context {
*/
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
/**
* Status of the negotiation of the use of early data.
* See the documentation of mbedtls_ssl_get_early_data_status() for more
* information.
*
* Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT when the context is
* reset.
*/
int MBEDTLS_PRIVATE(early_data_status);
#endif
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -1841,10 +1863,6 @@ struct mbedtls_ssl_context {
* and #MBEDTLS_SSL_CID_DISABLED. */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int MBEDTLS_PRIVATE(early_data_status);
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
/** Callback to export key block and master secret */
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */
@ -1993,7 +2011,7 @@ void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport);
*/
void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_EARLY_DATA)
/**
* \brief Set the early data mode
* Default: disabled on server and client
@ -2001,14 +2019,24 @@ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
* \param conf The SSL configuration to use.
* \param early_data_enabled can be:
*
* MBEDTLS_SSL_EARLY_DATA_DISABLED: early data functionality is disabled
* This is the default on client and server.
* MBEDTLS_SSL_EARLY_DATA_DISABLED:
* Early data functionality is disabled. This is the default on client and
* server.
*
* MBEDTLS_SSL_EARLY_DATA_ENABLED: early data functionality is enabled and
* may be negotiated in the handshake. Application using
* early data functionality needs to be aware of the
* lack of replay protection of the early data application
* payloads.
* MBEDTLS_SSL_EARLY_DATA_ENABLED:
* Early data functionality is enabled and may be negotiated in the handshake.
* Application using early data functionality needs to be aware that the
* security properties for early data (also refered to as 0-RTT data) are
* weaker than those for other kinds of TLS data. See the documentation of
* mbedtls_ssl_write_early_data() and mbedtls_ssl_read_early_data() for more
* information.
* When early data functionality is enabled on server and only in that case,
* the call to one of the APIs that trigger or resume an handshake sequence,
* namely mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
* mbedtls_ssl_read() or mbedtls_ssl_write() may return with the error code
* MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have
* been received. To read the early data, call mbedtls_ssl_read_early_data()
* before calling the original function again.
*
* \warning This interface is experimental and may change without notice.
*
@ -2048,7 +2076,7 @@ void mbedtls_ssl_conf_max_early_data_size(
mbedtls_ssl_config *conf, uint32_t max_early_data_size);
#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
@ -4733,6 +4761,13 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
* and the client did not demonstrate reachability yet - in
* this case you must stop using the context (see below).
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
@ -4741,7 +4776,8 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
@ -4810,8 +4846,9 @@ static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl)
*
* \warning If this function returns something other than \c 0,
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using
* the SSL context for reading or writing, and either free it
* or call \c mbedtls_ssl_session_reset() on it before
* re-using it for a new connection; the current connection
@ -4879,6 +4916,13 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
* side of a DTLS connection and the client is initiating a
* new connection using the same source port. See below.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
@ -4887,8 +4931,9 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
@ -4953,6 +4998,13 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
* in this case you must call this function again to complete
* the handshake when you're done attending other tasks.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
@ -4960,8 +5012,9 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* a non-negative value,
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
@ -5029,48 +5082,46 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_SSL_SRV_C)
/**
* \brief Read at most 'len' application data bytes while performing
* the handshake (early data).
* \brief Read at most 'len' bytes of early data
*
* \note This function behaves mainly as mbedtls_ssl_read(). The
* specification of mbedtls_ssl_read() relevant to TLS 1.3
* (thus not the parts specific to (D)TLS 1.2) applies to this
* function and the present documentation is restricted to the
* differences with mbedtls_ssl_read().
* \note This API is server specific.
*
* \param ssl SSL context
* \warning Early data is defined in the TLS 1.3 specification, RFC 8446.
* IMPORTANT NOTE from section 2.3 of the specification:
*
* The security properties for 0-RTT data are weaker than
* those for other kinds of TLS data. Specifically:
* - This data is not forward secret, as it is encrypted
* solely under keys derived using the offered PSK.
* - There are no guarantees of non-replay between connections.
* Protection against replay for ordinary TLS 1.3 1-RTT data
* is provided via the server's Random value, but 0-RTT data
* does not depend on the ServerHello and therefore has
* weaker guarantees. This is especially relevant if the
* data is authenticated either with TLS client
* authentication or inside the application protocol. The
* same warnings apply to any use of the
* early_exporter_master_secret.
*
* \note This function is used in conjunction with
* mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
* mbedtls_ssl_read() and mbedtls_ssl_write() to read early
* data when these functions return
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
*
* \param ssl SSL context, it must have been initialized and set up.
* \param buf buffer that will hold the data
* \param len maximum number of bytes to read
*
* \return One additional specific return value:
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA.
*
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it
* is not possible to read early data for the SSL context
* \p ssl.
*
* It may have been possible and it is not possible
* anymore because the server received the End of Early Data
* message or the maximum number of allowed early data for the
* PSK in use has been reached.
*
* It may never have been possible and will never be possible
* for the SSL context \p ssl because the use of early data
* is disabled for that context or more generally the context
* is not suitably configured to enable early data or the
* client does not use early data or the first call to the
* function was done while the handshake was already too
* advanced to gather and accept early data.
*
* It is not possible to read early data for the SSL context
* \p ssl but this does not preclude for using it with
* mbedtls_ssl_write(), mbedtls_ssl_read() or
* mbedtls_ssl_handshake().
*
* \note When a server wants to retrieve early data, it is expected
* that this function starts the handshake for the SSL context
* \p ssl. But this is not mandatory.
*
* \return The (positive) number of bytes read if successful.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
* \return #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA if it is not
* possible to read early data for the SSL context \p ssl. Note
* that this function is intended to be called for an SSL
* context \p ssl only after a call to mbedtls_ssl_handshake(),
* mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or
* mbedtls_ssl_write() for \p ssl that has returned
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
*/
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len);

View File

@ -650,6 +650,10 @@ struct mbedtls_ssl_handshake_params {
/* Flag indicating if a CertificateRequest message has been sent
* to the client or not. */
uint8_t certificate_request_sent;
#if defined(MBEDTLS_SSL_EARLY_DATA)
/* Flag indicating if the server has accepted early data or not. */
uint8_t early_data_accepted;
#endif
#endif /* MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -2130,12 +2134,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len);
#if defined(MBEDTLS_SSL_SRV_C)
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED \
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT
#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View File

@ -5647,13 +5647,54 @@ static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
/*
* brief Read at most 'len' application data bytes from the input
* buffer.
*
* param ssl SSL context:
* - First byte of application data not read yet in the input
* buffer located at address `in_offt`.
* - The number of bytes of data not read yet is `in_msglen`.
* param buf buffer that will hold the data
* param len maximum number of bytes to read
*
* note The function updates the fields `in_offt` and `in_msglen`
* according to the number of bytes read.
*
* return The number of bytes read.
*/
static int ssl_read_application_data(
mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
return (int) n;
}
/*
* Receive application data decrypted from the SSL layer
*/
int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
if (ssl == NULL || ssl->conf == NULL) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
@ -5817,32 +5858,34 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
#endif /* MBEDTLS_SSL_PROTO_DTLS */
}
n = (len < ssl->in_msglen)
? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
ret = ssl_read_application_data(ssl, buf, len);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
return (int) n;
return ret;
}
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len)
{
if (ssl == NULL || (ssl->conf == NULL)) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
/*
* The server may receive early data only while waiting for the End of
* Early Data handshake message.
*/
if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
(ssl->in_offt == NULL)) {
return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
}
return ssl_read_application_data(ssl, buf, len);
}
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */
/*
* Send application data to be encrypted by the SSL layer, taking care of max
* fragment length and buffer size.

View File

@ -1098,6 +1098,10 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
#endif
/* Initialize structures */
mbedtls_ssl_session_init(ssl->session_negotiate);
ssl_handshake_params_init(ssl->handshake);

View File

@ -1780,7 +1780,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
static int ssl_tls13_is_early_data_accepted(mbedtls_ssl_context *ssl,
int hrr_required)
{
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@ -1788,17 +1789,19 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: no early data extension received."));
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED;
return;
return 0;
}
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG(
1,
("EarlyData: rejected, feature disabled in server configuration."));
return;
return 0;
}
if (hrr_required) {
MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, HRR required."));
return 0;
}
if (!handshake->resume) {
@ -1807,7 +1810,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
resumption. */
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, not a session resumption."));
return;
return 0;
}
/* RFC 8446 4.2.10
@ -1830,7 +1833,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected key in "
"`pre_shared_key` is not the first one."));
return;
return 0;
}
if (handshake->ciphersuite_info->id !=
@ -1838,7 +1841,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected ciphersuite is not the one "
"of the selected pre-shared key."));
return;
return 0;
}
@ -1847,18 +1850,18 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
1,
("EarlyData: rejected, early_data not allowed in ticket "
"permission bits."));
return;
return 0;
}
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
return 1;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Update the handshake state machine */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
int hrr_required)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -1882,10 +1885,10 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
/* There is enough information, update early data state. */
ssl_tls13_update_early_data_status(ssl);
ssl->handshake->early_data_accepted =
ssl_tls13_is_early_data_accepted(ssl, hrr_required);
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
@ -1893,6 +1896,8 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
return ret;
}
}
#else
((void) hrr_required);
#endif /* MBEDTLS_SSL_EARLY_DATA */
return 0;
@ -1947,7 +1952,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
return 0;
}
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_client_hello(ssl));
MBEDTLS_SSL_PROC_CHK(
ssl_tls13_postprocess_client_hello(ssl, parse_client_hello_ret ==
SSL_CLIENT_HELLO_HRR_REQUIRED));
if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
@ -2530,7 +2537,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &output_len);
if (ret != 0) {
@ -2857,7 +2864,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
/* See RFC 8446 section A.2 for more information */
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early keys for inbound traffic. "
@ -2911,6 +2918,17 @@ 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) {
/* Set the reading pointer */
ssl->in_offt = ssl->in_msg;
}
return SSL_GOT_EARLY_DATA;
}
@ -2936,37 +2954,6 @@ static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl,
return 0;
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_early_application_data(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
return ret;
}
/*
* Output early data
*
* For the time being, we print received data via debug message.
*
* TODO: Remove it when `mbedtls_ssl_read_early_data` is ready.
*/
ssl->in_msg[ssl->in_msglen] = 0;
MBEDTLS_SSL_DEBUG_MSG(3, ("\n%s", ssl->in_msg));
/* 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.
*/
return 0;
}
/*
* RFC 8446 section A.2
*
@ -3037,7 +3024,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
ssl_tls13_prepare_for_handshake_second_flight(ssl);
} else if (ret == SSL_GOT_EARLY_DATA) {
MBEDTLS_SSL_PROC_CHK(ssl_tls13_process_early_application_data(ssl));
ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA;
goto cleanup;
} else {
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;

View File

@ -1612,6 +1612,7 @@ int main(int argc, char *argv[])
#if defined(MBEDTLS_SSL_EARLY_DATA)
int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED;
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf));
#if defined(MBEDTLS_MEMORY_DEBUG)
@ -3450,6 +3451,19 @@ handshake:
fflush(stdout);
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) {
memset(buf, 0, opt.buffer_size);
ret = mbedtls_ssl_read_early_data(&ssl, buf, opt.buffer_size);
if (ret > 0) {
buf[ret] = '\0';
mbedtls_printf(" %d early data bytes read\n\n%s\n",
ret, (char *) buf);
}
continue;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS &&
ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL) {

View File

@ -1,3 +1,4 @@
EarlyData context: line 0 lf
EarlyData context: line 1 lf
EarlyData context: line 2 lf
EarlyData context: If it appears, that means early_data received.

View File

@ -506,4 +506,7 @@ run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \
-s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \
-s "ClientHello: early_data(42) extension exists." \
-s "EncryptedExtensions: early_data(42) extension exists." \
-s "$( tail -1 $EARLY_DATA_INPUT )"
-s "$( head -1 $EARLY_DATA_INPUT )" \
-s "$( tail -1 $EARLY_DATA_INPUT )" \
-s "200 early data bytes read" \
-s "106 early data bytes read"

View File

@ -12,8 +12,7 @@
#define SSL_MESSAGE_QUEUE_INIT { NULL, 0, 0, 0 }
#if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \
defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \
defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \
@ -3662,12 +3661,7 @@ exit:
}
/* END_CASE */
/*
* The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is
* a temporary workaround to not run the test in Windows-2013 where there is
* an issue with mbedtls_vsnprintf().
*/
/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
void tls13_early_data()
{
int ret = -1;
@ -3678,7 +3672,6 @@ void tls13_early_data()
mbedtls_test_handshake_test_options client_options;
mbedtls_test_handshake_test_options server_options;
mbedtls_ssl_session saved_session;
mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 };
/*
* Test set-up
@ -3699,9 +3692,6 @@ void tls13_early_data()
mbedtls_ssl_conf_early_data(&client_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED);
server_options.pk_alg = MBEDTLS_PK_ECDSA;
server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
server_options.srv_log_obj = &server_pattern;
server_pattern.pattern = early_data;
ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
&server_options, NULL, NULL, NULL,
NULL);
@ -3750,15 +3740,12 @@ void tls13_early_data()
ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
TEST_EQUAL(ret, 0);
mbedtls_debug_set_threshold(3);
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(client_ep.ssl), &(server_ep.ssl),
MBEDTLS_SSL_SERVER_HELLO), 0);
TEST_ASSERT(client_ep.ssl.early_data_status !=
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
TEST_EQUAL(server_pattern.counter, 0);
ret = write_early_data(&(client_ep.ssl), (unsigned char *) early_data,
early_data_len);
@ -3766,11 +3753,16 @@ void tls13_early_data()
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl),
MBEDTLS_SSL_CLIENT_FINISHED), 0);
MBEDTLS_SSL_CLIENT_FINISHED), MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
TEST_EQUAL(server_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED);
TEST_EQUAL(server_pattern.counter, 1);
TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 1);
TEST_EQUAL(mbedtls_ssl_read_early_data(&(server_ep.ssl), buf, sizeof(buf)),
early_data_len);
TEST_MEMORY_COMPARE(buf, early_data_len, early_data, early_data_len);
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl),
MBEDTLS_SSL_HANDSHAKE_OVER), 0);
exit:
mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
@ -3778,7 +3770,6 @@ exit:
mbedtls_test_free_handshake_options(&client_options);
mbedtls_test_free_handshake_options(&server_options);
mbedtls_ssl_session_free(&saved_session);
mbedtls_debug_set_threshold(0);
PSA_DONE();
}
/* END_CASE */