Only CA certificates can be self-issued
authorViktor Dukhovni <openssl-users@dukhovni.org>
Fri, 5 Oct 2018 03:53:01 +0000 (23:53 -0400)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Thu, 18 Oct 2018 04:07:27 +0000 (00:07 -0400)
At the bottom of https://tools.ietf.org/html/rfc5280#page-12 and
top of https://tools.ietf.org/html/rfc5280#page-13 (last paragraph
of above https://tools.ietf.org/html/rfc5280#section-3.3), we see:

   This specification covers two classes of certificates: CA
   certificates and end entity certificates.  CA certificates may be
   further divided into three classes: cross-certificates, self-issued
   certificates, and self-signed certificates.  Cross-certificates are
   CA certificates in which the issuer and subject are different
   entities.  Cross-certificates describe a trust relationship between
   the two CAs.  Self-issued certificates are CA certificates in which
   the issuer and subject are the same entity.  Self-issued certificates
   are generated to support changes in policy or operations.  Self-
   signed certificates are self-issued certificates where the digital
   signature may be verified by the public key bound into the
   certificate.  Self-signed certificates are used to convey a public
   key for use to begin certification paths.  End entity certificates
   are issued to subjects that are not authorized to issue certificates.

that the term "self-issued" is only applicable to CAs, not end-entity
certificates.  In https://tools.ietf.org/html/rfc5280#section-4.2.1.9
the description of path length constraints says:

   The pathLenConstraint field is meaningful only if the cA boolean is
   asserted and the key usage extension, if present, asserts the
   keyCertSign bit (Section 4.2.1.3).  In this case, it gives the
   maximum number of non-self-issued intermediate certificates that may
   follow this certificate in a valid certification path.  (Note: The
   last certificate in the certification path is not an intermediate
   certificate, and is not included in this limit.  Usually, the last
   certificate is an end entity certificate, but it can be a CA
   certificate.)

This makes it clear that exclusion of self-issued certificates from
the path length count applies only to some *intermediate* CA
certificates.  A leaf certificate whether it has identical issuer
and subject or whether it is a CA or not is never part of the
intermediate certificate count.  The handling of all leaf certificates
must be the same, in the case of our code to post-increment the
path count by 1, so that we ultimately reach a non-self-issued
intermediate it will be the first one (not zeroth) in the chain
of intermediates.

Reviewed-by: Matt Caswell <matt@openssl.org>
crypto/x509/x509_vfy.c

index 3a60d412daf86e94232111ff8e8f773d0f70ef37..2ecdb48f14a00b58cbf1f6f1e14cbd97eb763a97 100644 (file)
@@ -524,8 +524,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
             if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
                 return 0;
         }
             if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
                 return 0;
         }
-        /* Increment path length if not self issued */
-        if (!(x->ex_flags & EXFLAG_SI))
+        /* Increment path length if not a self issued intermediate CA */
+        if (i == 0 || (x->ex_flags & EXFLAG_SI) == 0)
             plen++;
         /*
          * If this certificate is a proxy certificate, the next certificate
             plen++;
         /*
          * If this certificate is a proxy certificate, the next certificate