Commit f1be37eac8 for openssl.org
commit f1be37eac8f6ee72fa5ff5832a469f28827c78dd
Author: Anuj Ramesh <37349553+anujramesh@users.noreply.github.com>
Date: Wed Apr 15 14:02:05 2026 -0400
Fix TLS 1.3 alert for missing key_share
Fixes #30818
Co-authored-by: Anuj Ramesh <37349553+anujramesh@users.noreply.github.com>
Assisted-by: Claude:claude-fable-5
Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Frederik Wedel-Heinen <fwh.openssl@gmail.com>
Merge-date: Wed Oct 21 16:29:21 2026
Merged-from: https://github.com/openssl/openssl/pull/32527
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index bc00da04d1..be2d52bb08 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 afd769c9b0..8a1e0c52d2 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