Update crypto negotation to draft 15.

BUG=77

Change-Id: If568412655aae240b072c29d763a5b17bb5ca3f7
Reviewed-on: https://boringssl-review.googlesource.com/10840
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c
index 9e146e6..984cc5c 100644
--- a/ssl/tls13_server.c
+++ b/ssl/tls13_server.c
@@ -51,32 +51,11 @@
 
 static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
 
-static int resolve_psk_secret(SSL *ssl) {
-  SSL_HANDSHAKE *hs = ssl->s3->hs;
-
-  if (ssl->s3->tmp.new_cipher->algorithm_auth != SSL_aPSK) {
-    return tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len);
-  }
-
-  uint8_t resumption_psk[EVP_MAX_MD_SIZE];
-  if (!tls13_resumption_psk(ssl, resumption_psk, hs->hash_len,
-                            ssl->s3->new_session) ||
-      !tls13_advance_key_schedule(ssl, resumption_psk, hs->hash_len)) {
-    return 0;
-  }
-
-  return 1;
-}
-
 static int resolve_ecdhe_secret(SSL *ssl, int *out_need_retry,
                                 struct ssl_early_callback_ctx *early_ctx) {
   *out_need_retry = 0;
-  SSL_HANDSHAKE *hs = ssl->s3->hs;
 
-  if (ssl->s3->tmp.new_cipher->algorithm_mkey != SSL_kECDHE) {
-    return tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len);
-  }
-
+  /* We only support connections that include an ECDHE key exchange. */
   CBS key_share;
   if (!ssl_early_callback_get_extension(early_ctx, &key_share,
                                         TLSEXT_TYPE_key_share)) {
@@ -139,13 +118,11 @@
     return 0;
   }
 
-  uint16_t resumption_cipher;
   if (session != NULL &&
       /* Only resume if the session's version matches. */
       (session->ssl_version != ssl->version ||
-       !ssl_cipher_get_ecdhe_psk_cipher(session->cipher, &resumption_cipher) ||
-       !ssl_client_cipher_list_contains_cipher(&client_hello,
-                                               resumption_cipher))) {
+       !ssl_client_cipher_list_contains_cipher(
+           &client_hello, (uint16_t)SSL_CIPHER_get_id(session->cipher)))) {
     SSL_SESSION_free(session);
     session = NULL;
   }
@@ -227,39 +204,32 @@
     }
 
     ssl->s3->new_session->cipher = cipher;
-    ssl->s3->tmp.new_cipher = cipher;
-  } else {
-    uint16_t resumption_cipher;
-    if (!ssl_cipher_get_ecdhe_psk_cipher(ssl->s3->new_session->cipher,
-                                         &resumption_cipher)) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
-      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-      return ssl_hs_error;
-    }
-    ssl->s3->tmp.new_cipher = SSL_get_cipher_by_value(resumption_cipher);
   }
 
+  ssl->s3->tmp.new_cipher = ssl->s3->new_session->cipher;
   ssl->method->received_flight(ssl);
 
-  /* The PRF hash is now known. Set up the key schedule and hash the
-   * ClientHello. */
-  size_t resumption_ctx_len =
+
+  /* The PRF hash is now known. */
+  size_t hash_len =
       EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
+
+  /* Derive resumption material. */
+  uint8_t resumption_ctx[EVP_MAX_MD_SIZE] = {0};
+  uint8_t psk_secret[EVP_MAX_MD_SIZE] = {0};
   if (ssl->s3->session_reused) {
-    uint8_t resumption_ctx[EVP_MAX_MD_SIZE];
-    if (!tls13_resumption_context(ssl, resumption_ctx, resumption_ctx_len,
+    if (!tls13_resumption_context(ssl, resumption_ctx, hash_len,
                                   ssl->s3->new_session) ||
-        !tls13_init_key_schedule(ssl, resumption_ctx, resumption_ctx_len)) {
-      return ssl_hs_error;
-    }
-  } else {
-    if (!tls13_init_key_schedule(ssl, kZeroes, resumption_ctx_len)) {
+        !tls13_resumption_psk(ssl, psk_secret, hash_len,
+                              ssl->s3->new_session)) {
       return ssl_hs_error;
     }
   }
 
-  /* Resolve PSK and incorporate it into the secret. */
-  if (!resolve_psk_secret(ssl)) {
+  /* Set up the key schedule, hash in the ClientHello, and incorporate the PSK
+   * into the running secret. */
+  if (!tls13_init_key_schedule(ssl, resumption_ctx, hash_len) ||
+      !tls13_advance_key_schedule(ssl, psk_secret, hash_len)) {
     return ssl_hs_error;
   }
 
@@ -345,14 +315,27 @@
       !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
       !CBB_add_u16_length_prefixed(&body, &extensions) ||
       !ssl_ext_pre_shared_key_add_serverhello(ssl, &extensions) ||
-      !ssl_ext_key_share_add_serverhello(ssl, &extensions) ||
-      !ssl->method->finish_message(ssl, &cbb)) {
-    CBB_cleanup(&cbb);
-    return ssl_hs_error;
+      !ssl_ext_key_share_add_serverhello(ssl, &extensions)) {
+    goto err;
+  }
+
+  if (!ssl->s3->session_reused) {
+    if (!CBB_add_u16(&extensions, TLSEXT_TYPE_signature_algorithms) ||
+        !CBB_add_u16(&extensions, 0)) {
+      goto err;
+    }
+  }
+
+  if (!ssl->method->finish_message(ssl, &cbb)) {
+    goto err;
   }
 
   hs->state = state_send_encrypted_extensions;
   return ssl_hs_write_message;
+
+err:
+  CBB_cleanup(&cbb);
+  return ssl_hs_error;
 }
 
 static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL *ssl,
@@ -378,8 +361,8 @@
                                                       SSL_HANDSHAKE *hs) {
   /* Determine whether to request a client certificate. */
   ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
-  /* CertificateRequest may only be sent in certificate-based ciphers. */
-  if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
+  /* CertificateRequest may only be sent in non-resumption handshakes. */
+  if (ssl->s3->session_reused) {
     ssl->s3->tmp.cert_request = 0;
   }
 
@@ -424,7 +407,7 @@
 
 static enum ssl_hs_wait_t do_send_server_certificate(SSL *ssl,
                                                      SSL_HANDSHAKE *hs) {
-  if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
+  if (ssl->s3->session_reused) {
     hs->state = state_send_server_finished;
     return ssl_hs_ok;
   }