]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
constraints: Exclude self-signed root CAs without policies from policy validation
authorTobias Brunner <tobias@strongswan.org>
Wed, 8 Jan 2025 12:51:21 +0000 (13:51 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 9 Jan 2025 12:51:11 +0000 (13:51 +0100)
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

src/libstrongswan/plugins/constraints/constraints_validator.c

index 27bdb8943cf3e185b151ec785126320c77c9f350..51c10576c1292361ccdca18320b5d17f4e333005 100644 (file)
@@ -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))
                                {