]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tls] Refuse to resume sessions with mismatched master secret methods
authorMichael Brown <mcb30@ipxe.org>
Sun, 12 Oct 2025 21:29:33 +0000 (22:29 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sun, 12 Oct 2025 22:25:09 +0000 (23:25 +0100)
RFC 7627 section 5.3 states that the client must abort the handshake
if the server attempts to resume a session where the master secret
calculation method stored in the session does not match the method
used for the connection being resumed.

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

index 658a008f85c715ab7030fb71e7407e1906d59bf6..8ddc9c1bed6f44c2dfa3e56f3d4134ece74b046f 100644 (file)
@@ -353,6 +353,8 @@ struct tls_session {
        size_t ticket_len;
        /** Master secret */
        uint8_t master_secret[48];
+       /** Extended master secret flag */
+       int extended_master_secret;
 
        /** List of connections */
        struct list_head conn;
index 8f91da0188dace249b0dadad90b0d095400c90f2..efecf368c180f1f2ac92fa296262e01996a44406 100644 (file)
@@ -183,6 +183,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define EINFO_EPERM_KEY_EXCHANGE                                       \
        __einfo_uniqify ( EINFO_EPERM, 0x06,                            \
                          "ServerKeyExchange verification failed" )
+#define EPERM_EMS __einfo_error ( EINFO_EPERM_EMS )
+#define EINFO_EPERM_EMS                                                        \
+       __einfo_uniqify ( EINFO_EPERM, 0x07,                            \
+                         "Extended master secret extension mismatch" )
 #define EPROTO_VERSION __einfo_error ( EINFO_EPROTO_VERSION )
 #define EINFO_EPROTO_VERSION                                           \
        __einfo_uniqify ( EINFO_EPROTO, 0x01,                           \
@@ -2243,6 +2247,14 @@ static int tls_new_server_hello ( struct tls_connection *tls,
                if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
                        return rc;
 
+               /* Ensure master secret generation method matches */
+               if ( tls->extended_master_secret !=
+                    tls->session->extended_master_secret ) {
+                       DBGC ( tls, "TLS %p mismatched extended master secret "
+                              "extension\n", tls );
+                       return -EPERM_EMS;
+               }
+
        } else {
 
                /* Record new session ID, if present */
@@ -2635,6 +2647,7 @@ static int tls_new_finished ( struct tls_connection *tls,
        if ( tls->session_id_len || tls->new_session_ticket_len ) {
                memcpy ( session->master_secret, tls->master_secret,
                         sizeof ( session->master_secret ) );
+               session->extended_master_secret = tls->extended_master_secret;
        }
        if ( tls->session_id_len ) {
                session->id_len = tls->session_id_len;