@@ -22,6 +22,7 @@ import (
22
22
"encoding/pem"
23
23
"fmt"
24
24
"internal/testenv"
25
+ "math"
25
26
"math/big"
26
27
"net"
27
28
"net/url"
@@ -686,6 +687,10 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
686
687
t .Errorf ("%s: failed to parse policy identifiers: got:%#v want:%#v" , test .name , cert .PolicyIdentifiers , template .PolicyIdentifiers )
687
688
}
688
689
690
+ if len (cert .PolicyIdentifiersExt ) > 0 {
691
+ t .Errorf ("%s: unexpected PolicyIdentifiersExt value:%#v" , test .name , template .PolicyIdentifiersExt )
692
+ }
693
+
689
694
if len (cert .PermittedDNSDomains ) != 2 || cert .PermittedDNSDomains [0 ] != ".example.com" || cert .PermittedDNSDomains [1 ] != "example.com" {
690
695
t .Errorf ("%s: failed to parse name constraints: %#v" , test .name , cert .PermittedDNSDomains )
691
696
}
@@ -806,6 +811,82 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
806
811
}
807
812
}
808
813
814
+ func TestCreateSelfSignedCertificatePolicyIdentifier (t * testing.T ) {
815
+ random := rand .Reader
816
+
817
+ ecdsaPriv , err := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
818
+ if err != nil {
819
+ t .Fatalf ("Failed to generate ECDSA key: %s" , err )
820
+ }
821
+ {
822
+ // Cannot have a certificate template with both PolicyIdentifiers and PolicyIdentifiersExt.
823
+ template := Certificate {
824
+ SerialNumber : big .NewInt (- 1 ),
825
+ SignatureAlgorithm : ECDSAWithSHA256 ,
826
+ PolicyIdentifiers : []asn1.ObjectIdentifier {[]int {1 , 2 , 3 }},
827
+ PolicyIdentifiersExt : []asn1.ObjectIdentifierExt {asn1.ObjectIdentifierExt {1 , 2 , 3 , 4 }},
828
+ }
829
+ _ , err := CreateCertificate (random , & template , & template , & ecdsaPriv .PublicKey , ecdsaPriv )
830
+ if err == nil {
831
+ t .Error ("specifying PolicyIdentifiers and PolicyIdentifiersExt should fail" )
832
+ }
833
+ }
834
+ {
835
+ // Certificate template with policy identifier that has sub-oids less than math.MaxInt32.
836
+ template := Certificate {
837
+ SerialNumber : big .NewInt (- 1 ),
838
+ SignatureAlgorithm : ECDSAWithSHA256 ,
839
+ PolicyIdentifiers : []asn1.ObjectIdentifier {[]int {1 , 2 , 3 }},
840
+ }
841
+ derBytes , err := CreateCertificate (random , & template , & template , & ecdsaPriv .PublicKey , ecdsaPriv )
842
+ if err != nil {
843
+ t .Errorf ("failed to create certificate: %s" , err )
844
+ }
845
+ cert , err := ParseCertificate (derBytes )
846
+ if err != nil {
847
+ t .Errorf ("failed to parse certificate: %s" , err )
848
+ }
849
+ if len (cert .PolicyIdentifiers ) != 1 || ! cert .PolicyIdentifiers [0 ].Equal (template .PolicyIdentifiers [0 ]) {
850
+ t .Errorf ("failed to parse policy identifiers: got:%#v want:%#v" , cert .PolicyIdentifiers , template .PolicyIdentifiers )
851
+ }
852
+ if len (cert .PolicyIdentifiersExt ) > 0 {
853
+ t .Errorf ("unexpected PolicyIdentifiersExt value:%#v" , template .PolicyIdentifiersExt )
854
+ }
855
+ }
856
+ {
857
+ // Certificate template with policy identifier that has sub-oids greater than math.MaxInt32.
858
+ template := Certificate {
859
+ SerialNumber : big .NewInt (- 1 ),
860
+ SignatureAlgorithm : ECDSAWithSHA256 ,
861
+ PolicyIdentifiersExt : []asn1.ObjectIdentifierExt {
862
+ asn1.ObjectIdentifierExt {1 , 2 , math .MaxInt32 },
863
+ asn1.ObjectIdentifierExt {1 , 2 , 1 << 60 },
864
+ asn1.ObjectIdentifierExt {1 , 2 , new (big.Int ).Lsh (big .NewInt (1 ), 80 )},
865
+ asn1.ObjectIdentifierExt {1 , 2 , new (big.Int ).Lsh (big .NewInt (1 ), 80 ), 1 << 60 },
866
+ },
867
+ }
868
+ derBytes , err := CreateCertificate (random , & template , & template , & ecdsaPriv .PublicKey , ecdsaPriv )
869
+ if err != nil {
870
+ t .Errorf ("failed to create certificate: %s" , err )
871
+ }
872
+ cert , err := ParseCertificate (derBytes )
873
+ if err != nil {
874
+ t .Errorf ("failed to parse certificate: %s" , err )
875
+ }
876
+ if len (cert .PolicyIdentifiers ) > 0 {
877
+ t .Errorf ("unexpected PolicyIdentifiers value:%#v" , template .PolicyIdentifiers )
878
+ }
879
+ if len (cert .PolicyIdentifiersExt ) == 0 || len (cert .PolicyIdentifiersExt ) != len (template .PolicyIdentifiersExt ) {
880
+ t .Errorf ("failed to parse policy identifiers: got:%#v want:%#v" , cert .PolicyIdentifiersExt , template .PolicyIdentifiersExt )
881
+ }
882
+ for i , pi := range cert .PolicyIdentifiersExt {
883
+ if ! pi .Equal (template .PolicyIdentifiersExt [i ]) {
884
+ t .Errorf ("failed to parse policy identifiers: got:%#v want:%#v" , cert .PolicyIdentifiersExt , template .PolicyIdentifiersExt )
885
+ }
886
+ }
887
+ }
888
+ }
889
+
809
890
// Self-signed certificate using ECDSA with SHA1 & secp256r1
810
891
var ecdsaSHA1CertPem = `
811
892
-----BEGIN CERTIFICATE-----
@@ -2189,6 +2270,66 @@ func TestCriticalNameConstraintWithUnknownType(t *testing.T) {
2189
2270
}
2190
2271
}
2191
2272
2273
+ const certWithLargeSubOidPEM = `
2274
+ -----BEGIN CERTIFICATE-----
2275
+ MIIFZjCCA06gAwIBAgITFgAAAAImoUeGgGDlrAAAAAAAAjANBgkqhkiG9w0BAQsF
2276
+ ADAYMRYwFAYDVQQDEw1DaG9ydXNSb290LUNBMB4XDTE0MDMyNTIxMjYxNFoXDTM0
2277
+ MDMxOTIzMjAwNlowYTESMBAGCgmSJomT8ixkARkWAm56MRIwEAYKCZImiZPyLGQB
2278
+ GRYCY28xFjAUBgoJkiaJk/IsZAEZFgZjaG9ydXMxHzAdBgNVBAMTFmNob3J1cy1D
2279
+ U01TUFJQS0kxNTgtQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3
2280
+ YrgjhkQJqYjL27DAbQim8c3wVldUURBWMLExycwGIbMCxyRFrQmMhqV3bBaKxixx
2281
+ jIAZTVB7hha6HCuR/fkfYlNo1suiu1g7WIPxdecV23CuvOiVfTbI7j8LlijsVbKW
2282
+ 2jOy7LBSywaU58aPS95UqUfqtY53pWbFzQQu//hovqFFwk12mApu42SqmcupxS7/
2283
+ tmhkaC+wgliaiS8p+CJZGSBUekuVQNclLGqyYUeBlO3jjIwVZzh9qlLaEbO7NLG8
2284
+ k3A5w/9T3r195AmA4+sXKlj9nV9zS6Q8t6ygB6g6/Hr2sv8Xogi3AAR65HghSz2z
2285
+ kRbANOUVuVtCMHfiJUYHAgMBAAGjggFeMIIBWjAQBgkrBgEEAYI3FQEEAwIBADAd
2286
+ BgNVHQ4EFgQUPn4jsmFshpUupvUcLDmp2LpJCaowgYwGA1UdIASBhDCBgTB/Bg0q
2287
+ JIH5z5nyYIUaQgEBMG4wOgYIKwYBBQUHAgIwLh4sAEwAZQBnAGEAbAAgAFAAbwBs
2288
+ AGkAYwB5ACAAUwB0AGEAdABlAG0AZQBuAHQwMAYIKwYBBQUHAgEWJGh0dHA6Ly9j
2289
+ cmwuY2hvcnVzLmNvLm56L3BraS9jcHMudHh0ADAZBgkrBgEEAYI3FAIEDB4KAFMA
2290
+ dQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAW
2291
+ gBTPctdjhzmVPatJ73QufzslwP7q3DA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8v
2292
+ Y3JsLmNob3J1cy5jby5uei9wa2kvQ2hvcnVzUm9vdC1DQS5jcmwwDQYJKoZIhvcN
2293
+ AQELBQADggIBAKFEeteUZqZXv95+hpjYFGj6NubVRmbmIH1DU2nydY+RdOZAhn6b
2294
+ 0ozXoTtprEoo5POUjNZOz7btr08SCbtYQsm4nL5NHj3JSuMj0jDlnn8Qs4yadk5D
2295
+ 3rTMOf6ZdwVqqZuctwfjlfXgOvPHnVsbUsK02x4b6yJqbbQu7KxxkVoSuneOWpHd
2296
+ ZPNqF8aigupfTn5wylKFz2zW39yRQbu1Xbbe31xjqN6g0T/57+myf1j6PtyntmcX
2297
+ 8n31ZFLCtuC1uXEvN4Mlr0FGXoMpwzlysHzWejFWRQ7Oj7O9/pyzHFgxrlbZilp4
2298
+ 7qDATM212smJDReEFaFTVR6CgA4xZC4xADL0SU/6MNa2vA4bg8bVlQ5XxBOyRBfq
2299
+ PEItYXN3dp7c9medpAh1QauNpFZL7n4DA63X2zB97o6N8fyNSzJXp6x1qGUUgSSz
2300
+ QSF65ypj/QDdRwczNmvBlSAFQoFEQpYJarJXPBj9859y1ZkDCctYz6lXUA1qjkCT
2301
+ /mM6UTdnDD7LR3vQmQo6t8ydr4sQVV8O1ZJmAxHt+4qYg/UpHdPt63mneHPZaoE9
2302
+ N9tF+yS8w1F2Mw5YP6OyjZJy6o8kXR3I/jao4hvDVjfEzo4eSrucAsqwr3Q4kUgl
2303
+ GYhu9NN9++fuqOoXuWBguh+3//dgMOXhgFVsWvx9fzLiQQqUc5ToGbJK
2304
+ -----END CERTIFICATE-----`
2305
+
2306
+ // X.509 certificates may contain policy identifiers that have
2307
+ // sub-oid values greater than math.MaxInt32. ParseCertificate
2308
+ // must not return an error when parsing such certificates.
2309
+ func TestCertificateWithLargeSubOidInPolicyIdentifiers (t * testing.T ) {
2310
+ block , _ := pem .Decode ([]byte (certWithLargeSubOidPEM ))
2311
+ c , err := ParseCertificate (block .Bytes )
2312
+ if err != nil {
2313
+ t .Errorf ("Failed to parse certificate: %v" , err .Error ())
2314
+ }
2315
+ if len (c .PolicyIdentifiersExt ) != 1 {
2316
+ // The Certificate policy identifier is 1.2.36.67006527840.666.66.1.1
2317
+ // Because it does not fit in the PolicyIdentifiers field, it is
2318
+ // unmarshaled in the PolicyIdentifiersExt field.
2319
+ t .Errorf ("PolicyIdentifiersExt expected 1 but got %d" , len (c .PolicyIdentifiersExt ))
2320
+ }
2321
+ expected := "1.2.36.67006527840.666.66.1.1"
2322
+ if c .PolicyIdentifiersExt [0 ].String () != expected {
2323
+ t .Errorf ("PolicyIdentifiersExt expected %s but got %s" , expected , c .PolicyIdentifiersExt [0 ].String ())
2324
+ }
2325
+ if len (c .PolicyIdentifiers ) > 0 {
2326
+ // The Certificate policy identifier for this particular x509 certificate
2327
+ // does not fit in the PolicyIdentifiers field, because suboid 67006527840
2328
+ // is more than 2^31
2329
+ t .Errorf ("PolicyIdentifiers expected zero length but got %d" , len (c .PolicyIdentifiers ))
2330
+ }
2331
+ }
2332
+
2192
2333
const badIPMaskPEM = `
2193
2334
-----BEGIN CERTIFICATE-----
2194
2335
MIICzzCCAbegAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UEAxMSQmFk
0 commit comments