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
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))
{