File strongswan-CVE-2022-40617.patch of Package strongswan.29076
@@ -, +, @@
basic trust chain validation
using certificate "CN=www.strongswan.org"
using trusted intermediate ca certificate "C=US, O=Let's Encrypt, CN=R3"
using trusted ca certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
reached self-signed root ca with a path length of 1
requesting ocsp status from 'http://r3.o.lencr.org' ...
ocsp response correctly signed by "C=US, O=Let's Encrypt, CN=R3"
ocsp response is valid: until Jul 27 12:59:58 2022
fetching crl from 'http://x1.c.lencr.org/' ...
using trusted certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
crl correctly signed by "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
crl is valid: until Apr 18 01:59:59 2023
using certificate "CN=www.strongswan.org"
using trusted intermediate ca certificate "C=US, O=Let's Encrypt, CN=R3"
requesting ocsp status from 'http://r3.o.lencr.org' ...
ocsp response correctly signed by "C=US, O=Let's Encrypt, CN=R3"
ocsp response is valid: until Jul 27 12:59:58 2022
using trusted ca certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
fetching crl from 'http://x1.c.lencr.org/' ...
using trusted certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
crl correctly signed by "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
crl is valid: until Apr 18 01:59:59 2023
reached self-signed root ca with a path length of 1
---
.../credentials/credential_manager.c | 54 +++++++++++++++----
1 file changed, 45 insertions(+), 9 deletions(-)
Index: strongswan-5.1.3/src/libstrongswan/credentials/credential_manager.c
===================================================================
--- strongswan-5.1.3.orig/src/libstrongswan/credentials/credential_manager.c
+++ strongswan-5.1.3/src/libstrongswan/credentials/credential_manager.c
@@ -549,7 +549,7 @@ static void cache_queue(private_credenti
*/
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;
@@ -564,7 +564,7 @@ static bool check_lifetime(private_crede
continue;
}
status = validator->check_lifetime(validator, cert,
- pathlen, trusted, auth);
+ pathlen, anchor, auth);
if (status != NEED_MORE)
{
break;
@@ -597,13 +597,13 @@ static bool check_lifetime(private_crede
*/
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;
}
@@ -616,7 +616,7 @@ static bool check_certificate(private_cr
continue;
}
if (!validator->validate(validator, subject, issuer,
- online, pathlen, trusted, auth))
+ online, pathlen, anchor, auth))
{
enumerator->destroy(enumerator);
return FALSE;
@@ -716,6 +716,7 @@ static bool verify_trust_chain(private_c
auth_cfg_t *auth;
signature_scheme_t scheme;
int pathlen;
+ bool is_anchor = FALSE;
auth = auth_cfg_create();
get_key_strength(subject, auth);
@@ -733,7 +734,7 @@ static bool verify_trust_chain(private_c
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
{
@@ -766,11 +767,18 @@ static bool verify_trust_chain(private_c
DBG1(DBG_CFG, "no issuer certificate found for \"%Y\"",
current->get_subject(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);
@@ -782,7 +790,7 @@ static bool verify_trust_chain(private_c
}
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);
@@ -795,6 +803,34 @@ static bool verify_trust_chain(private_c
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);