Adding code to send session as PSK Identity.
BUG=75
Change-Id: Ied864cfccbc0e68d71c55c5ab563da27b7253463
Reviewed-on: https://boringssl-review.googlesource.com/9043
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index bb345b4..dc6c6dd 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1030,7 +1030,10 @@
* without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
if (!ssl->s3->initial_handshake_complete &&
ssl->session != NULL &&
- ssl->session->tlsext_tick != NULL) {
+ ssl->session->tlsext_tick != NULL &&
+ /* Don't send TLS 1.3 session tickets in the ticket extension. */
+ ssl->method->version_from_wire(ssl->session->ssl_version) <
+ TLS1_3_VERSION) {
ticket_data = ssl->session->tlsext_tick;
ticket_len = ssl->session->tlsext_ticklen;
}
@@ -1428,7 +1431,7 @@
}
/* Session resumption uses the original session information. */
- if (ssl->session == NULL &&
+ if (!ssl->s3->session_reused &&
!CBS_stow(
contents,
&ssl->s3->new_session->tlsext_signed_cert_timestamp_list,
@@ -1447,7 +1450,7 @@
static int ext_sct_add_serverhello(SSL *ssl, CBB *out) {
/* The extension shouldn't be sent when resuming sessions. */
- if (ssl->session != NULL ||
+ if (ssl->s3->session_reused ||
ssl->ctx->signed_cert_timestamp_list_length == 0) {
return 1;
}
@@ -1972,6 +1975,89 @@
}
+/* Pre Shared Key
+ *
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-14 */
+
+static int ext_pre_shared_key_add_clienthello(SSL *ssl, CBB *out) {
+ uint16_t min_version, max_version;
+ if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+ return 0;
+ }
+
+ if (max_version < TLS1_3_VERSION || ssl->session == NULL ||
+ ssl->method->version_from_wire(ssl->session->ssl_version) <
+ TLS1_3_VERSION) {
+ return 1;
+ }
+
+ CBB contents, identities, identity;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &identities) ||
+ !CBB_add_u16_length_prefixed(&identities, &identity) ||
+ !CBB_add_bytes(&identity, ssl->session->tlsext_tick,
+ ssl->session->tlsext_ticklen)) {
+ return 0;
+ }
+
+ return CBB_flush(out);
+}
+
+int ssl_ext_pre_shared_key_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ uint16_t psk_id;
+ if (!CBS_get_u16(contents, &psk_id) ||
+ CBS_len(contents) != 0) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ if (psk_id != 0) {
+ *out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY;
+ return 0;
+ }
+
+ return 1;
+}
+
+int ssl_ext_pre_shared_key_parse_clienthello(SSL *ssl,
+ SSL_SESSION **out_session,
+ uint8_t *out_alert,
+ CBS *contents) {
+ CBS identities, identity;
+ if (!CBS_get_u16_length_prefixed(contents, &identities) ||
+ !CBS_get_u16_length_prefixed(&identities, &identity) ||
+ CBS_len(contents) != 0) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ /* TLS 1.3 session tickets are renewed separately as part of the
+ * NewSessionTicket. */
+ int renew;
+ return tls_process_ticket(ssl, out_session, &renew, CBS_data(&identity),
+ CBS_len(&identity), NULL, 0);
+}
+
+int ssl_ext_pre_shared_key_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->s3->session_reused) {
+ return 1;
+ }
+
+ CBB contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ /* We only consider the first identity for resumption */
+ !CBB_add_u16(&contents, 0) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
/* Key Share
*
* https://tools.ietf.org/html/draft-ietf-tls-tls13-12 */
@@ -2361,6 +2447,14 @@
ignore_parse_clienthello,
dont_add_serverhello,
},
+ {
+ TLSEXT_TYPE_pre_shared_key,
+ NULL,
+ ext_pre_shared_key_add_clienthello,
+ forbid_parse_serverhello,
+ ignore_parse_clienthello,
+ dont_add_serverhello,
+ },
/* The final extension must be non-empty. WebSphere Application Server 7.0 is
* intolerant to the last extension being zero-length. See
* https://crbug.com/363583. */
@@ -2786,6 +2880,10 @@
*out_renew_ticket = 0;
*out_session = NULL;
+ if (SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
+ goto done;
+ }
+
if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
goto done;
}
@@ -2875,6 +2973,12 @@
memcpy(session->session_id, session_id, session_id_len);
session->session_id_length = session_id_len;
+ if (!ssl_session_is_context_valid(ssl, session) ||
+ !ssl_session_is_time_valid(ssl, session)) {
+ SSL_SESSION_free(session);
+ session = NULL;
+ }
+
*out_session = session;
done: