Commit 1e0643bef1 for strongswan.org

commit 1e0643bef105704337efc141a37dfcfbaa53cb1f
Author: Tobias Brunner <tobias@strongswan.org>
Date:   Fri Mar 20 17:38:07 2026 +0100

    tls-server: Only accept non-empty ECDH public keys with TLS < 1.3

    This prevents a crash due to a null-pointer dereference when processing
    an empty ECDH public key.

    The previous length check only applied in the `!ec` case, so in the `ec`
    case, the access to `pub.ptr[0]` was unguarded.  If a crafted TLS
    record ends with an empty ClientKeyExchange, then `read_data8` sets
    `pub` to `chunk_empty`, causing a null-pointer dereference.

    Note that if some data follows the empty ClientKeyExchange, this just
    causes a 1-byte out-of-bounds read that has no further effect as the
    TLS session is aborted immediately.  Either because the read value
    doesn't equal TLS_ANSI_UNCOMPRESSED or because the empty public key
    is rejected by `set_public_key()`.

    The referenced commit that introduced the pointer access, added the
    check for `pub.len` specifically to the `!ec` case, while the pointer
    access was initially unconditional (probably because the code was just
    copied from `tls_peer.c` which processes ECDH public keys in a separate
    function, so there was no `ec` flag).  The latter was fixed a couple of
    days later with 7b3c01845f63 ("Read the compression type byte for EC
    groups, only").  However, that commit didn't change the length check.
    Anyway, it's possible that the original intention was to add the check
    to the `ec` case on the previous line, or that there was some confusion
    with the parenthesis and something like the current code was intended to
    begin with.

    Fixes: e6cce7ff0d1b ("Prepend point format to ECDH public key")
    Fixes: CVE-2026-35332

diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c
index fc767c0fad..60fbcd2ea6 100644
--- a/src/libtls/tls_server.c
+++ b/src/libtls/tls_server.c
@@ -862,7 +862,7 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this,
 	group = this->dh->get_method(this->dh);
 	ec = key_exchange_is_ecdh(group);
 	if ((ec && !reader->read_data8(reader, &pub)) ||
-		(!ec && (!reader->read_data16(reader, &pub) || pub.len == 0)))
+		(!ec && !reader->read_data16(reader, &pub)) || pub.len == 0)
 	{
 		DBG1(DBG_TLS, "received invalid Client Key Exchange");
 		this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);