From 95dbd5c8580ad14db951535e0bfedcf9ed713eb2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 8 Jan 2025 13:51:21 +0100 Subject: [PATCH] constraints: Exclude self-signed root CAs without policies from policy validation Self-signed trust anchors are not part of the certificate path validation according to RFC 8280, section 6.1: When the trust anchor is provided in the form of a self-signed certificate, this self-signed certificate is not included as part of the prospective certification path. But policies in them could still be used, as stated in section 6.2: Where a CA distributes self-signed certificates to specify trust anchor information, certificate extensions can be used to specify recommended inputs to path validation. For example, a policy constraints extension could be included in the self-signed certificate to indicate that paths beginning with this trust anchor should be trusted only for the specified policies. [...] Implementations that use self-signed certificates to specify trust anchor information are free to process or ignore such information. So unconditionally enforcing that self-signed root certificates contain the policies is probably too strict. Often they won't contain the extension at all. With this change, we allow that but still enforce the policies in case such a certificate contains them. The other policy-related constraints are also enforced still should they be contained. Closes strongswan/strongswan#2601 --- .../plugins/constraints/constraints_validator.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/plugins/constraints/constraints_validator.c b/src/libstrongswan/plugins/constraints/constraints_validator.c index 27bdb8943..51c10576c 100644 --- a/src/libstrongswan/plugins/constraints/constraints_validator.c +++ b/src/libstrongswan/plugins/constraints/constraints_validator.c @@ -936,8 +936,19 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen, if (valid) { - x509 = (x509_t*)subject; + /* remove the self-signed root certificate from the chain if it + * does not contain any certificate policies, in accordance with + * RFC 5280, sections 6.1 and 6.2 */ + x509 = (x509_t*)issuer; + enumerator = x509->create_cert_policy_enumerator(x509); + if ((x509->get_flags(x509) & X509_SELF_SIGNED) && + !enumerator->enumerate(enumerator, &policy)) + { + chain->remove_last(chain, (void**)&x509); + } + enumerator->destroy(enumerator); + x509 = (x509_t*)subject; enumerator = x509->create_cert_policy_enumerator(x509); while (enumerator->enumerate(enumerator, &policy)) {