From b62732e1d645e5d7d21e198f556e94437bc69d7f Mon Sep 17 00:00:00 2001 From: Xiaokang Qian Date: Thu, 30 Nov 2023 09:58:08 +0000 Subject: [PATCH] tls13: cli: Add mbedtls_ssl_write_early_data() API Signed-off-by: Xiaokang Qian Signed-off-by: Ronald Cron --- library/ssl_msg.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index c2e64c609..f3bb32360 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6058,6 +6058,81 @@ int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t return ret; } +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) +int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const struct mbedtls_ssl_config *conf; + int written_data_len = 0; + + MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data")); + + if (ssl == NULL || (conf = ssl->conf) == NULL) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) || + (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) || + (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) { + return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; + } + + if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { + return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; + } + + /* + * If we are at the beginning of the handshake, advance the handshake just + * enough to be able to send early data if possible. That way, we can + * guarantee that when starting the handshake with this function we will + * send at least one record of early data. + * Otherwise, resume the handshake and if the handshake sequence stops + * waiting for some message from the server, send early data if we can. + */ + + if ((ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) || + (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT)) { + while ((ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) || + (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT)) { + ret = mbedtls_ssl_handshake_step(ssl); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret); + return ret; + } + + ret = mbedtls_ssl_flush_output(ssl); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret); + return ret; + } + } + } else { + if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) && + (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { + return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; + } + + ret = mbedtls_ssl_handshake(ssl); + if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) { + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); + return ret; + } + } + + if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) && + (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { + return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; + } + + written_data_len = ssl_write_real(ssl, buf, len); + + MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, len=%d", written_data_len)); + + return written_data_len; +} +#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ + /* * Notify the peer that the connection is being closed */