From 141b11d5a12f8bdf4825227db70e2a4309906ae9 Mon Sep 17 00:00:00 2001 From: Katie Hockman Date: Fri, 17 Apr 2020 10:23:07 -0400 Subject: [PATCH] crypto/x509: disallow setting MaxPathLen without IsCA Fixes #38216 Change-Id: I3222abe2153abb4cbfa65a4825c153ce128f56a0 Reviewed-on: https://go-review.googlesource.com/c/go/+/228777 TryBot-Result: Gobot Gobot Reviewed-by: Filippo Valsorda --- src/crypto/x509/x509.go | 4 ++++ src/crypto/x509/x509_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go index 6d03a129f8..ecf44071cf 100644 --- a/src/crypto/x509/x509.go +++ b/src/crypto/x509/x509.go @@ -2100,6 +2100,10 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv return nil, errors.New("x509: no SerialNumber given") } + if template.BasicConstraintsValid && !template.IsCA && (template.MaxPathLen != 0 || template.MaxPathLenZero) { + return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen") + } + hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm) if err != nil { return nil, err diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index bbb1f8d4f1..05bade5a8f 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -1645,6 +1645,41 @@ func serialiseAndParse(t *testing.T, template *Certificate) *Certificate { return cert } +func TestMaxPathLenNotCA(t *testing.T) { + template := &Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: "Σ Acme Co", + }, + NotBefore: time.Unix(1000, 0), + NotAfter: time.Unix(100000, 0), + + BasicConstraintsValid: true, + IsCA: false, + } + cert := serialiseAndParse(t, template) + if m := cert.MaxPathLen; m != -1 { + t.Errorf("MaxPathLen should be -1 when IsCa is false, got %d", m) + } + + template.MaxPathLen = 5 + if _, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey); err == nil { + t.Error("specifying a MaxPathLen when IsCA is false should fail") + } + + template.MaxPathLen = 0 + template.MaxPathLenZero = true + if _, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey); err == nil { + t.Error("setting MaxPathLenZero when IsCA is false should fail") + } + + template.BasicConstraintsValid = false + cert2 := serialiseAndParse(t, template) + if m := cert2.MaxPathLen; m != 0 { + t.Errorf("Bad MaxPathLen should be ignored if BasicConstraintsValid is false, got %d", m) + } +} + func TestMaxPathLen(t *testing.T) { template := &Certificate{ SerialNumber: big.NewInt(1), -- 2.50.0