summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2025-10-12 23:29:33 +0200
committerMichael Brown2025-10-13 00:25:09 +0200
commit57504353febc61533e637f16ec6f933870b68ec9 (patch)
tree98c1ccbb43ae0e1d5435047ad13f7ae4cbc1936b
parent[tls] Add support for the Extended Master Secret (diff)
downloadipxe-57504353febc61533e637f16ec6f933870b68ec9.tar.gz
ipxe-57504353febc61533e637f16ec6f933870b68ec9.tar.xz
ipxe-57504353febc61533e637f16ec6f933870b68ec9.zip
[tls] Refuse to resume sessions with mismatched master secret methods
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>
-rw-r--r--src/include/ipxe/tls.h2
-rw-r--r--src/net/tls.c13
2 files changed, 15 insertions, 0 deletions
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index 658a008f8..8ddc9c1be 100644
--- a/src/include/ipxe/tls.h
+++ b/src/include/ipxe/tls.h
@@ -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;
diff --git a/src/net/tls.c b/src/net/tls.c
index 8f91da018..efecf368c 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -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;