From faa77f36f0e0be37bf9733a14d79a8e9f5863c45 Mon Sep 17 00:00:00 2001
From: Todd Short <tshort@akamai.com>
Date: Fri, 14 Jun 2019 12:04:14 -0400
Subject: [PATCH 02/43] QUIC: New method to get QUIC secret length

---
 ssl/ssl_local.h |  1 -
 ssl/ssl_quic.c  | 30 ++++++++++++++++++++++++++----
 ssl/tls13_enc.c |  3 ---
 3 files changed, 26 insertions(+), 8 deletions(-)

--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -1717,7 +1717,6 @@ struct ssl_st {
     QUIC_DATA *quic_input_data_head;
     QUIC_DATA *quic_input_data_tail;
     const SSL_QUIC_METHOD *quic_method;
-    size_t quic_len;
 #endif
     /*
      * Parsed form of the ClientHello, kept around across client_hello_cb
--- a/ssl/ssl_quic.c
+++ b/ssl/ssl_quic.c
@@ -181,6 +181,8 @@ int quic_set_encryption_secrets(SSL *ssl
 {
     uint8_t *read_secret = NULL;
     uint8_t *write_secret = NULL;
+    size_t len;
+    const EVP_MD *md;
     static const unsigned char zeros[EVP_MAX_MD_SIZE];
 
     if (!SSL_IS_QUIC(ssl))
@@ -202,21 +204,41 @@ int quic_set_encryption_secrets(SSL *ssl
     default:
         return 1;
     }
+
+    md = ssl_handshake_md(ssl);
+    if (md == NULL) {
+        /* May not have selected cipher, yet */
+        const SSL_CIPHER *c = NULL;
+
+        if (ssl->session != NULL)
+            c = SSL_SESSION_get0_cipher(ssl->session);
+        else if (ssl->psksession != NULL)
+            c = SSL_SESSION_get0_cipher(ssl->psksession);
+
+        if (c != NULL)
+            md = SSL_CIPHER_get_handshake_digest(c);
+    }
+
+    if ((len = EVP_MD_size(md)) <= 0) {
+        SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
     /* In some cases, we want to set the secret only when BOTH are non-zero */
     if (read_secret != NULL && write_secret != NULL
-            && !memcmp(read_secret, zeros, ssl->quic_len)
-            && !memcmp(write_secret, zeros, ssl->quic_len))
+            && !memcmp(read_secret, zeros, len)
+            && !memcmp(write_secret, zeros, len))
         return 1;
 
     if (ssl->server) {
         if (!ssl->quic_method->set_encryption_secrets(ssl, level, read_secret,
-                                                      write_secret, ssl->quic_len)) {
+                                                      write_secret, len)) {
             SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
             return 0;
         }
     } else {
         if (!ssl->quic_method->set_encryption_secrets(ssl, level, write_secret,
-                                                      read_secret, ssl->quic_len)) {
+                                                      read_secret, len)) {
             SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
             return 0;
         }
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -550,9 +550,6 @@ int tls13_change_cipher_state(SSL *s, in
                 goto err;
             }
             hashlen = hashlenui;
-#ifndef OPENSSL_NO_QUIC
-            s->quic_len = hashlen;
-#endif
             EVP_MD_CTX_free(mdctx);
 
             if (!tls13_hkdf_expand(s, md, insecret,
