From a3a2609b185ef1d321b69212ae3d78579ce7cc59 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 3 Jun 2026 00:26:18 +0200 Subject: [PATCH] F-5811: verify resumed cipher suite matches cached session On session-ID resumption the client only checked that the server's selected suite was in its offered list, not that it equaled the resumed session's suite, so a server could resume the session ID under a different cipher suite. Per RFC 5246 Section 7.4.1.2 / F.1.4 a resumed session reuses its negotiated suite; abort with a fatal illegal_parameter on mismatch. --- src/internal.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/internal.c b/src/internal.c index 04185f1ffd..317c4fed28 100644 --- a/src/internal.c +++ b/src/internal.c @@ -32279,6 +32279,25 @@ static void MakePSKPreMasterSecret(Arrays* arrays, byte use_psk_key) WOLFSSL_ERROR_VERBOSE(EXT_MASTER_SECRET_NEEDED_E); return EXT_MASTER_SECRET_NEEDED_E; } +#ifndef NO_RESUME_SUITE_CHECK + /* RFC 5246 Section 7.4.1.3: on resumption the ServerHello + * reuses the previously negotiated cipher suite. Reject a + * server that resumes the session but selects a different + * suite. Skipped for ticket resumption (suite is bound in the + * ticket), consistent with the EMS check above. */ + if ( + #ifdef HAVE_SESSION_TICKET + ssl->session->ticketLen == 0 && + #endif + (ssl->options.cipherSuite0 != ssl->session->cipherSuite0 || + ssl->options.cipherSuite != ssl->session->cipherSuite)) { + WOLFSSL_MSG("Resumed session cipher suite does not match " + "ServerHello cipher suite"); + SendAlert(ssl, alert_fatal, illegal_parameter); + WOLFSSL_ERROR_VERBOSE(MATCH_SUITE_ERROR); + return MATCH_SUITE_ERROR; + } +#endif /* NO_RESUME_SUITE_CHECK */ if (SetCipherSpecs(ssl) == 0) { if (!HaveUniqueSessionObj(ssl)) { WOLFSSL_MSG("Unable to have unique session object");