Skip to content

crypto/x509: NameConstraintsWithoutSANs when checking signing certificate #24151

@thsnr

Description

@thsnr

What did you do?

A CA which issues personal signing certificates has specified X.509 Name Constraints to exclude any DNS names and IP addresses:

X509v3 Name Constraints:
    Excluded:
      DNS:""
      IP:0.0.0.0/0.0.0.0
      IP:0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0

This is good practice to protect against misissued certificates.

Attempt to verify a test certificate issued by that CA: https://play.golang.org/p/y4l1JJqDQPs

What did you expect to see?

I expected the verification to succeed as it did in go 1.9 and earlier.

What did you see instead?

Starting from go 1.10, verification fails with NameConstraintsWithoutSANs:

x509: issuer has name constraints but leaf doesn't have a SAN extension

It is true that the signing certificates do not contain SAN extensions, because they have no need for one. This error did not trigger before, because when verifying a signing certificate, no DNS name is specified. But as stated in the change log for go 1.10:

Certificate.Verify now enforces the name constraints for all names contained in the certificate, not just the one name that a client has asked about.

I believe this is a bug, because RFC 5280 Section 4.2.1.10 regarding Name Constraints states:

Restrictions apply only when the specified name form is present. If no name of the type is in the certificate, the certificate is acceptable.

I understand this behavior is there for cases where we encounter a legacy TLS server certificate which relies on the Common Name as the hostname, but other certificates are now also hit by this. Maybe Certificate.Verify should distinguish between TLS server certificates and other X.509 certificates and have NameConstraintsWithoutSANs only trigger for the first ones?

Does this issue reproduce with the latest release (go1.10)?

Yes, go 1.10 is where it was introduced.

System details

go version go1.10rc2 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/tiit/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/tiit/go"
GORACE=""
GOROOT="/usr/lib/go-1.10"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.10/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build045278460=/tmp/go-build -gno-record-gcc-switches"
GOROOT/bin/go version: go version go1.10rc2 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.10rc2
uname -sr: Linux 4.14.0-3-amd64
Distributor ID:	Debian
Description:	Debian GNU/Linux testing (buster)
Release:	testing
Codename:	buster
/lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Debian GLIBC 2.26-6) stable release version 2.26, by Roland McGrath et al.
gdb --version: GNU gdb (Debian 7.12-6+b1) 7.12.0.20161007-git

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