mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-05-28 04:03:29 -04:00
tls-crypt-v2: Avoid interpreting opcode as part of WKc
The buffer we pass to tls_crypt_v2_extract_client_key contains the
entire received control channel packet. We should skip the opcode before
trying to read WKC.
This logic error is a second bug behind the XlabAI finding, next too the
too-strict ASSERT in tls_crypt_unwrap.
Also remove a too strict ASSERT in tls_crypt_unwrap. We already check
a few lines later for a too short packet and return a proper error
("packet too short").
XlabAI found a way of triggering this ASSERT that requires a tls-crypt-v2
client key that has a specific property (a specific byte need to have a
specific value, about 1/256 probability). If an attacker can get hold of
such a tls-crypt-v2 client key or observe a handshake using such a key,
the attacker can trigger the ASSERT, crashing the server. Setups that do
not use tls-crypt-v2 are not affected.
Independently, Cisco Talos reported a way to trigger this ASSERT with any
tls-crypt-v2 key but this requires the attacker to be also in possession
of the private key part of the tls-crypt-v2 client key or to inject packet
into a live session of a client session.
CVE: 2026-35058
Reported-By: XlabAI Team of Tencent Xuanwu Lab (xlabai@tencent.com)
Reported-By: Guannan Wang (wgnbuaa@gmail.com
Reported-By: Zhanpeng Liu (pkugenuine@gmail.com)
Reported-By: Guancheng Li (lgcpku@gmail.com)
Reported-By: Emma Reuter of Cisco ASIG (TALOS-2026-2381)
Signed-off-by: Steffan Karger <steffan@karger.me>
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Change-Id: I623733c0476c98f436d19009ee8990693c1579b5
Private-URL: https://github.com/OpenVPN/openvpn-private-issues/issues/111
Acked-by: Gert Doering <gert@greenie.muc.de>
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 18270324a5fd43122ca1b8c29b224c5dd5905429)
This commit is contained in:
parent
bac8be0761
commit
607e2fcb9c
2 changed files with 12 additions and 3 deletions
|
|
@ -216,7 +216,6 @@ tls_crypt_unwrap(const struct buffer *src, struct buffer *dst, struct crypto_opt
|
|||
gc_init(&gc);
|
||||
|
||||
ASSERT(opt);
|
||||
ASSERT(src->len > 0);
|
||||
ASSERT(ctx->cipher);
|
||||
ASSERT(packet_id_initialized(&opt->packet_id) || (opt->flags & CO_IGNORE_PACKET_ID));
|
||||
|
||||
|
|
@ -619,7 +618,8 @@ tls_crypt_v2_extract_client_key(struct buffer *buf, struct tls_wrap_ctx *ctx,
|
|||
struct buffer wrapped_client_key = *buf;
|
||||
uint16_t net_len = 0;
|
||||
|
||||
if (BLEN(&wrapped_client_key) < sizeof(net_len))
|
||||
if (!buf_advance(&wrapped_client_key, 1)
|
||||
|| BLEN(&wrapped_client_key) < 1 + sizeof(net_len))
|
||||
{
|
||||
msg(D_TLS_ERRORS, "Can not read tls-crypt-v2 client key length");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -518,7 +518,16 @@ tls_crypt_v2_wrap_unwrap_max_metadata(void **state)
|
|||
.mode = TLS_WRAP_CRYPT,
|
||||
.tls_crypt_v2_server_key = ctx->server_keys.encrypt,
|
||||
};
|
||||
assert_true(tls_crypt_v2_extract_client_key(&ctx->wkc, &wrap_ctx, NULL, true));
|
||||
|
||||
/* a buffer that only contains the wrapped key should fail */
|
||||
assert_false(tls_crypt_v2_extract_client_key(&ctx->wkc, &wrap_ctx, NULL, true));
|
||||
|
||||
/* add a opcode in front of the key to make it valid to extract */
|
||||
struct buffer wkcop = alloc_buf_gc(buf_len(&ctx->wkc) + 1, &ctx->gc);
|
||||
buf_write_u8(&wkcop, 0x50);
|
||||
buf_copy(&wkcop, &ctx->wkc);
|
||||
assert_true(tls_crypt_v2_extract_client_key(&wkcop, &wrap_ctx, NULL, true));
|
||||
|
||||
tls_wrap_free(&wrap_ctx);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue