]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tls] Generate master secret at point of sending ClientKeyExchange
authorMichael Brown <mcb30@ipxe.org>
Thu, 6 Oct 2022 15:06:44 +0000 (16:06 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 11 Oct 2022 13:37:12 +0000 (14:37 +0100)
The master secret is currently constructed upon receiving the
ServerHello message.  This precludes the use of key exchange
mechanisms such as Ephemeral Diffie-Hellman (DHE), which require a
ServerKeyExchange message to exchange additional key material before
the pre-master secret and master secret can be constructed.

Allow for the use of such cipher suites by deferring generation of the
master secret until the point of sending the ClientKeyExchange
message.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/net/tls.c

index 21f7073400956f92255daaef2bf6117e79a8013b..89ed6fceb75ab8ff70f54f270fc06a9bf0d22956 100644 (file)
@@ -1220,6 +1220,16 @@ static int tls_send_client_key_exchange ( struct tls_connection *tls ) {
        int len;
        int rc;
 
+       /* Generate master secret */
+       tls_generate_master_secret ( tls );
+
+       /* Generate keys */
+       if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
+               DBGC ( tls, "TLS %p could not generate keys: %s\n",
+                      tls, strerror ( rc ) );
+               return rc;
+       }
+
        /* Encrypt pre-master secret using server's public key */
        memset ( &key_xchg, 0, sizeof ( key_xchg ) );
        len = pubkey_encrypt ( pubkey, cipherspec->pubkey_ctx,
@@ -1622,7 +1632,7 @@ static int tls_new_server_hello ( struct tls_connection *tls,
        if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 )
                return rc;
 
-       /* Reuse or generate master secret */
+       /* Check session ID */
        if ( hello_a->session_id_len &&
             ( hello_a->session_id_len == tls->session_id_len ) &&
             ( memcmp ( session_id, tls->session_id,
@@ -1631,12 +1641,11 @@ static int tls_new_server_hello ( struct tls_connection *tls,
                /* Session ID match: reuse master secret */
                DBGC ( tls, "TLS %p resuming session ID:\n", tls );
                DBGC_HDA ( tls, 0, tls->session_id, tls->session_id_len );
+               if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
+                       return rc;
 
        } else {
 
-               /* Generate new master secret */
-               tls_generate_master_secret ( tls );
-
                /* Record new session ID, if present */
                if ( hello_a->session_id_len &&
                     ( hello_a->session_id_len <= sizeof ( tls->session_id ))){
@@ -1649,10 +1658,6 @@ static int tls_new_server_hello ( struct tls_connection *tls,
                }
        }
 
-       /* Generate keys */
-       if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
-               return rc;
-
        /* Handle secure renegotiation */
        if ( tls->secure_renegotiation ) {