Add ALPN information in session tickets
Signed-off-by: Waleed Elmelegy <waleed.elmelegy@arm.com>
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 681ccab..d7d26ab 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3735,7 +3735,25 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/* Serialization of TLS 1.3 sessions:
*
- * For more detail, see the description of ssl_session_save().
+ * struct {
+ * opaque hostname<0..2^16-1>;
+ * uint64 ticket_reception_time;
+ * uint32 ticket_lifetime;
+ * opaque ticket<1..2^16-1>;
+ * } ClientOnlyData;
+ *
+ * struct {
+ * uint32 ticket_age_add;
+ * uint8 ticket_flags;
+ * opaque resumption_key<0..255>;
+ * uint32 max_early_data_size;
+ * uint16 record_size_limit;
+ * select ( endpoint ) {
+ * case client: ClientOnlyData;
+ * case server: uint64 ticket_creation_time;
+ * };
+ * } serialized_session_tls13;
+ *
*/
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
@@ -3750,9 +3768,16 @@
size_t hostname_len = (session->hostname == NULL) ?
0 : strlen(session->hostname) + 1;
#endif
+
+#if defined(MBEDTLS_SSL_SRV_C) && \
+ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ const uint8_t alpn_len = (session->alpn == NULL) ?
+ 0 : (uint8_t) strlen(session->alpn) + 1;
+#endif
size_t needed = 4 /* ticket_age_add */
+ 1 /* ticket_flags */
+ 1; /* resumption_key length */
+
*olen = 0;
if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) {
@@ -3771,6 +3796,15 @@
needed += 8; /* ticket_creation_time or ticket_reception_time */
#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ needed += 1 /* alpn_len */
+ + alpn_len; /* alpn */
+#endif
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
#if defined(MBEDTLS_SSL_CLI_C)
if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -3813,13 +3847,24 @@
p += 2;
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+#if defined(MBEDTLS_HAVE_TIME)
MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
p += 8;
- }
#endif /* MBEDTLS_HAVE_TIME */
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ *p++ = alpn_len;
+ if (alpn_len > 0) {
+ /* save chosen alpn */
+ memcpy(p, session->alpn, alpn_len);
+ p += alpn_len;
+ }
+#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
#if defined(MBEDTLS_SSL_CLI_C)
if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -3894,16 +3939,39 @@
p += 2;
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+#if defined(MBEDTLS_HAVE_TIME)
if (end - p < 8) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
- }
#endif /* MBEDTLS_HAVE_TIME */
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN)
+ uint8_t alpn_len;
+
+ if (end - p < 1) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ alpn_len = *p++;
+
+ if (end - p < alpn_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ if (alpn_len > 0) {
+ session->alpn = mbedtls_calloc(alpn_len, sizeof(char));
+ if (session->alpn == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+ memcpy(session->alpn, p, alpn_len);
+ p += alpn_len;
+ }
+#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
#if defined(MBEDTLS_SSL_CLI_C)
if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -4849,6 +4917,10 @@
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
mbedtls_free(session->hostname);
#endif
+#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && \
+ defined(MBEDTLS_SSL_SRV_C)
+ mbedtls_free(session->alpn);
+#endif
mbedtls_free(session->ticket);
#endif