+ err:
+ OPENSSL_free(extensions);
+ return MSG_PROCESS_ERROR;
+}
+
+static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt)
+{
+ unsigned int sversion;
+ const unsigned char *cipherchars;
+ RAW_EXTENSION *extensions = NULL;
+ PACKET extpkt;
+
+ if (!PACKET_get_net_2(pkt, &sversion)) {
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST,
+ SSL_R_LENGTH_MISMATCH);
+ goto err;
+ }
+
+ /* TODO(TLS1.3): Remove the TLS1_3_VERSION_DRAFT clause before release */
+ if (sversion != TLS1_3_VERSION && sversion != TLS1_3_VERSION_DRAFT) {
+ SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
+ SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST,
+ SSL_R_WRONG_SSL_VERSION);
+ goto err;
+ }
+
+ s->hello_retry_request = 1;
+
+ /*
+ * If we were sending early_data then the enc_write_ctx is now invalid and
+ * should not be used.
+ */
+ EVP_CIPHER_CTX_free(s->enc_write_ctx);
+ s->enc_write_ctx = NULL;
+
+ if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) {
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST,
+ SSL_R_LENGTH_MISMATCH);
+ goto err;
+ }
+
+ if (!set_client_ciphersuite(s, cipherchars)) {
+ /* SSLfatal() already called */
+ goto err;
+ }
+
+ if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
+ /* Must have a non-empty extensions block */
+ || PACKET_remaining(&extpkt) == 0
+ /* Must be no trailing data after extensions */
+ || PACKET_remaining(pkt) != 0) {
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST,
+ SSL_R_BAD_LENGTH);
+ goto err;
+ }
+
+ if (!tls_collect_extensions(s, &extpkt, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST,
+ &extensions, NULL, 1)
+ || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST,
+ extensions, NULL, 0, 1)) {
+ /* SSLfatal() already called */
+ goto err;
+ }
+
+ OPENSSL_free(extensions);
+ extensions = NULL;
+
+ if (s->ext.tls13_cookie_len == 0
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+ && s->s3->tmp.pkey != NULL
+#endif
+ ) {
+ /*
+ * We didn't receive a cookie or a new key_share so the next
+ * ClientHello will not change
+ */
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
+ SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST,
+ SSL_R_NO_CHANGE_FOLLOWING_HRR);
+ goto err;
+ }
+
+ /*
+ * Re-initialise the Transcript Hash. We're going to prepopulate it with
+ * a synthetic message_hash in place of ClientHello1.
+ */
+ if (!create_synthetic_message_hash(s)) {
+ /* SSLfatal() already called */
+ goto err;
+ }
+
+ /*
+ * Add this message to the Transcript Hash. Normally this is done
+ * automatically prior to the message processing stage. However due to the
+ * need to create the synthetic message hash, we defer that step until now
+ * for HRR messages.
+ */
+ if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+ s->init_num + SSL3_HM_HEADER_LENGTH)) {
+ /* SSLfatal() already called */
+ goto err;
+ }
+
+ return MSG_PROCESS_FINISHED_READING;
+ err: