Upstream-Status: Backport from 
https://download.strongswan.org/security/CVE-2022-40617

Affects "strongswan < 5.9.8"

Signed-off-by: Hitendra Prajapati <hprajap...@mvista.com>
---
 .../strongswan/files/CVE-2022-40617.patch     | 157 ++++++++++++++++++
 .../strongswan/strongswan_5.9.6.bb            |   1 +
 2 files changed, 158 insertions(+)
 create mode 100644 
meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch

diff --git 
a/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch 
b/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch
new file mode 100644
index 000000000..ffef6800e
--- /dev/null
+++ b/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch
@@ -0,0 +1,157 @@
+From 6a6c275534e31b41f6d203cfd92685b7526a45e8 Mon Sep 17 00:00:00 2001
+From: Hitendra Prajapati <hprajap...@mvista.com>
+Date: Fri, 11 Nov 2022 10:15:38 +0530
+Subject: [PATCH] CVE-2022-40617
+
+Upstream-Status: Backport 
[https://download.strongswan.org/security/CVE-2022-40617]
+CVE: CVE-2022-40617
+Signed-off-by: Hitendra Prajapati <hprajap...@mvista.com>
+
+credential-manager: Do online revocation checks only after
+ basic trust chain validation
+
+This avoids querying URLs of potentially untrusted certificates, e.g. if
+an attacker sends a specially crafted end-entity and intermediate CA
+certificate with a CDP that points to a server that completes the
+TCP handshake but then does not send any further data, which will block
+the fetcher thread (depending on the plugin) for as long as the default
+timeout for TCP.  Doing that multiple times will block all worker threads,
+leading to a DoS attack.
+
+The logging during the certificate verification obviously changes.
+---
+ .../credentials/credential_manager.c          | 54 +++++++++++++++----
+ 1 file changed, 45 insertions(+), 9 deletions(-)
+
+diff --git a/src/libstrongswan/credentials/credential_manager.c 
b/src/libstrongswan/credentials/credential_manager.c
+index 3be0190..f65372b 100644
+--- a/src/libstrongswan/credentials/credential_manager.c
++++ b/src/libstrongswan/credentials/credential_manager.c
+@@ -555,7 +555,7 @@ static void cache_queue(private_credential_manager_t *this)
+  */
+ static bool check_lifetime(private_credential_manager_t *this,
+                                                  certificate_t *cert, char 
*label,
+-                                                 int pathlen, bool trusted, 
auth_cfg_t *auth)
++                                                 int pathlen, bool anchor, 
auth_cfg_t *auth)
+ {
+       time_t not_before, not_after;
+       cert_validator_t *validator;
+@@ -570,7 +570,7 @@ static bool check_lifetime(private_credential_manager_t 
*this,
+                       continue;
+               }
+               status = validator->check_lifetime(validator, cert,
+-                                                                              
   pathlen, trusted, auth);
++                                                                              
   pathlen, anchor, auth);
