crypto/x509: allow setting MaxPathLen to -1 without IsCA

This fixes a bug in CL 228777 which disallowed
a MaxPathLen of -1 without IsCA, even though the
x509.Certificate documentation indicates that
MaxPathLen of -1 is considered "unset".

Updates #38216

Change-Id: Ib7240e00408d060f27567be8b820d0eee239256f
Reviewed-on: https://go-review.googlesource.com/c/go/+/235280
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index ecf4407..288c9c6 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -2100,7 +2100,7 @@
 		return nil, errors.New("x509: no SerialNumber given")
 	}
 
-	if template.BasicConstraintsValid && !template.IsCA && (template.MaxPathLen != 0 || template.MaxPathLenZero) {
+	if template.BasicConstraintsValid && !template.IsCA && template.MaxPathLen != -1 && (template.MaxPathLen != 0 || template.MaxPathLenZero) {
 		return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen")
 	}
 
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index 7e00147..0141021 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -1674,11 +1674,15 @@
 		BasicConstraintsValid: true,
 		IsCA:                  false,
 	}
-	cert := serialiseAndParse(t, template)
-	if m := cert.MaxPathLen; m != -1 {
+	if m := serialiseAndParse(t, template).MaxPathLen; m != -1 {
 		t.Errorf("MaxPathLen should be -1 when IsCa is false, got %d", m)
 	}
 
+	template.MaxPathLen = -1
+	if m := serialiseAndParse(t, template).MaxPathLen; m != -1 {
+		t.Errorf("MaxPathLen should be -1 when IsCa is false and MaxPathLen set to -1, 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")
@@ -1691,8 +1695,7 @@
 	}
 
 	template.BasicConstraintsValid = false
-	cert2 := serialiseAndParse(t, template)
-	if m := cert2.MaxPathLen; m != 0 {
+	if m := serialiseAndParse(t, template).MaxPathLen; m != 0 {
 		t.Errorf("Bad MaxPathLen should be ignored if BasicConstraintsValid is false, got %d", m)
 	}
 }