aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Langley <agl@golang.org>2018-01-10 13:59:51 -0800
committerAdam Langley <agl@golang.org>2018-01-11 16:47:29 +0000
commit4458a357ab819a612c0c4cafae88a65287254fe9 (patch)
tree35dd5eebea1ef568f5d7486ff62bea205a8f248e
parent6631f22776ab56f306bd00d44bc2e3b8d0b90585 (diff)
downloadgo-4458a357ab819a612c0c4cafae88a65287254fe9.tar.gz
go-4458a357ab819a612c0c4cafae88a65287254fe9.zip
crypto/x509: parse multiple URLs in a single CRLDP.
Previously we would only extract a single URL from a given CRLDP, but https://tools.ietf.org/html/rfc5280#section-4.2.1.13 permits multiple URLs for a single distribution point. Fixes #23403 Change-Id: I2eaed1537df02d0627db1b86bcd9c94506236bea Reviewed-on: https://go-review.googlesource.com/87299 Run-TryBot: Adam Langley <agl@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r--src/crypto/x509/x509.go24
-rw-r--r--src/crypto/x509/x509_test.go55
2 files changed, 64 insertions, 15 deletions
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 4c9182d902..86d9e82aca 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -984,7 +984,7 @@ type distributionPoint struct {
}
type distributionPointName struct {
- FullName asn1.RawValue `asn1:"optional,tag:0"`
+ FullName []asn1.RawValue `asn1:"optional,tag:0"`
RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
}
@@ -1466,20 +1466,14 @@ func parseCertificate(in *certificate) (*Certificate, error) {
for _, dp := range cdp {
// Per RFC 5280, 4.2.1.13, one of distributionPoint or cRLIssuer may be empty.
- if len(dp.DistributionPoint.FullName.Bytes) == 0 {
+ if len(dp.DistributionPoint.FullName) == 0 {
continue
}
- var n asn1.RawValue
- if _, err := asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n); err != nil {
- return nil, err
- }
- // Trailing data after the fullName is
- // allowed because other elements of
- // the SEQUENCE can appear.
-
- if n.Tag == 6 {
- out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes))
+ for _, fullName := range dp.DistributionPoint.FullName {
+ if fullName.Tag == 6 {
+ out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(fullName.Bytes))
+ }
}
}
@@ -1946,11 +1940,11 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId
var crlDp []distributionPoint
for _, name := range template.CRLDistributionPoints {
- rawFullName, _ := asn1.Marshal(asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)})
-
dp := distributionPoint{
DistributionPoint: distributionPointName{
- FullName: asn1.RawValue{Tag: 0, Class: 2, IsCompound: true, Bytes: rawFullName},
+ FullName: []asn1.RawValue{
+ asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
+ },
},
}
crlDp = append(crlDp, dp)
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index 502f5d21d3..7d75727a8c 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -1891,3 +1891,58 @@ func TestEmptySubject(t *testing.T) {
t.Fatal("SAN extension is missing")
}
+
+// multipleURLsInCRLDPPEM contains two URLs in a single CRL DistributionPoint
+// structure. It is taken from https://crt.sh/?id=12721534.
+const multipleURLsInCRLDPPEM = `
+-----BEGIN CERTIFICATE-----
+MIIF4TCCBMmgAwIBAgIQc+6uFePfrahUGpXs8lhiTzANBgkqhkiG9w0BAQsFADCB
+8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy
+dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1
+YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3
+dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh
+IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD
+LUFDQzAeFw0xNDA5MTgwODIxMDBaFw0zMDA5MTgwODIxMDBaMIGGMQswCQYDVQQG
+EwJFUzEzMDEGA1UECgwqQ09OU09SQ0kgQURNSU5JU1RSQUNJTyBPQkVSVEEgREUg
+Q0FUQUxVTllBMSowKAYDVQQLDCFTZXJ2ZWlzIFDDumJsaWNzIGRlIENlcnRpZmlj
+YWNpw7MxFjAUBgNVBAMMDUVDLUNpdXRhZGFuaWEwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDFkHPRZPZlXTWZ5psJhbS/Gx+bxcTpGrlVQHHtIkgGz77y
+TA7UZUFb2EQMncfbOhR0OkvQQn1aMvhObFJSR6nI+caf2D+h/m/InMl1MyH3S0Ak
+YGZZsthnyC6KxqK2A/NApncrOreh70ULkQs45aOKsi1kR1W0zE+iFN+/P19P7AkL
+Rl3bXBCVd8w+DLhcwRrkf1FCDw6cEqaFm3cGgf5cbBDMaVYAweWTxwBZAq2RbQAW
+jE7mledcYghcZa4U6bUmCBPuLOnO8KMFAvH+aRzaf3ws5/ZoOVmryyLLJVZ54peZ
+OwnP9EL4OuWzmXCjBifXR2IAblxs5JYj57tls45nAgMBAAGjggHaMIIB1jASBgNV
+HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUC2hZPofI
+oxUa4ECCIl+fHbLFNxUwHwYDVR0jBBgwFoAUoMOLRKo3pUW/l4Ba0fF4opvpXY0w
+gdYGA1UdIASBzjCByzCByAYEVR0gADCBvzAxBggrBgEFBQcCARYlaHR0cHM6Ly93
+d3cuYW9jLmNhdC9DQVRDZXJ0L1JlZ3VsYWNpbzCBiQYIKwYBBQUHAgIwfQx7QXF1
+ZXN0IGNlcnRpZmljYXQgw6lzIGVtw6hzIMO6bmljYSBpIGV4Y2x1c2l2YW1lbnQg
+YSBFbnRpdGF0cyBkZSBDZXJ0aWZpY2FjacOzLiBWZWdldSBodHRwczovL3d3dy5h
+b2MuY2F0L0NBVENlcnQvUmVndWxhY2lvMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEF
+BQcwAYYXaHR0cDovL29jc3AuY2F0Y2VydC5jYXQwYgYDVR0fBFswWTBXoFWgU4Yn
+aHR0cDovL2Vwc2NkLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JshihodHRwOi8v
+ZXBzY2QyLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JsMA0GCSqGSIb3DQEBCwUA
+A4IBAQChqFTjlAH5PyIhLjLgEs68CyNNC1+vDuZXRhy22TI83JcvGmQrZosPvVIL
+PsUXx+C06Pfqmh48Q9S89X9K8w1SdJxP/rZeGEoRiKpwvQzM4ArD9QxyC8jirxex
+3Umg9Ai/sXQ+1lBf6xw4HfUUr1WIp7pNHj0ZWLo106urqktcdeAFWme+/klis5fu
+labCSVPuT/QpwakPrtqOhRms8vgpKiXa/eLtL9ZiA28X/Mker0zlAeTA7Z7uAnp6
+oPJTlZu1Gg1ZDJueTWWsLlO+P+Wzm3MRRIbcgdRzm4mdO7ubu26SzX/aQXDhuih+
+eVxXDTCfs7GUlxnjOp5j559X/N0A
+-----END CERTIFICATE-----
+`
+
+func TestMultipleURLsInCRLDP(t *testing.T) {
+ block, _ := pem.Decode([]byte(multipleURLsInCRLDPPEM))
+ cert, err := ParseCertificate(block.Bytes)
+ if err != nil {
+ t.Fatalf("failed to parse certificate: %s", err)
+ }
+
+ want := []string{
+ "http://epscd.catcert.net/crl/ec-acc.crl",
+ "http://epscd2.catcert.net/crl/ec-acc.crl",
+ }
+ if got := cert.CRLDistributionPoints; !reflect.DeepEqual(got, want) {
+ t.Errorf("CRL distribution points = %#v, want #%v", got, want)
+ }
+}