+               if (status != NEED_MORE)
+               {
+                       break;
+@@ -603,13 +603,13 @@ static bool check_lifetime(private_credential_manager_t 
*this,
+  */
+ static bool check_certificate(private_credential_manager_t *this,
+                               certificate_t *subject, certificate_t *issuer, 
bool online,
+-                              int pathlen, bool trusted, auth_cfg_t *auth)
++                              int pathlen, bool anchor, auth_cfg_t *auth)
+ {
+       cert_validator_t *validator;
+       enumerator_t *enumerator;
+ 
+       if (!check_lifetime(this, subject, "subject", pathlen, FALSE, auth) ||
+-              !check_lifetime(this, issuer, "issuer", pathlen + 1, trusted, 
auth))
++              !check_lifetime(this, issuer, "issuer", pathlen + 1, anchor, 
auth))
+       {
+               return FALSE;
+       }
+@@ -622,7 +622,7 @@ static bool check_certificate(private_credential_manager_t 
*this,
+                       continue;
+               }
+               if (!validator->validate(validator, subject, issuer,
+-                                                               online, 
pathlen, trusted, auth))
++                                                               online, 
pathlen, anchor, auth))
+               {
+                       enumerator->destroy(enumerator);
+                       return FALSE;
+@@ -725,6 +725,7 @@ static bool 
verify_trust_chain(private_credential_manager_t *this,
+       auth_cfg_t *auth;
+       signature_params_t *scheme;
+       int pathlen;
++      bool is_anchor = FALSE;
+ 
+       auth = auth_cfg_create();
+       get_key_strength(subject, auth);
+@@ -742,7 +743,7 @@ static bool 
verify_trust_chain(private_credential_manager_t *this,
+                               auth->add(auth, AUTH_RULE_CA_CERT, 
issuer->get_ref(issuer));
+                               DBG1(DBG_CFG, "  using trusted ca certificate 
\"%Y\"",
+                                                         
issuer->get_subject(issuer));
+-                              trusted = TRUE;
++                              trusted = is_anchor = TRUE;
+                       }
+                       else
+                       {
+@@ -777,11 +778,18 @@ static bool 
verify_trust_chain(private_credential_manager_t *this,
+                               DBG1(DBG_CFG, "  issuer is \"%Y\"",
+                                        current->get_issuer(current));
+                               call_hook(this, CRED_HOOK_NO_ISSUER, current);
++                              if (trusted)
++                              {
++                                      DBG1(DBG_CFG, "  reached end of 
incomplete trust chain for "
++                                               "trusted certificate \"%Y\"",
++                                               subject->get_subject(subject));
++                              }
+                               break;
+                       }
+               }
+-              if (!check_certificate(this, current, issuer, online,
+-                                                         pathlen, trusted, 
auth))
++              /* don't do online verification here */
++              if (!check_certificate(this, current, issuer, FALSE,
++                                                         pathlen, is_anchor, 
auth))
+               {
+                       trusted = FALSE;
+                       issuer->destroy(issuer);
+@@ -793,7 +801,7 @@ static bool 
verify_trust_chain(private_credential_manager_t *this,
+               }
+               current->destroy(current);
+               current = issuer;
+-              if (trusted)
++              if (is_anchor)
+               {
+                       DBG1(DBG_CFG, "  reached self-signed root ca with a "
+                                "path length of %d", pathlen);
+@@ -806,6 +814,34 @@ static bool 
verify_trust_chain(private_credential_manager_t *this,
+               DBG1(DBG_CFG, "maximum path length of %d exceeded", 
MAX_TRUST_PATH_LEN);
+               call_hook(this, CRED_HOOK_EXCEEDED_PATH_LEN, subject);
+       }
++      else if (trusted && online)
++      {
++              enumerator_t *enumerator;
++              auth_rule_t rule;
++
++              /* do online revocation checks after basic validation of the 
chain */
++              pathlen = 0;
++              current = subject;
++              enumerator = auth->create_enumerator(auth);
++              while (enumerator->enumerate(enumerator, &rule, &issuer))
++              {
++                      if (rule == AUTH_RULE_CA_CERT || rule == 
AUTH_RULE_IM_CERT)
++                      {
++                              if (!check_certificate(this, current, issuer, 
TRUE, pathlen++,
++                                                                         rule 
== AUTH_RULE_CA_CERT, auth))
++                              {
++                                      trusted = FALSE;
++                                      break;
++                              }
++                              else if (rule == AUTH_RULE_CA_CERT)
++                              {
++                                      break;
++                              }
++                              current = issuer;
++                      }
++              }
++              enumerator->destroy(enumerator);
++      }
+       if (trusted)
+       {
+               result->merge(result, auth, FALSE);
+-- 
+2.25.1
+
diff --git a/meta-networking/recipes-support/strongswan/strongswan_5.9.6.bb 
b/meta-networking/recipes-support/strongswan/strongswan_5.9.6.bb
index 1b82dceac..b8d44db26 100644
--- a/meta-networking/recipes-support/strongswan/strongswan_5.9.6.bb
+++ b/meta-networking/recipes-support/strongswan/strongswan_5.9.6.bb
@@ -10,6 +10,7 @@ DEPENDS:append = "${@bb.utils.contains('DISTRO_FEATURES', 
'tpm2', '  tpm2-tss',
 
 SRC_URI = "http://download.strongswan.org/strongswan-${PV}.tar.bz2 \
            file://0001-enum-Fix-compiler-warning.patch \
+           file://CVE-2022-40617.patch \
            "
 
 SRC_URI[sha256sum] = 
"91d0978ac448912759b85452d8ff0d578aafd4507aaf4f1c1719f9d0c7318ab7"
-- 
2.25.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#99552): 
https://lists.openembedded.org/g/openembedded-devel/message/99552
Mute This Topic: https://lists.openembedded.org/mt/94953155/21656
Group Owner: openembedded-devel+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to