Implement PR 1091 (TLS 1.3 draft '22').

This introduces a wire change to Experiment2/Experiment3 over 0RTT, however
as there is never going to be a 0RTT deployment with Experiment2/Experiment3,
this is valid.

Change-Id: Id541d195cbc4bbb3df7680ae2a02b53bb8ae3eab
Reviewed-on: https://boringssl-review.googlesource.com/22744
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc
index 9c09309..0013e61 100644
--- a/ssl/tls13_client.cc
+++ b/ssl/tls13_client.cc
@@ -36,7 +36,6 @@
   state_read_hello_retry_request = 0,
   state_send_second_client_hello,
   state_read_server_hello,
-  state_process_change_cipher_spec,
   state_read_encrypted_extensions,
   state_read_certificate_request,
   state_read_server_certificate,
@@ -57,23 +56,52 @@
   if (!ssl->method->get_message(ssl, &msg)) {
     return ssl_hs_read_message;
   }
-  if (msg.type != SSL3_MT_HELLO_RETRY_REQUEST) {
-    hs->tls13_state = state_read_server_hello;
-    return ssl_hs_ok;
-  }
 
-  CBS body = msg.body, extensions;
-  uint16_t server_version, cipher_suite = 0;
-  if (!CBS_get_u16(&body, &server_version) ||
-      (ssl_is_draft21(ssl->version) &&
-       !CBS_get_u16(&body, &cipher_suite)) ||
-      !CBS_get_u16_length_prefixed(&body, &extensions) ||
-      // HelloRetryRequest may not be empty.
-      CBS_len(&extensions) == 0 ||
-      CBS_len(&body) != 0) {
-    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
-    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
-    return ssl_hs_error;
+  CBS extensions;
+  uint16_t cipher_suite = 0;
+  if (ssl_is_draft22(ssl->version)) {
+    if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) {
+      return ssl_hs_error;
+    }
+
+    CBS body = msg.body, server_random, session_id;
+    uint16_t server_version;
+    if (!CBS_get_u16(&body, &server_version) ||
+        !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) ||
+        !CBS_get_u8_length_prefixed(&body, &session_id) ||
+        !CBS_get_u16(&body, &cipher_suite) ||
+        !CBS_skip(&body, 1) ||
+        !CBS_get_u16_length_prefixed(&body, &extensions) ||
+        CBS_len(&extensions) == 0 ||
+        CBS_len(&body) != 0) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      return ssl_hs_error;
+    }
+
+    if (!CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) {
+      hs->tls13_state = state_read_server_hello;
+      return ssl_hs_ok;
+    }
+  } else {
+    if (msg.type != SSL3_MT_HELLO_RETRY_REQUEST) {
+      hs->tls13_state = state_read_server_hello;
+      return ssl_hs_ok;
+    }
+
+    CBS body = msg.body;
+    uint16_t server_version;
+    if (!CBS_get_u16(&body, &server_version) ||
+        (ssl_is_draft21(ssl->version) &&
+         !CBS_get_u16(&body, &cipher_suite)) ||
+        !CBS_get_u16_length_prefixed(&body, &extensions) ||
+        // HelloRetryRequest may not be empty.
+        CBS_len(&extensions) == 0 ||
+        CBS_len(&body) != 0) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      return ssl_hs_error;
+    }
   }
 
   if (ssl_is_draft21(ssl->version)) {
@@ -96,11 +124,13 @@
   }
 
 
-  bool have_cookie, have_key_share;
-  CBS cookie, key_share;
+  bool have_cookie, have_key_share, have_supported_versions;
+  CBS cookie, key_share, supported_versions;
   const SSL_EXTENSION_TYPE ext_types[] = {
       {TLSEXT_TYPE_key_share, &have_key_share, &key_share},
       {TLSEXT_TYPE_cookie, &have_cookie, &cookie},
+      {TLSEXT_TYPE_supported_versions, &have_supported_versions,
+       &supported_versions},
   };
 
   uint8_t alert = SSL_AD_DECODE_ERROR;
@@ -111,6 +141,11 @@
     return ssl_hs_error;
   }
 
+  if (!ssl_is_draft22(ssl->version) && have_supported_versions) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+    return ssl_hs_error;
+  }
   if (have_cookie) {
     CBS cookie_value;
     if (!CBS_get_u16_length_prefixed(&cookie, &cookie_value) ||
@@ -359,20 +394,8 @@
 
   if (!tls13_advance_key_schedule(hs, dhe_secret.data(), dhe_secret.size()) ||
       !ssl_hash_message(hs, msg) ||
-      !tls13_derive_handshake_secrets(hs)) {
-    return ssl_hs_error;
-  }
-
-  ssl->method->next_message(ssl);
-  hs->tls13_state = state_process_change_cipher_spec;
-  return ssl_is_resumption_experiment(ssl->version)
-             ? ssl_hs_read_change_cipher_spec
-             : ssl_hs_ok;
-}
-
-static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
-  SSL *const ssl = hs->ssl;
-  if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
+      !tls13_derive_handshake_secrets(hs) ||
+      !tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
                              hs->hash_len)) {
     return ssl_hs_error;
   }
@@ -388,6 +411,7 @@
     }
   }
 
+  ssl->method->next_message(ssl);
   hs->tls13_state = state_read_encrypted_extensions;
   return ssl_hs_ok;
 }
@@ -642,9 +666,7 @@
   }
 
   if (hs->early_data_offered) {
-    if ((ssl_is_resumption_client_ccs_experiment(ssl->version) &&
-         !ssl->method->add_change_cipher_spec(ssl)) ||
-        !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
+    if (!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
                                hs->hash_len)) {
       return ssl_hs_error;
     }
@@ -767,9 +789,6 @@
       case state_read_server_hello:
         ret = do_read_server_hello(hs);
         break;
-      case state_process_change_cipher_spec:
-        ret = do_process_change_cipher_spec(hs);
-        break;
       case state_read_encrypted_extensions:
         ret = do_read_encrypted_extensions(hs);
         break;
@@ -824,8 +843,6 @@
       return "TLS 1.3 client send_second_client_hello";
     case state_read_server_hello:
       return "TLS 1.3 client read_server_hello";
-    case state_process_change_cipher_spec:
-      return "TLS 1.3 client process_change_cipher_spec";
     case state_read_encrypted_extensions:
       return "TLS 1.3 client read_encrypted_extensions";
     case state_read_certificate_request: