diff options
| author | Anuj Ramesh <[email protected]> | 2026-04-15 20:02:05 +0200 |
|---|---|---|
| committer | Tomas Mraz <[email protected]> | 2026-10-21 18:27:38 +0200 |
| commit | f1be37eac8f6ee72fa5ff5832a469f28827c78dd (patch) | |
| tree | 12f7ad4eed352b7b3a7fab1efff44c78a59bee54 | |
| parent | ssl: handle session ID cache lock failure (diff) | |
| download | openssl-f1be37eac8f6ee72fa5ff5832a469f28827c78dd.tar.gz openssl-f1be37eac8f6ee72fa5ff5832a469f28827c78dd.zip | |
Fix TLS 1.3 alert for missing key_share
Fixes #30818
Co-authored-by: Anuj Ramesh <[email protected]>
Assisted-by: Claude:claude-fable-5
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Frederik Wedel-Heinen <[email protected]>
Merge-date: Wed Oct 21 16:29:21 2026
Merged-from: https://github.com/openssl/openssl/pull/32527
| -rw-r--r-- | ssl/statem/extensions.c | 14 | ||||
| -rw-r--r-- | test/recipes/70-test_key_share.t | 28 |
2 files changed, 37 insertions, 5 deletions
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index bc00da04d1a..be2d52bb085 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1732,14 +1732,20 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) */ if (!s->server && !sent) { - if ((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_NO_SUITABLE_KEY_SHARE); - return 0; - } + /* + * In a full handshake the ServerHello must carry a key_share, so its + * absence is a missing_extension alert (RFC 8446, sections 4.2.8 + * and 6.2). Only when resuming may the server legitimately omit it, + * and then only if we offered psk_ke. + */ if (!s->hit) { SSLfatal(s, SSL_AD_MISSING_EXTENSION, SSL_R_NO_SUITABLE_KEY_SHARE); return 0; } + if ((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_NO_SUITABLE_KEY_SHARE); + return 0; + } } /* * IF diff --git a/test/recipes/70-test_key_share.t b/test/recipes/70-test_key_share.t index afd769c9b06..8a1e0c52d2e 100644 --- a/test/recipes/70-test_key_share.t +++ b/test/recipes/70-test_key_share.t @@ -90,7 +90,7 @@ if (disabled("ec")) { $proxy->serverflags("-groups P-384"); } $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 25; +plan tests => 26; ok(TLSProxy::Message->success(), "Success after HRR"); #Test 2: The server sending an HRR requesting a group the client already sent @@ -345,6 +345,27 @@ SKIP: { ok(TLSProxy::Message->success(), "Large number of supported groups"); } +#Test 26: A ServerHello without a key_share in a full (non-resumption) +# handshake must fail with a missing_extension alert (RFC 8446 +# sections 4.2.8 and 6.2), not illegal_parameter +$proxy->clear(); +$direction = SERVER_TO_CLIENT; +$testtype = MISSING_EXTENSION; +$proxy->start(); +ok(is_missing_extension_client_alert(), + "Missing key_share in ServerHello gives missing_extension alert"); + +sub is_missing_extension_client_alert +{ + return 0 unless TLSProxy::Message->fail(); + + my $alert = TLSProxy::Message->alert(); + return 1 if !$alert->server() + && $alert->description() + == TLSProxy::Message::AL_DESC_MISSING_EXTENSION; + return 0; +} + sub modify_key_shares_filter { my $proxy = shift; @@ -517,6 +538,11 @@ sub modify_key_shares_filter $message->repack(); return; } + if ($testtype == MISSING_EXTENSION) { + $message->delete_extension(TLSProxy::Message::EXT_KEY_SHARE); + $message->repack(); + return; + } if ($testtype == SELECT_X25519) { $ext = pack "C4H64", 0x00, 0x1d, #x25519 |
