From e4b4aabc4996fc61c37deab7858d07bc4d220136 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 2 Feb 2022 18:39:20 +0100 Subject: [PATCH] libtls: Enforce client/server identity when looking for public key The client already enforces that the server identity is contained in the received certificate. But on the server, the referenced commit changed the lookup from the configured (or adopted if %any was configured) client identity to the subject DN of the received client certificate. So any client with a trusted certificate was accepted. Fixes: d2fc9b0961c6 ("tls-server: Mutual authentication support for TLS 1.3") Fixes: CVE-2022-4967 Closes strongswan/strongswan#873 --- src/libtls/tls_peer.c | 10 +++++----- src/libtls/tls_server.c | 7 +++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index f3854eba5265..58a36dbd2d55 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -165,7 +165,7 @@ struct private_tls_peer_t { /* Implemented in tls_server.c */ bool tls_write_key_share(bio_writer_t **key_share, diffie_hellman_t *dh); -public_key_t *tls_find_public_key(auth_cfg_t *peer_auth); +public_key_t *tls_find_public_key(auth_cfg_t *peer_auth, identification_t *id); /** * Verify the DH group/key type requested by the server is valid. @@ -641,7 +641,7 @@ static status_t process_cert_verify(private_tls_peer_t *this, public_key_t *public; chunk_t msg; - public = tls_find_public_key(this->server_auth); + public = tls_find_public_key(this->server_auth, this->server); if (!public) { DBG1(DBG_TLS, "no trusted certificate found for '%Y' to verify TLS server", @@ -690,7 +690,7 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this, this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - public = tls_find_public_key(this->server_auth); + public = tls_find_public_key(this->server_auth, this->server); if (!public) { DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server); @@ -797,7 +797,7 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this, return NEED_MORE; } - public = tls_find_public_key(this->server_auth); + public = tls_find_public_key(this->server_auth, this->server); if (!public) { DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server); @@ -1621,7 +1621,7 @@ static status_t send_key_exchange_encrypt(private_tls_peer_t *this, return NEED_MORE; } - public = tls_find_public_key(this->server_auth); + public = tls_find_public_key(this->server_auth, this->server); if (!public) { DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server); diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index bbfe542496c3..4efe04e08286 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -173,7 +173,7 @@ struct private_tls_server_t { /** * Find a trusted public key to encrypt/verify key exchange data */ -public_key_t *tls_find_public_key(auth_cfg_t *peer_auth) +public_key_t *tls_find_public_key(auth_cfg_t *peer_auth, identification_t *id) { public_key_t *public = NULL, *current; certificate_t *cert, *found; @@ -184,8 +184,7 @@ public_key_t *tls_find_public_key(auth_cfg_t *peer_auth) if (cert) { enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, - KEY_ANY, cert->get_subject(cert), - peer_auth, TRUE); + KEY_ANY, id, peer_auth, TRUE); while (enumerator->enumerate(enumerator, ¤t, &auth)) { found = auth->get(auth, AUTH_RULE_SUBJECT_CERT); @@ -923,7 +922,7 @@ static status_t process_cert_verify(private_tls_server_t *this, public_key_t *public; chunk_t msg; - public = tls_find_public_key(this->peer_auth); + public = tls_find_public_key(this->peer_auth, this->peer); if (!public) { DBG1(DBG_TLS, "no trusted certificate found for '%Y' to verify TLS peer", -- 2.34.1