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
This commit is contained in:
Tobias Brunner
2025-01-09 13:51:11 +01:00
parent cc8c86c673
commit 95dbd5c858
@@ -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))
{