Add end-of-early-data write
Signed-off-by: Xiaokang Qian <xiaokang.qian@arm.com>
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 4aea61c..e469174 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -2108,6 +2108,96 @@
}
+/*
+ * Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
+ *
+ * RFC 8446:
+ *
+ * If the server sent an "early_data" extension in the EncryptedExtensions
+ * message, the client MUST send an EndOfEarlyData message after receiving
+ * the server Finished.
+ *
+ * If the server does not send an "early_data" extension
+ * in EncryptedExtensions, then the client MUST NOT send
+ * an EndOfEarlyData message.
+ */
+
+/* Write end of early data message
+ * struct {} EndOfEarlyData;
+ */
+
+#define SSL_END_OF_EARLY_DATA_WRITE 0
+#define SSL_END_OF_EARLY_DATA_SKIP 1
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_write_end_of_early_data_coordinate(
+ mbedtls_ssl_context *ssl)
+{
+ ((void) ssl);
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
+ return SSL_END_OF_EARLY_DATA_WRITE;
+ } else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
+ MBEDTLS_SSL_DEBUG_MSG(4, ("skip EndOfEarlyData, server rejected"));
+ return SSL_END_OF_EARLY_DATA_SKIP;
+ } else {
+ MBEDTLS_SSL_DEBUG_MSG(4, ("skip write EndOfEarlyData"));
+ }
+#endif /* MBEDTLS_SSL_EARLY_DATA */
+
+ return SSL_END_OF_EARLY_DATA_SKIP;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_finalize_write_end_of_early_data(
+ mbedtls_ssl_context *ssl)
+{
+#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
+ mbedtls_ssl_handshake_set_state(
+ ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED);
+#else
+ mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
+#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
+
+ return 0;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_write_end_of_early_data(mbedtls_ssl_context *ssl)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("=> write EndOfEarlyData"));
+
+ MBEDTLS_SSL_PROC_CHK_NEG(
+ ssl_tls13_write_end_of_early_data_coordinate(ssl));
+ if (ret == SSL_END_OF_EARLY_DATA_WRITE) {
+ unsigned char *buf = NULL;
+ size_t buf_len;
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("Client write EndOfEarlyData"));
+
+ MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl,
+ MBEDTLS_SSL_HS_END_OF_EARLY_DATA, &buf,
+ &buf_len));
+
+ mbedtls_ssl_add_hs_hdr_to_checksum(
+ ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0);
+
+ MBEDTLS_SSL_PROC_CHK(
+ mbedtls_ssl_finish_handshake_msg(ssl, buf_len, 0));
+ }
+
+ /* Update state */
+ MBEDTLS_SSL_PROC_CHK(
+ ssl_tls13_finalize_write_end_of_early_data(ssl));
+
+cleanup:
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("<= write EndOfEarlyData"));
+ return ret;
+}
+
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
/*
* STATE HANDLING: CertificateRequest
@@ -2367,13 +2457,7 @@
return ret;
}
-#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
- mbedtls_ssl_handshake_set_state(
- ssl,
- MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED);
-#else
- mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
-#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
+ mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
return 0;
}
@@ -2789,6 +2873,10 @@
ret = ssl_tls13_process_server_finished(ssl);
break;
+ case MBEDTLS_SSL_END_OF_EARLY_DATA:
+ ret = ssl_tls13_write_end_of_early_data(ssl);
+ break;
+
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
ret = ssl_tls13_write_client_certificate(ssl);
break;