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: