Skip to content

crypto/x509: Certificate.Verify does not enforce name constraints correctly #59171

Description

@rittneje

In Go 1.19, Certificate.Verify was changed to also enforce name constraints on non-leaf certificates. https://tip.golang.org/doc/go1.19#crypto/x509

However, as per the source code, this is enforced by saying that if certificate X has a name constraint, then it gets enforced on both (and only) the leaf and certificate X. This violates RFC 5280 section 4.2.1.10:

The name constraints extension, which MUST be used only in a CA
certificate, indicates a name space within which all subject names in
subsequent certificates in a certification path MUST be located.
Restrictions apply to the subject distinguished name and apply to
subject alternative names. Restrictions apply only when the
specified name form is present. If no name of the type is in the
certificate, the certificate is acceptable.

Note that the RFC clearly says "subsequent certificates", which means that enforcing a certificate's name constraints on itself is incorrect. In addition, Go is not enforcing the name constraints on the subsequent intermediate certificates in the chain, which also violates the RFC.

As an example, here we have a root certificate with a name constraint for "example.com", an intermediate certificate with a SAN of "www.sample.com", and a leaf certificate with a SAN of "www.example.com". This should be rejected due to the invalid intermediate SAN, but is accepted. https://go.dev/play/p/Ozj9G8lZaD6

In this example, we have a root certificate with a name constraint for "example.com" and a SAN of "foobar.com", an intermediate certificate with no SANs, and a leaf certificate with a SAN of "www.example.com". This should be accepted because the root name constraint is not supposed to apply to itself, but is rejected. https://go.dev/play/p/eeq2mE4Dzby

Note that OpenSSL properly follows the RFC in both cases. (That is, it properly rejects the first example, and properly accepts the second example.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions