]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/x509: parse multiple URLs in a single CRLDP.
authorAdam Langley <agl@golang.org>
Wed, 10 Jan 2018 21:59:51 +0000 (13:59 -0800)
committerAdam Langley <agl@golang.org>
Thu, 11 Jan 2018 16:47:29 +0000 (16:47 +0000)
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>
src/crypto/x509/x509.go
src/crypto/x509/x509_test.go

index 4c9182d9021ec38396d01234205d658321a38f0e..86d9e82aca45332b4744261de68a56650cee7a69 100644 (file)
@@ -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)
index 502f5d21d387558a43b3d414d0528cbedc2c3de4..7d75727a8ca8c68a15e84c9db01c33846f3e4a22 100644 (file)
@@ -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)
+       }
+}