github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/crypto/x509/x509_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package x509 6 7 import ( 8 "bytes" 9 "crypto" 10 "crypto/dsa" 11 "crypto/ecdsa" 12 "crypto/ed25519" 13 "crypto/elliptic" 14 "crypto/rand" 15 "crypto/rsa" 16 _ "crypto/sha256" 17 _ "crypto/sha512" 18 "crypto/x509/pkix" 19 "encoding/asn1" 20 "encoding/base64" 21 "encoding/hex" 22 "encoding/pem" 23 "fmt" 24 "internal/testenv" 25 "io" 26 "math/big" 27 "net" 28 "net/url" 29 "os/exec" 30 "reflect" 31 "runtime" 32 "strings" 33 "testing" 34 "time" 35 ) 36 37 func TestParsePKCS1PrivateKey(t *testing.T) { 38 block, _ := pem.Decode([]byte(pemPrivateKey)) 39 priv, err := ParsePKCS1PrivateKey(block.Bytes) 40 if err != nil { 41 t.Errorf("Failed to parse private key: %s", err) 42 return 43 } 44 if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 || 45 priv.PublicKey.E != rsaPrivateKey.PublicKey.E || 46 priv.D.Cmp(rsaPrivateKey.D) != 0 || 47 priv.Primes[0].Cmp(rsaPrivateKey.Primes[0]) != 0 || 48 priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 { 49 t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey) 50 } 51 52 // This private key includes an invalid prime that 53 // rsa.PrivateKey.Validate should reject. 54 data := []byte("0\x16\x02\x00\x02\x02\u007f\x00\x02\x0200\x02\x0200\x02\x02\x00\x01\x02\x02\u007f\x00") 55 if _, err := ParsePKCS1PrivateKey(data); err == nil { 56 t.Errorf("parsing invalid private key did not result in an error") 57 } 58 } 59 60 func TestPKCS1MismatchPublicKeyFormat(t *testing.T) { 61 62 const pkixPublicKey = "30820122300d06092a864886f70d01010105000382010f003082010a0282010100dd5a0f37d3ca5232852ccc0e81eebec270e2f2c6c44c6231d852971a0aad00aa7399e9b9de444611083c59ea919a9d76c20a7be131a99045ec19a7bb452d647a72429e66b87e28be9e8187ed1d2a2a01ef3eb2360706bd873b07f2d1f1a72337aab5ec94e983e39107f52c480d404915e84d75a3db2cfd601726a128cb1d7f11492d4bdb53272e652276667220795c709b8a9b4af6489cbf48bb8173b8fb607c834a71b6e8bf2d6aab82af3c8ad7ce16d8dcf58373a6edc427f7484d09744d4c08f4e19ed07adbf6cb31243bc5d0d1145e77a08a6fc5efd208eca67d6abf2d6f38f58b6fdd7c28774fb0cc03fc4935c6e074842d2e1479d3d8787249258719f90203010001" 63 const errorContains = "use ParsePKIXPublicKey instead" 64 derBytes, _ := hex.DecodeString(pkixPublicKey) 65 _, err := ParsePKCS1PublicKey(derBytes) 66 if !strings.Contains(err.Error(), errorContains) { 67 t.Errorf("expected error containing %q, got %s", errorContains, err) 68 } 69 } 70 71 func testParsePKIXPublicKey(t *testing.T, pemBytes string) (pub interface{}) { 72 block, _ := pem.Decode([]byte(pemBytes)) 73 pub, err := ParsePKIXPublicKey(block.Bytes) 74 if err != nil { 75 t.Fatalf("Failed to parse public key: %s", err) 76 } 77 78 pubBytes2, err := MarshalPKIXPublicKey(pub) 79 if err != nil { 80 t.Errorf("Failed to marshal public key for the second time: %s", err) 81 return 82 } 83 if !bytes.Equal(pubBytes2, block.Bytes) { 84 t.Errorf("Reserialization of public key didn't match. got %x, want %x", pubBytes2, block.Bytes) 85 } 86 return 87 } 88 89 func TestParsePKIXPublicKey(t *testing.T) { 90 t.Run("RSA", func(t *testing.T) { 91 pub := testParsePKIXPublicKey(t, pemPublicKey) 92 _, ok := pub.(*rsa.PublicKey) 93 if !ok { 94 t.Errorf("Value returned from ParsePKIXPublicKey was not an RSA public key") 95 } 96 }) 97 t.Run("Ed25519", func(t *testing.T) { 98 pub := testParsePKIXPublicKey(t, pemEd25519Key) 99 _, ok := pub.(ed25519.PublicKey) 100 if !ok { 101 t.Errorf("Value returned from ParsePKIXPublicKey was not an Ed25519 public key") 102 } 103 }) 104 } 105 106 var pemPublicKey = `-----BEGIN PUBLIC KEY----- 107 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VoPN9PKUjKFLMwOge6+ 108 wnDi8sbETGIx2FKXGgqtAKpzmem53kRGEQg8WeqRmp12wgp74TGpkEXsGae7RS1k 109 enJCnma4fii+noGH7R0qKgHvPrI2Bwa9hzsH8tHxpyM3qrXslOmD45EH9SxIDUBJ 110 FehNdaPbLP1gFyahKMsdfxFJLUvbUycuZSJ2ZnIgeVxwm4qbSvZInL9Iu4FzuPtg 111 fINKcbbovy1qq4KvPIrXzhbY3PWDc6btxCf3SE0JdE1MCPThntB62/bLMSQ7xdDR 112 FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ 113 +QIDAQAB 114 -----END PUBLIC KEY----- 115 ` 116 117 var pemPrivateKey = testingKey(` 118 -----BEGIN RSA TESTING KEY----- 119 MIICXAIBAAKBgQCxoeCUW5KJxNPxMp+KmCxKLc1Zv9Ny+4CFqcUXVUYH69L3mQ7v 120 IWrJ9GBfcaA7BPQqUlWxWM+OCEQZH1EZNIuqRMNQVuIGCbz5UQ8w6tS0gcgdeGX7 121 J7jgCQ4RK3F/PuCM38QBLaHx988qG8NMc6VKErBjctCXFHQt14lerd5KpQIDAQAB 122 AoGAYrf6Hbk+mT5AI33k2Jt1kcweodBP7UkExkPxeuQzRVe0KVJw0EkcFhywKpr1 123 V5eLMrILWcJnpyHE5slWwtFHBG6a5fLaNtsBBtcAIfqTQ0Vfj5c6SzVaJv0Z5rOd 124 7gQF6isy3t3w9IF3We9wXQKzT6q5ypPGdm6fciKQ8RnzREkCQQDZwppKATqQ41/R 125 vhSj90fFifrGE6aVKC1hgSpxGQa4oIdsYYHwMzyhBmWW9Xv/R+fPyr8ZwPxp2c12 126 33QwOLPLAkEA0NNUb+z4ebVVHyvSwF5jhfJxigim+s49KuzJ1+A2RaSApGyBZiwS 127 rWvWkB471POAKUYt5ykIWVZ83zcceQiNTwJBAMJUFQZX5GDqWFc/zwGoKkeR49Yi 128 MTXIvf7Wmv6E++eFcnT461FlGAUHRV+bQQXGsItR/opIG7mGogIkVXa3E1MCQARX 129 AAA7eoZ9AEHflUeuLn9QJI/r0hyQQLEtrpwv6rDT1GCWaLII5HJ6NUFVf4TTcqxo 130 6vdM4QGKTJoO+SaCyP0CQFdpcxSAuzpFcKv0IlJ8XzS/cy+mweCMwyJ1PFEc4FX6 131 wg/HcAJWY60xZTJDFN+Qfx8ZQvBEin6c2/h+zZi5IVY= 132 -----END RSA TESTING KEY----- 133 `) 134 135 // pemEd25519Key is the example from RFC 8410, Secrion 4. 136 var pemEd25519Key = ` 137 -----BEGIN PUBLIC KEY----- 138 MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE= 139 -----END PUBLIC KEY----- 140 ` 141 142 func TestPKIXMismatchPublicKeyFormat(t *testing.T) { 143 144 const pkcs1PublicKey = "308201080282010100817cfed98bcaa2e2a57087451c7674e0c675686dc33ff1268b0c2a6ee0202dec710858ee1c31bdf5e7783582e8ca800be45f3275c6576adc35d98e26e95bb88ca5beb186f853b8745d88bc9102c5f38753bcda519fb05948d5c77ac429255ff8aaf27d9f45d1586e95e2e9ba8a7cb771b8a09dd8c8fed3f933fd9b439bc9f30c475953418ef25f71a2b6496f53d94d39ce850aa0cc75d445b5f5b4f4ee4db78ab197a9a8d8a852f44529a007ac0ac23d895928d60ba538b16b0b087a7f903ed29770e215019b77eaecc360f35f7ab11b6d735978795b2c4a74e5bdea4dc6594cd67ed752a108e666729a753ab36d6c4f606f8760f507e1765be8cd744007e629020103" 145 const errorContains = "use ParsePKCS1PublicKey instead" 146 derBytes, _ := hex.DecodeString(pkcs1PublicKey) 147 _, err := ParsePKIXPublicKey(derBytes) 148 if !strings.Contains(err.Error(), errorContains) { 149 t.Errorf("expected error containing %q, got %s", errorContains, err) 150 } 151 } 152 153 var testPrivateKey *rsa.PrivateKey 154 155 func init() { 156 block, _ := pem.Decode([]byte(pemPrivateKey)) 157 158 var err error 159 if testPrivateKey, err = ParsePKCS1PrivateKey(block.Bytes); err != nil { 160 panic("Failed to parse private key: " + err.Error()) 161 } 162 } 163 164 func bigFromString(s string) *big.Int { 165 ret := new(big.Int) 166 ret.SetString(s, 10) 167 return ret 168 } 169 170 func fromBase10(base10 string) *big.Int { 171 i := new(big.Int) 172 i.SetString(base10, 10) 173 return i 174 } 175 176 func bigFromHexString(s string) *big.Int { 177 ret := new(big.Int) 178 ret.SetString(s, 16) 179 return ret 180 } 181 182 var rsaPrivateKey = &rsa.PrivateKey{ 183 PublicKey: rsa.PublicKey{ 184 N: bigFromString("124737666279038955318614287965056875799409043964547386061640914307192830334599556034328900586693254156136128122194531292927142396093148164407300419162827624945636708870992355233833321488652786796134504707628792159725681555822420087112284637501705261187690946267527866880072856272532711620639179596808018872997"), 185 E: 65537, 186 }, 187 D: bigFromString("69322600686866301945688231018559005300304807960033948687567105312977055197015197977971637657636780793670599180105424702854759606794705928621125408040473426339714144598640466128488132656829419518221592374964225347786430566310906679585739468938549035854760501049443920822523780156843263434219450229353270690889"), 188 Primes: []*big.Int{ 189 bigFromString("11405025354575369741595561190164746858706645478381139288033759331174478411254205003127028642766986913445391069745480057674348716675323735886284176682955723"), 190 bigFromString("10937079261204603443118731009201819560867324167189758120988909645641782263430128449826989846631183550578761324239709121189827307416350485191350050332642639"), 191 }, 192 } 193 194 func TestMarshalRSAPrivateKey(t *testing.T) { 195 priv := &rsa.PrivateKey{ 196 PublicKey: rsa.PublicKey{ 197 N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"), 198 E: 3, 199 }, 200 D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"), 201 Primes: []*big.Int{ 202 fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"), 203 fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"), 204 fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"), 205 }, 206 } 207 208 derBytes := MarshalPKCS1PrivateKey(priv) 209 210 priv2, err := ParsePKCS1PrivateKey(derBytes) 211 if err != nil { 212 t.Errorf("error parsing serialized key: %s", err) 213 return 214 } 215 if priv.PublicKey.N.Cmp(priv2.PublicKey.N) != 0 || 216 priv.PublicKey.E != priv2.PublicKey.E || 217 priv.D.Cmp(priv2.D) != 0 || 218 len(priv2.Primes) != 3 || 219 priv.Primes[0].Cmp(priv2.Primes[0]) != 0 || 220 priv.Primes[1].Cmp(priv2.Primes[1]) != 0 || 221 priv.Primes[2].Cmp(priv2.Primes[2]) != 0 { 222 t.Errorf("got:%+v want:%+v", priv, priv2) 223 } 224 } 225 226 func TestMarshalRSAPublicKey(t *testing.T) { 227 pub := &rsa.PublicKey{ 228 N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"), 229 E: 3, 230 } 231 derBytes := MarshalPKCS1PublicKey(pub) 232 pub2, err := ParsePKCS1PublicKey(derBytes) 233 if err != nil { 234 t.Errorf("ParsePKCS1PublicKey: %s", err) 235 } 236 if pub.N.Cmp(pub2.N) != 0 || pub.E != pub2.E { 237 t.Errorf("ParsePKCS1PublicKey = %+v, want %+v", pub, pub2) 238 } 239 240 // It's never been documented that asn1.Marshal/Unmarshal on rsa.PublicKey works, 241 // but it does, and we know of code that depends on it. 242 // Lock that in, even though we'd prefer that people use MarshalPKCS1PublicKey and ParsePKCS1PublicKey. 243 derBytes2, err := asn1.Marshal(*pub) 244 if err != nil { 245 t.Errorf("Marshal(rsa.PublicKey): %v", err) 246 } else if !bytes.Equal(derBytes, derBytes2) { 247 t.Errorf("Marshal(rsa.PublicKey) = %x, want %x", derBytes2, derBytes) 248 } 249 pub3 := new(rsa.PublicKey) 250 rest, err := asn1.Unmarshal(derBytes, pub3) 251 if err != nil { 252 t.Errorf("Unmarshal(rsa.PublicKey): %v", err) 253 } 254 if len(rest) != 0 || pub.N.Cmp(pub3.N) != 0 || pub.E != pub3.E { 255 t.Errorf("Unmarshal(rsa.PublicKey) = %+v, %q want %+v, %q", pub, rest, pub2, []byte(nil)) 256 } 257 258 publicKeys := []struct { 259 derBytes []byte 260 expectedErrSubstr string 261 }{ 262 { 263 derBytes: []byte{ 264 0x30, 6, // SEQUENCE, 6 bytes 265 0x02, 1, // INTEGER, 1 byte 266 17, 267 0x02, 1, // INTEGER, 1 byte 268 3, // 3 269 }, 270 }, { 271 derBytes: []byte{ 272 0x30, 6, // SEQUENCE 273 0x02, 1, // INTEGER, 1 byte 274 0xff, // -1 275 0x02, 1, // INTEGER, 1 byte 276 3, 277 }, 278 expectedErrSubstr: "zero or negative", 279 }, { 280 derBytes: []byte{ 281 0x30, 6, // SEQUENCE 282 0x02, 1, // INTEGER, 1 byte 283 17, 284 0x02, 1, // INTEGER, 1 byte 285 0xff, // -1 286 }, 287 expectedErrSubstr: "zero or negative", 288 }, { 289 derBytes: []byte{ 290 0x30, 6, // SEQUENCE 291 0x02, 1, // INTEGER, 1 byte 292 17, 293 0x02, 1, // INTEGER, 1 byte 294 3, 295 1, 296 }, 297 expectedErrSubstr: "trailing data", 298 }, { 299 derBytes: []byte{ 300 0x30, 9, // SEQUENCE 301 0x02, 1, // INTEGER, 1 byte 302 17, 303 0x02, 4, // INTEGER, 4 bytes 304 0x7f, 0xff, 0xff, 0xff, 305 }, 306 }, { 307 derBytes: []byte{ 308 0x30, 10, // SEQUENCE 309 0x02, 1, // INTEGER, 1 byte 310 17, 311 0x02, 5, // INTEGER, 5 bytes 312 0x00, 0x80, 0x00, 0x00, 0x00, 313 }, 314 // On 64-bit systems, encoding/asn1 will accept the 315 // public exponent, but ParsePKCS1PublicKey will return 316 // an error. On 32-bit systems, encoding/asn1 will 317 // return the error. The common substring of both error 318 // is the word “large”. 319 expectedErrSubstr: "large", 320 }, 321 } 322 323 for i, test := range publicKeys { 324 shouldFail := len(test.expectedErrSubstr) > 0 325 pub, err := ParsePKCS1PublicKey(test.derBytes) 326 if shouldFail { 327 if err == nil { 328 t.Errorf("#%d: unexpected success, got %#v", i, pub) 329 } else if !strings.Contains(err.Error(), test.expectedErrSubstr) { 330 t.Errorf("#%d: expected error containing %q, got %s", i, test.expectedErrSubstr, err) 331 } 332 } else { 333 if err != nil { 334 t.Errorf("#%d: unexpected failure: %s", i, err) 335 continue 336 } 337 reserialized := MarshalPKCS1PublicKey(pub) 338 if !bytes.Equal(reserialized, test.derBytes) { 339 t.Errorf("#%d: failed to reserialize: got %x, expected %x", i, reserialized, test.derBytes) 340 } 341 } 342 } 343 } 344 345 type matchHostnamesTest struct { 346 pattern, host string 347 ok bool 348 } 349 350 var matchHostnamesTests = []matchHostnamesTest{ 351 {"a.b.c", "a.b.c", true}, 352 {"a.b.c", "b.b.c", false}, 353 {"", "b.b.c", false}, 354 {"a.b.c", "", false}, 355 {"example.com", "example.com", true}, 356 {"example.com", "www.example.com", false}, 357 {"*.example.com", "example.com", false}, 358 {"*.example.com", "www.example.com", true}, 359 {"*.example.com", "www.example.com.", true}, 360 {"*.example.com", "xyz.www.example.com", false}, 361 {"*.example.com", "https://www.example.com", false}, // Issue 27591 362 {"*.example..com", "www.example..com", false}, 363 {"www.example..com", "www.example..com", true}, 364 {"*.*.example.com", "xyz.www.example.com", false}, 365 {"*.www.*.com", "xyz.www.example.com", false}, 366 {"*bar.example.com", "foobar.example.com", false}, 367 {"f*.example.com", "foobar.example.com", false}, 368 {"www.example.com", "*.example.com", false}, 369 {"", ".", false}, 370 {".", "", false}, 371 {".", ".", false}, 372 {"example.com", "example.com.", true}, 373 {"example.com.", "example.com", false}, 374 {"example.com.", "example.com.", true}, // perfect matches allow trailing dots in patterns 375 {"*.com.", "example.com.", false}, 376 {"*.com.", "example.com", false}, 377 {"*.com", "example.com", true}, 378 {"*.com", "example.com.", true}, 379 {"foo:bar", "foo:bar", true}, 380 {"*.foo:bar", "xxx.foo:bar", false}, 381 {"*.2.3.4", "1.2.3.4", false}, 382 {"*.2.3.4", "[1.2.3.4]", false}, 383 {"*:4860:4860::8888", "2001:4860:4860::8888", false}, 384 {"*:4860:4860::8888", "[2001:4860:4860::8888]", false}, 385 {"2001:4860:4860::8888", "2001:4860:4860::8888", false}, 386 {"2001:4860:4860::8888", "[2001:4860:4860::8888]", false}, 387 {"[2001:4860:4860::8888]", "2001:4860:4860::8888", false}, 388 {"[2001:4860:4860::8888]", "[2001:4860:4860::8888]", false}, 389 } 390 391 func TestMatchHostnames(t *testing.T) { 392 for i, test := range matchHostnamesTests { 393 c := &Certificate{DNSNames: []string{test.pattern}} 394 r := c.VerifyHostname(test.host) == nil 395 if r != test.ok { 396 t.Errorf("#%d mismatch got: %t want: %t when matching '%s' against '%s'", i, r, test.ok, test.host, test.pattern) 397 } 398 } 399 } 400 401 func TestMatchIP(t *testing.T) { 402 // Check that pattern matching is working. 403 c := &Certificate{ 404 DNSNames: []string{"*.foo.bar.baz"}, 405 Subject: pkix.Name{ 406 CommonName: "*.foo.bar.baz", 407 }, 408 } 409 err := c.VerifyHostname("quux.foo.bar.baz") 410 if err != nil { 411 t.Fatalf("VerifyHostname(quux.foo.bar.baz): %v", err) 412 } 413 414 // But check that if we change it to be matching against an IP address, 415 // it is rejected. 416 c = &Certificate{ 417 DNSNames: []string{"*.2.3.4"}, 418 Subject: pkix.Name{ 419 CommonName: "*.2.3.4", 420 }, 421 } 422 err = c.VerifyHostname("1.2.3.4") 423 if err == nil { 424 t.Fatalf("VerifyHostname(1.2.3.4) should have failed, did not") 425 } 426 427 c = &Certificate{ 428 IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")}, 429 } 430 err = c.VerifyHostname("127.0.0.1") 431 if err != nil { 432 t.Fatalf("VerifyHostname(127.0.0.1): %v", err) 433 } 434 err = c.VerifyHostname("::1") 435 if err != nil { 436 t.Fatalf("VerifyHostname(::1): %v", err) 437 } 438 err = c.VerifyHostname("[::1]") 439 if err != nil { 440 t.Fatalf("VerifyHostname([::1]): %v", err) 441 } 442 } 443 444 func TestCertificateParse(t *testing.T) { 445 s, _ := base64.StdEncoding.DecodeString(certBytes) 446 certs, err := ParseCertificates(s) 447 if err != nil { 448 t.Error(err) 449 } 450 if len(certs) != 2 { 451 t.Errorf("Wrong number of certs: got %d want 2", len(certs)) 452 return 453 } 454 455 err = certs[0].CheckSignatureFrom(certs[1]) 456 if err != nil { 457 t.Error(err) 458 } 459 460 if err := certs[0].VerifyHostname("mail.google.com"); err != nil { 461 t.Error(err) 462 } 463 464 const expectedExtensions = 10 465 if n := len(certs[0].Extensions); n != expectedExtensions { 466 t.Errorf("want %d extensions, got %d", expectedExtensions, n) 467 } 468 } 469 470 func TestCertificateEqualOnNil(t *testing.T) { 471 cNonNil := new(Certificate) 472 var cNil1, cNil2 *Certificate 473 if !cNil1.Equal(cNil2) { 474 t.Error("Nil certificates: cNil1 is not equal to cNil2") 475 } 476 if !cNil2.Equal(cNil1) { 477 t.Error("Nil certificates: cNil2 is not equal to cNil1") 478 } 479 if cNil1.Equal(cNonNil) { 480 t.Error("Unexpectedly cNil1 is equal to cNonNil") 481 } 482 if cNonNil.Equal(cNil1) { 483 t.Error("Unexpectedly cNonNil is equal to cNil1") 484 } 485 } 486 487 func TestMismatchedSignatureAlgorithm(t *testing.T) { 488 der, _ := pem.Decode([]byte(rsaPSSSelfSignedPEM)) 489 if der == nil { 490 t.Fatal("Failed to find PEM block") 491 } 492 493 cert, err := ParseCertificate(der.Bytes) 494 if err != nil { 495 t.Fatal(err) 496 } 497 498 if err = cert.CheckSignature(ECDSAWithSHA256, nil, nil); err == nil { 499 t.Fatal("CheckSignature unexpectedly return no error") 500 } 501 502 const expectedSubstring = " but have public key of type " 503 if !strings.Contains(err.Error(), expectedSubstring) { 504 t.Errorf("Expected error containing %q, but got %q", expectedSubstring, err) 505 } 506 } 507 508 var certBytes = "MIIE0jCCA7qgAwIBAgIQWcvS+TTB3GwCAAAAAGEAWzANBgkqhkiG9w0BAQsFADBCMQswCQYD" + 509 "VQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMRMwEQYDVQQDEwpHVFMg" + 510 "Q0EgMU8xMB4XDTIwMDQwMTEyNTg1NloXDTIwMDYyNDEyNTg1NlowaTELMAkGA1UEBhMCVVMx" + 511 "EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEzARBgNVBAoT" + 512 "Ckdvb2dsZSBMTEMxGDAWBgNVBAMTD21haWwuZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqG" + 513 "SM49AwEHA0IABO+dYiPnkFl+cZVf6mrWeNp0RhQcJSBGH+sEJxjvc+cYlW3QJCnm57qlpFdd" + 514 "pz3MPyVejvXQdM6iI1mEWP4C2OujggJmMIICYjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAww" + 515 "CgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUI6pZhnQ/lQgmPDwSKR2A54G7" + 516 "AS4wHwYDVR0jBBgwFoAUmNH4bhDrz5vsYJ8YkBug630J/SswZAYIKwYBBQUHAQEEWDBWMCcG" + 517 "CCsGAQUFBzABhhtodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHMxbzEwKwYIKwYBBQUHMAKGH2h0" + 518 "dHA6Ly9wa2kuZ29vZy9nc3IyL0dUUzFPMS5jcnQwLAYDVR0RBCUwI4IPbWFpbC5nb29nbGUu" + 519 "Y29tghBpbmJveC5nb29nbGUuY29tMCEGA1UdIAQaMBgwCAYGZ4EMAQICMAwGCisGAQQB1nkC" + 520 "BQMwLwYDVR0fBCgwJjAkoCKgIIYeaHR0cDovL2NybC5wa2kuZ29vZy9HVFMxTzEuY3JsMIIB" + 521 "AwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYAsh4FzIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+L" + 522 "kF4AAAFxNgmxKgAABAMARzBFAiEA12/OHdTGXQ3qHHC3NvYCyB8aEz/+ZFOLCAI7lhqj28sC" + 523 "IG2/7Yz2zK6S6ai+dH7cTMZmoFGo39gtaTqtZAqEQX7nAHUAXqdz+d9WwOe1Nkh90EngMnqR" + 524 "mgyEoRIShBh1loFxRVgAAAFxNgmxTAAABAMARjBEAiA7PNq+MFfv6O9mBkxFViS2TfU66yRB" + 525 "/njcebWglLQjZQIgOyRKhxlEizncFRml7yn4Bg48ktXKGjo+uiw6zXEINb0wDQYJKoZIhvcN" + 526 "AQELBQADggEBADM2Rh306Q10PScsolYMxH1B/K4Nb2WICvpY0yDPJFdnGjqCYym196TjiEvs" + 527 "R6etfeHdyzlZj6nh82B4TVyHjiWM02dQgPalOuWQcuSy0OvLh7F1E7CeHzKlczdFPBTOTdM1" + 528 "RDTxlvw1bAqc0zueM8QIAyEy3opd7FxAcGQd5WRIJhzLBL+dbbMOW/LTeW7cm/Xzq8cgCybN" + 529 "BSZAvhjseJ1L29OlCTZL97IfnX0IlFQzWuvvHy7V2B0E3DHlzM0kjwkkCKDUUp/wajv2NZKC" + 530 "TkhEyERacZRKc9U0ADxwsAzHrdz5+5zfD2usEV/MQ5V6d8swLXs+ko0X6swrd4YCiB8wggRK" + 531 "MIIDMqADAgECAg0B47SaoY2KqYElaVC4MA0GCSqGSIb3DQEBCwUAMEwxIDAeBgNVBAsTF0ds" + 532 "b2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpH" + 533 "bG9iYWxTaWduMB4XDTE3MDYxNTAwMDA0MloXDTIxMTIxNTAwMDA0MlowQjELMAkGA1UEBhMC" + 534 "VVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczETMBEGA1UEAxMKR1RTIENBIDFP" + 535 "MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAYz0XUi83TnORA73603WkhG8nP" + 536 "PI5MdbkPMRmEPZ48Ke9QDRCTbwWAgJ8qoL0SSwLhPZ9YFiT+MJ8LdHdVkx1L903hkoIQ9lGs" + 537 "DMOyIpQPNGuYEEnnC52DOd0gxhwt79EYYWXnI4MgqCMS/9Ikf9Qv50RqW03XUGawr55CYwX7" + 538 "4BzEY2Gvn2oz/2KXvUjZ03wUZ9x13C5p6PhteGnQtxAFuPExwjsk/RozdPgj4OxrGYoWxuPN" + 539 "pM0L27OkWWA4iDutHbnGjKdTG/y82aSrvN08YdeTFZjugb2P4mRHIEAGTtesl+i5wFkSoUkl" + 540 "I+TtcDQspbRjfPmjPYPRzW0krAcCAwEAAaOCATMwggEvMA4GA1UdDwEB/wQEAwIBhjAdBgNV" + 541 "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E" + 542 "FgQUmNH4bhDrz5vsYJ8YkBug630J/SswHwYDVR0jBBgwFoAUm+IHV2ccHsBqBt5ZtJot39wZ" + 543 "hi4wNQYIKwYBBQUHAQEEKTAnMCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC5wa2kuZ29vZy9n" + 544 "c3IyMDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly9jcmwucGtpLmdvb2cvZ3NyMi9nc3IyLmNy" + 545 "bDA/BgNVHSAEODA2MDQGBmeBDAECAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3BraS5nb29n" + 546 "L3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQAagD42efvzLqlGN31eVBY1rsdOCJn+" + 547 "vdE0aSZSZgc9CrpJy2L08RqO/BFPaJZMdCvTZ96yo6oFjYRNTCBlD6WW2g0W+Gw7228EI4hr" + 548 "OmzBYL1on3GO7i1YNAfw1VTphln9e14NIZT1jMmo+NjyrcwPGvOap6kEJ/mjybD/AnhrYbrH" + 549 "NSvoVvpPwxwM7bY8tEvq7czhPOzcDYzWPpvKQliLzBYhF0C8otZm79rEFVvNiaqbCSbnMtIN" + 550 "bmcgAlsQsJAJnAwfnq3YO+qh/GzoEFwIUhlRKnG7rHq13RXtK8kIKiyKtKYhq2P/11JJUNCJ" + 551 "t63yr/tQri/hlQ3zRq2dnPXK" 552 553 func parseCIDR(s string) *net.IPNet { 554 _, net, err := net.ParseCIDR(s) 555 if err != nil { 556 panic(err) 557 } 558 return net 559 } 560 561 func parseURI(s string) *url.URL { 562 uri, err := url.Parse(s) 563 if err != nil { 564 panic(err) 565 } 566 return uri 567 } 568 569 func TestCreateSelfSignedCertificate(t *testing.T) { 570 random := rand.Reader 571 572 ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 573 if err != nil { 574 t.Fatalf("Failed to generate ECDSA key: %s", err) 575 } 576 577 ed25519Pub, ed25519Priv, err := ed25519.GenerateKey(random) 578 if err != nil { 579 t.Fatalf("Failed to generate Ed25519 key: %s", err) 580 } 581 582 tests := []struct { 583 name string 584 pub, priv interface{} 585 checkSig bool 586 sigAlgo SignatureAlgorithm 587 }{ 588 {"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, SHA1WithRSA}, 589 {"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384}, 590 {"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA}, 591 {"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1}, 592 {"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, SHA256WithRSAPSS}, 593 {"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS}, 594 {"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384}, 595 {"Ed25519", ed25519Pub, ed25519Priv, true, PureEd25519}, 596 } 597 598 testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth} 599 testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}} 600 extraExtensionData := []byte("extra extension") 601 602 for _, test := range tests { 603 commonName := "test.example.com" 604 template := Certificate{ 605 // SerialNumber is negative to ensure that negative 606 // values are parsed. This is due to the prevalence of 607 // buggy code that produces certificates with negative 608 // serial numbers. 609 SerialNumber: big.NewInt(-1), 610 Subject: pkix.Name{ 611 CommonName: commonName, 612 Organization: []string{"Σ Acme Co"}, 613 Country: []string{"US"}, 614 ExtraNames: []pkix.AttributeTypeAndValue{ 615 { 616 Type: []int{2, 5, 4, 42}, 617 Value: "Gopher", 618 }, 619 // This should override the Country, above. 620 { 621 Type: []int{2, 5, 4, 6}, 622 Value: "NL", 623 }, 624 }, 625 }, 626 NotBefore: time.Unix(1000, 0), 627 NotAfter: time.Unix(100000, 0), 628 629 SignatureAlgorithm: test.sigAlgo, 630 631 SubjectKeyId: []byte{1, 2, 3, 4}, 632 KeyUsage: KeyUsageCertSign, 633 634 ExtKeyUsage: testExtKeyUsage, 635 UnknownExtKeyUsage: testUnknownExtKeyUsage, 636 637 BasicConstraintsValid: true, 638 IsCA: true, 639 640 OCSPServer: []string{"http://ocsp.example.com"}, 641 IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"}, 642 643 DNSNames: []string{"test.example.com"}, 644 EmailAddresses: []string{"gopher@golang.org"}, 645 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, 646 URIs: []*url.URL{parseURI("https://foo.com/wibble#foo")}, 647 648 PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}}, 649 PermittedDNSDomains: []string{".example.com", "example.com"}, 650 ExcludedDNSDomains: []string{"bar.example.com"}, 651 PermittedIPRanges: []*net.IPNet{parseCIDR("192.168.1.1/16"), parseCIDR("1.2.3.4/8")}, 652 ExcludedIPRanges: []*net.IPNet{parseCIDR("2001:db8::/48")}, 653 PermittedEmailAddresses: []string{"foo@example.com"}, 654 ExcludedEmailAddresses: []string{".example.com", "example.com"}, 655 PermittedURIDomains: []string{".bar.com", "bar.com"}, 656 ExcludedURIDomains: []string{".bar2.com", "bar2.com"}, 657 658 CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"}, 659 660 ExtraExtensions: []pkix.Extension{ 661 { 662 Id: []int{1, 2, 3, 4}, 663 Value: extraExtensionData, 664 }, 665 // This extension should override the SubjectKeyId, above. 666 { 667 Id: oidExtensionSubjectKeyId, 668 Critical: false, 669 Value: []byte{0x04, 0x04, 4, 3, 2, 1}, 670 }, 671 }, 672 } 673 674 derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv) 675 if err != nil { 676 t.Errorf("%s: failed to create certificate: %s", test.name, err) 677 continue 678 } 679 680 cert, err := ParseCertificate(derBytes) 681 if err != nil { 682 t.Errorf("%s: failed to parse certificate: %s", test.name, err) 683 continue 684 } 685 686 if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) { 687 t.Errorf("%s: failed to parse policy identifiers: got:%#v want:%#v", test.name, cert.PolicyIdentifiers, template.PolicyIdentifiers) 688 } 689 690 if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" { 691 t.Errorf("%s: failed to parse name constraints: %#v", test.name, cert.PermittedDNSDomains) 692 } 693 694 if len(cert.ExcludedDNSDomains) != 1 || cert.ExcludedDNSDomains[0] != "bar.example.com" { 695 t.Errorf("%s: failed to parse name constraint exclusions: %#v", test.name, cert.ExcludedDNSDomains) 696 } 697 698 if len(cert.PermittedIPRanges) != 2 || cert.PermittedIPRanges[0].String() != "192.168.0.0/16" || cert.PermittedIPRanges[1].String() != "1.0.0.0/8" { 699 t.Errorf("%s: failed to parse IP constraints: %#v", test.name, cert.PermittedIPRanges) 700 } 701 702 if len(cert.ExcludedIPRanges) != 1 || cert.ExcludedIPRanges[0].String() != "2001:db8::/48" { 703 t.Errorf("%s: failed to parse IP constraint exclusions: %#v", test.name, cert.ExcludedIPRanges) 704 } 705 706 if len(cert.PermittedEmailAddresses) != 1 || cert.PermittedEmailAddresses[0] != "foo@example.com" { 707 t.Errorf("%s: failed to parse permitted email addreses: %#v", test.name, cert.PermittedEmailAddresses) 708 } 709 710 if len(cert.ExcludedEmailAddresses) != 2 || cert.ExcludedEmailAddresses[0] != ".example.com" || cert.ExcludedEmailAddresses[1] != "example.com" { 711 t.Errorf("%s: failed to parse excluded email addreses: %#v", test.name, cert.ExcludedEmailAddresses) 712 } 713 714 if len(cert.PermittedURIDomains) != 2 || cert.PermittedURIDomains[0] != ".bar.com" || cert.PermittedURIDomains[1] != "bar.com" { 715 t.Errorf("%s: failed to parse permitted URIs: %#v", test.name, cert.PermittedURIDomains) 716 } 717 718 if len(cert.ExcludedURIDomains) != 2 || cert.ExcludedURIDomains[0] != ".bar2.com" || cert.ExcludedURIDomains[1] != "bar2.com" { 719 t.Errorf("%s: failed to parse excluded URIs: %#v", test.name, cert.ExcludedURIDomains) 720 } 721 722 if cert.Subject.CommonName != commonName { 723 t.Errorf("%s: subject wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Subject.CommonName, commonName) 724 } 725 726 if len(cert.Subject.Country) != 1 || cert.Subject.Country[0] != "NL" { 727 t.Errorf("%s: ExtraNames didn't override Country", test.name) 728 } 729 730 for _, ext := range cert.Extensions { 731 if ext.Id.Equal(oidExtensionSubjectAltName) { 732 if ext.Critical { 733 t.Fatal("SAN extension is marked critical") 734 } 735 } 736 } 737 738 found := false 739 for _, atv := range cert.Subject.Names { 740 if atv.Type.Equal([]int{2, 5, 4, 42}) { 741 found = true 742 break 743 } 744 } 745 if !found { 746 t.Errorf("%s: Names didn't contain oid 2.5.4.42 from ExtraNames", test.name) 747 } 748 749 if cert.Issuer.CommonName != commonName { 750 t.Errorf("%s: issuer wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Issuer.CommonName, commonName) 751 } 752 753 if cert.SignatureAlgorithm != test.sigAlgo { 754 t.Errorf("%s: SignatureAlgorithm wasn't copied from template. Got %v, want %v", test.name, cert.SignatureAlgorithm, test.sigAlgo) 755 } 756 757 if !reflect.DeepEqual(cert.ExtKeyUsage, testExtKeyUsage) { 758 t.Errorf("%s: extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.ExtKeyUsage, testExtKeyUsage) 759 } 760 761 if !reflect.DeepEqual(cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) { 762 t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) 763 } 764 765 if !reflect.DeepEqual(cert.OCSPServer, template.OCSPServer) { 766 t.Errorf("%s: OCSP servers differ from template. Got %v, want %v", test.name, cert.OCSPServer, template.OCSPServer) 767 } 768 769 if !reflect.DeepEqual(cert.IssuingCertificateURL, template.IssuingCertificateURL) { 770 t.Errorf("%s: Issuing certificate URLs differ from template. Got %v, want %v", test.name, cert.IssuingCertificateURL, template.IssuingCertificateURL) 771 } 772 773 if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) { 774 t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames) 775 } 776 777 if !reflect.DeepEqual(cert.EmailAddresses, template.EmailAddresses) { 778 t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses) 779 } 780 781 if len(cert.URIs) != 1 || cert.URIs[0].String() != "https://foo.com/wibble#foo" { 782 t.Errorf("%s: URIs differ from template. Got %v, want %v", test.name, cert.URIs, template.URIs) 783 } 784 785 if !reflect.DeepEqual(cert.IPAddresses, template.IPAddresses) { 786 t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses) 787 } 788 789 if !reflect.DeepEqual(cert.CRLDistributionPoints, template.CRLDistributionPoints) { 790 t.Errorf("%s: CRL distribution points differ from template. Got %v, want %v", test.name, cert.CRLDistributionPoints, template.CRLDistributionPoints) 791 } 792 793 if !bytes.Equal(cert.SubjectKeyId, []byte{4, 3, 2, 1}) { 794 t.Errorf("%s: ExtraExtensions didn't override SubjectKeyId", test.name) 795 } 796 797 if !bytes.Contains(derBytes, extraExtensionData) { 798 t.Errorf("%s: didn't find extra extension in DER output", test.name) 799 } 800 801 if test.checkSig { 802 err = cert.CheckSignatureFrom(cert) 803 if err != nil { 804 t.Errorf("%s: signature verification failed: %s", test.name, err) 805 } 806 } 807 } 808 } 809 810 // Self-signed certificate using ECDSA with SHA1 & secp256r1 811 var ecdsaSHA1CertPem = ` 812 -----BEGIN CERTIFICATE----- 813 MIICDjCCAbUCCQDF6SfN0nsnrjAJBgcqhkjOPQQBMIGPMQswCQYDVQQGEwJVUzET 814 MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEVMBMG 815 A1UECgwMR29vZ2xlLCBJbmMuMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG 816 CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIwMjAyMDUw 817 WhcNMjIwNTE4MjAyMDUwWjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm 818 b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTATBgNVBAoMDEdvb2dsZSwg 819 SW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAhBgkqhkiG9w0BCQEWFGdv 820 bGFuZy1kZXZAZ21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/Wgn 821 WQDo5+bz71T0327ERgd5SDDXFbXLpzIZDXTkjpe8QTEbsF+ezsQfrekrpDPC4Cd3 822 P9LY0tG+aI8IyVKdUjAJBgcqhkjOPQQBA0gAMEUCIGlsqMcRqWVIWTD6wXwe6Jk2 823 DKxL46r/FLgJYnzBEH99AiEA3fBouObsvV1R3oVkb4BQYnD4/4LeId6lAT43YvyV 824 a/A= 825 -----END CERTIFICATE----- 826 ` 827 828 // Self-signed certificate using ECDSA with SHA256 & secp256r1 829 var ecdsaSHA256p256CertPem = ` 830 -----BEGIN CERTIFICATE----- 831 MIICDzCCAbYCCQDlsuMWvgQzhTAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCVVMx 832 EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT 833 BgNVBAoMDEdvb2dsZSwgSW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAh 834 BgkqhkiG9w0BCQEWFGdvbGFuZy1kZXZAZ21haWwuY29tMB4XDTEyMDUyMTAwMTkx 835 NloXDTIyMDUxOTAwMTkxNlowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp 836 Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYDVQQKDAxHb29nbGUs 837 IEluYy4xFzAVBgNVBAMMDnd3dy5nb29nbGUuY29tMSMwIQYJKoZIhvcNAQkBFhRn 838 b2xhbmctZGV2QGdtYWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPMt 839 2ErhxAty5EJRu9yM+MTy+hUXm3pdW1ensAv382KoGExSXAFWP7pjJnNtHO+XSwVm 840 YNtqjcAGFKpweoN//kQwCgYIKoZIzj0EAwIDRwAwRAIgIYSaUA/IB81gjbIw/hUV 841 70twxJr5EcgOo0hLp3Jm+EYCIFDO3NNcgmURbJ1kfoS3N/0O+irUtoPw38YoNkqJ 842 h5wi 843 -----END CERTIFICATE----- 844 ` 845 846 // Self-signed certificate using ECDSA with SHA256 & secp384r1 847 var ecdsaSHA256p384CertPem = ` 848 -----BEGIN CERTIFICATE----- 849 MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx 850 EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS 851 BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG 852 CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0 853 WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm 854 b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg 855 SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s 856 YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK 857 jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze 858 qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI 859 zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr 860 PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh 861 3yILeYQzllt/g0rKVRk= 862 -----END CERTIFICATE----- 863 ` 864 865 // Self-signed certificate using ECDSA with SHA384 & secp521r1 866 var ecdsaSHA384p521CertPem = ` 867 -----BEGIN CERTIFICATE----- 868 MIICljCCAfcCCQDhp1AFD/ahKjAKBggqhkjOPQQDAzCBjjELMAkGA1UEBhMCVVMx 869 EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS 870 BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG 871 CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMTUwNDI5 872 WhcNMjIwNTE5MTUwNDI5WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm 873 b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg 874 SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s 875 YW5nLWRldkBnbWFpbC5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACqx9Rv 876 IssRs1LWYcNN+WffwlHw4Tv3y8/LIAA9MF1ZScIonU9nRMxt4a2uGJVCPDw6JHpz 877 PaYc0E9puLoE9AfKpwFr59Jkot7dBg55SKPEFkddoip/rvmN7NPAWjMBirOwjOkm 878 8FPthvPhGPqsu9AvgVuHu3PosWiHGNrhh379pva8MzAKBggqhkjOPQQDAwOBjAAw 879 gYgCQgEHNmswkUdPpHqrVxp9PvLVl+xxPuHBkT+75z9JizyxtqykHQo9Uh6SWCYH 880 BF9KLolo01wMt8DjoYP5Fb3j5MH7xwJCAbWZzTOp4l4DPkIvAh4LeC4VWbwPPyqh 881 kBg71w/iEcSY3wUKgHGcJJrObZw7wys91I5kENljqw/Samdr3ka+jBJa 882 -----END CERTIFICATE----- 883 ` 884 885 var ecdsaTests = []struct { 886 sigAlgo SignatureAlgorithm 887 pemCert string 888 }{ 889 {ECDSAWithSHA1, ecdsaSHA1CertPem}, 890 {ECDSAWithSHA256, ecdsaSHA256p256CertPem}, 891 {ECDSAWithSHA256, ecdsaSHA256p384CertPem}, 892 {ECDSAWithSHA384, ecdsaSHA384p521CertPem}, 893 } 894 895 func TestECDSA(t *testing.T) { 896 for i, test := range ecdsaTests { 897 pemBlock, _ := pem.Decode([]byte(test.pemCert)) 898 cert, err := ParseCertificate(pemBlock.Bytes) 899 if err != nil { 900 t.Errorf("%d: failed to parse certificate: %s", i, err) 901 continue 902 } 903 if sa := cert.SignatureAlgorithm; sa != test.sigAlgo { 904 t.Errorf("%d: signature algorithm is %v, want %v", i, sa, test.sigAlgo) 905 } 906 if parsedKey, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok { 907 t.Errorf("%d: wanted an ECDSA public key but found: %#v", i, parsedKey) 908 } 909 if pka := cert.PublicKeyAlgorithm; pka != ECDSA { 910 t.Errorf("%d: public key algorithm is %v, want ECDSA", i, pka) 911 } 912 if err = cert.CheckSignatureFrom(cert); err != nil { 913 t.Errorf("%d: certificate verification failed: %s", i, err) 914 } 915 } 916 } 917 918 // Self-signed certificate using DSA with SHA1 919 var dsaCertPem = `-----BEGIN CERTIFICATE----- 920 MIIEDTCCA82gAwIBAgIJALHPghaoxeDhMAkGByqGSM44BAMweTELMAkGA1UEBhMC 921 VVMxCzAJBgNVBAgTAk5DMQ8wDQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2ds 922 ZSwgSW5jMRIwEAYDVQQDEwlKb24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFs 923 bGllQGdvb2dsZS5jb20wHhcNMTEwNTE0MDMwMTQ1WhcNMTEwNjEzMDMwMTQ1WjB5 924 MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTkMxDzANBgNVBAcTBk5ld3RvbjEUMBIG 925 A1UEChMLR29vZ2xlLCBJbmMxEjAQBgNVBAMTCUpvbiBBbGxpZTEiMCAGCSqGSIb3 926 DQEJARYTam9uYWxsaWVAZ29vZ2xlLmNvbTCCAbcwggEsBgcqhkjOOAQBMIIBHwKB 927 gQC8hLUnQ7FpFYu4WXTj6DKvXvz8QrJkNJCVMTpKAT7uBpobk32S5RrPKXocd4gN 928 8lyGB9ggS03EVlEwXvSmO0DH2MQtke2jl9j1HLydClMf4sbx5V6TV9IFw505U1iW 929 jL7awRMgxge+FsudtJK254FjMFo03ZnOQ8ZJJ9E6AEDrlwIVAJpnBn9moyP11Ox5 930 Asc/5dnjb6dPAoGBAJFHd4KVv1iTVCvEG6gGiYop5DJh28hUQcN9kul+2A0yPUSC 931 X93oN00P8Vh3eYgSaCWZsha7zDG53MrVJ0Zf6v/X/CoZNhLldeNOepivTRAzn+Rz 932 kKUYy5l1sxYLHQKF0UGNCXfFKZT0PCmgU+PWhYNBBMn6/cIh44vp85ideo5CA4GE 933 AAKBgFmifCafzeRaohYKXJgMGSEaggCVCRq5xdyDCat+wbOkjC4mfG01/um3G8u5 934 LxasjlWRKTR/tcAL7t0QuokVyQaYdVypZXNaMtx1db7YBuHjj3aP+8JOQRI9xz8c 935 bp5NDJ5pISiFOv4p3GZfqZPcqckDt78AtkQrmnal2txhhjF6o4HeMIHbMB0GA1Ud 936 DgQWBBQVyyr7hO11ZFFpWX50298Sa3V+rzCBqwYDVR0jBIGjMIGggBQVyyr7hO11 937 ZFFpWX50298Sa3V+r6F9pHsweTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5DMQ8w 938 DQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2dsZSwgSW5jMRIwEAYDVQQDEwlK 939 b24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFsbGllQGdvb2dsZS5jb22CCQCx 940 z4IWqMXg4TAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUPtn/5j8Q1jJI 941 7ggOIsgrhgUdjGQCFCsmDq1H11q9+9Wp9IMeGrTSKHIM 942 -----END CERTIFICATE----- 943 ` 944 945 func TestParseCertificateWithDsaPublicKey(t *testing.T) { 946 expectedKey := &dsa.PublicKey{ 947 Parameters: dsa.Parameters{ 948 P: bigFromHexString("00BC84B52743B169158BB85974E3E832AF5EFCFC42B264349095313A4A013EEE069A1B937D92E51ACF297A1C77880DF25C8607D8204B4DC45651305EF4A63B40C7D8C42D91EDA397D8F51CBC9D0A531FE2C6F1E55E9357D205C39D395358968CBEDAC11320C607BE16CB9DB492B6E78163305A34DD99CE43C64927D13A0040EB97"), 949 Q: bigFromHexString("009A67067F66A323F5D4EC7902C73FE5D9E36FA74F"), 950 G: bigFromHexString("009147778295BF5893542BC41BA806898A29E43261DBC85441C37D92E97ED80D323D44825FDDE8374D0FF15877798812682599B216BBCC31B9DCCAD527465FEAFFD7FC2A193612E575E34E7A98AF4D10339FE47390A518CB9975B3160B1D0285D1418D0977C52994F43C29A053E3D685834104C9FAFDC221E38BE9F3989D7A8E42"), 951 }, 952 Y: bigFromHexString("59A27C269FCDE45AA2160A5C980C19211A820095091AB9C5DC8309AB7EC1B3A48C2E267C6D35FEE9B71BCBB92F16AC8E559129347FB5C00BEEDD10BA8915C90698755CA965735A32DC7575BED806E1E38F768FFBC24E41123DC73F1C6E9E4D0C9E692128853AFE29DC665FA993DCA9C903B7BF00B6442B9A76A5DADC6186317A"), 953 } 954 pemBlock, _ := pem.Decode([]byte(dsaCertPem)) 955 cert, err := ParseCertificate(pemBlock.Bytes) 956 if err != nil { 957 t.Fatalf("Failed to parse certificate: %s", err) 958 } 959 if cert.PublicKeyAlgorithm != DSA { 960 t.Errorf("Parsed key algorithm was not DSA") 961 } 962 parsedKey, ok := cert.PublicKey.(*dsa.PublicKey) 963 if !ok { 964 t.Fatalf("Parsed key was not a DSA key: %s", err) 965 } 966 if expectedKey.Y.Cmp(parsedKey.Y) != 0 || 967 expectedKey.P.Cmp(parsedKey.P) != 0 || 968 expectedKey.Q.Cmp(parsedKey.Q) != 0 || 969 expectedKey.G.Cmp(parsedKey.G) != 0 { 970 t.Fatal("Parsed key differs from expected key") 971 } 972 } 973 974 func TestParseCertificateWithDSASignatureAlgorithm(t *testing.T) { 975 pemBlock, _ := pem.Decode([]byte(dsaCertPem)) 976 cert, err := ParseCertificate(pemBlock.Bytes) 977 if err != nil { 978 t.Fatalf("Failed to parse certificate: %s", err) 979 } 980 if cert.SignatureAlgorithm != DSAWithSHA1 { 981 t.Errorf("Parsed signature algorithm was not DSAWithSHA1") 982 } 983 } 984 985 func TestVerifyCertificateWithDSASignature(t *testing.T) { 986 pemBlock, _ := pem.Decode([]byte(dsaCertPem)) 987 cert, err := ParseCertificate(pemBlock.Bytes) 988 if err != nil { 989 t.Fatalf("Failed to parse certificate: %s", err) 990 } 991 // test cert is self-signed 992 if err = cert.CheckSignatureFrom(cert); err == nil { 993 t.Fatalf("Expected error verifying DSA certificate") 994 } 995 } 996 997 var rsaPSSSelfSignedPEM = `-----BEGIN CERTIFICATE----- 998 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 1031 -----END CERTIFICATE-----` 1032 1033 // openssl req -newkey rsa:2048 -keyout test.key -sha256 -sigopt \ 1034 // rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 -sigopt rsa_mgf1_md:sha256 \ 1035 // -x509 -days 3650 -nodes -subj '/C=US/ST=CA/L=SF/O=Test/CN=Test' -out \ 1036 // test.pem 1037 var rsaPSSSelfSignedOpenSSL110PEM = `-----BEGIN CERTIFICATE----- 1038 MIIDwDCCAnigAwIBAgIJAM9LAMHTE5xpMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZI 1039 AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgMEUxCzAJBgNV 1040 BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDTALBgNVBAoMBFRlc3Qx 1041 DTALBgNVBAMMBFRlc3QwHhcNMTgwMjIyMjIxMzE4WhcNMjgwMjIwMjIxMzE4WjBF 1042 MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMQ0wCwYDVQQK 1043 DARUZXN0MQ0wCwYDVQQDDARUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 1044 CgKCAQEA4Zrsydod+GoTAJLLutWNF87qhhVPBsK1zB1Gj+NAAe4+VbrZ1E41H1wp 1045 qITx7DA8DRtJEf+NqrTAnAdZWBG/tAOA5LfXVax0ZSQtLnYLSeylLoMtDyY3eFAj 1046 TmuTOoyVy6raktowCnHCh01NsstqqTfrx6SbmzOmDmKTkq/I+7K0MCVsn41xRDVM 1047 +ShD0WGFGioEGoiWnFSWupxJDA3Q6jIDEygVwNKHwnhv/2NgG2kqZzrZSQA67en0 1048 iKAXtoDNPpmyD5oS9YbEJ+2Nbm7oLeON30i6kZvXKIzJXx+UWViazHZqnsi5rQ8G 1049 RHF+iVFXsqd0MzDKmkKOT5FDhrsbKQIDAQABo1MwUTAdBgNVHQ4EFgQU9uFY/nlg 1050 gLH00NBnr/o7QvpN9ugwHwYDVR0jBBgwFoAU9uFY/nlggLH00NBnr/o7QvpN9ugw 1051 DwYDVR0TAQH/BAUwAwEB/zA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEa 1052 MBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIAOCAQEAhJzpwxBNGKvzKWDe 1053 WLqv6RMrl/q4GcH3b7M9wjxe0yOm4F+Tb2zJ7re4h+D39YkJf8cX1NV9UQVu6z4s 1054 Fvo2kmlR0qZOXAg5augmCQ1xS0WHFoF6B52anNzHkZQbAIYJ3kGoFsUHzs7Sz7F/ 1055 656FsRpHA9UzJQ3avPPMrA4Y4aoJ7ANJ6XIwTrdWrhULOVuvYRLCl4CdTVztVFX6 1056 wxX8nS1ISYd8jXPUMgsBKVbWufvLoIymMJW8CZbpprVZel5zFn0bmPrON8IHS30w 1057 Gs+ITJjKEnZgXmAQ25SLKVzkZkBcGANs2GsdHNJ370Puisy0FIPD2NXR5uASAf7J 1058 +w9fjQ== 1059 -----END CERTIFICATE-----` 1060 1061 func TestRSAPSSSelfSigned(t *testing.T) { 1062 for i, pemBlock := range []string{rsaPSSSelfSignedPEM, rsaPSSSelfSignedOpenSSL110PEM} { 1063 der, _ := pem.Decode([]byte(pemBlock)) 1064 if der == nil { 1065 t.Errorf("#%d: failed to find PEM block", i) 1066 continue 1067 } 1068 1069 cert, err := ParseCertificate(der.Bytes) 1070 if err != nil { 1071 t.Errorf("#%d: failed to parse: %s", i, err) 1072 continue 1073 } 1074 1075 if err = cert.CheckSignatureFrom(cert); err != nil { 1076 t.Errorf("#%d: signature check failed: %s", i, err) 1077 continue 1078 } 1079 } 1080 } 1081 1082 const ed25519Certificate = ` 1083 Certificate: 1084 Data: 1085 Version: 3 (0x2) 1086 Serial Number: 1087 0c:83:d8:21:2b:82:cb:23:98:23:63:e2:f7:97:8a:43:5b:f3:bd:92 1088 Signature Algorithm: ED25519 1089 Issuer: CN = Ed25519 test certificate 1090 Validity 1091 Not Before: May 6 17:27:16 2019 GMT 1092 Not After : Jun 5 17:27:16 2019 GMT 1093 Subject: CN = Ed25519 test certificate 1094 Subject Public Key Info: 1095 Public Key Algorithm: ED25519 1096 ED25519 Public-Key: 1097 pub: 1098 36:29:c5:6c:0d:4f:14:6c:81:d0:ff:75:d3:6a:70: 1099 5f:69:cd:0f:4d:66:d5:da:98:7e:82:49:89:a3:8a: 1100 3c:fa 1101 X509v3 extensions: 1102 X509v3 Subject Key Identifier: 1103 09:3B:3A:9D:4A:29:D8:95:FF:68:BE:7B:43:54:72:E0:AD:A2:E3:AE 1104 X509v3 Authority Key Identifier: 1105 keyid:09:3B:3A:9D:4A:29:D8:95:FF:68:BE:7B:43:54:72:E0:AD:A2:E3:AE 1106 1107 X509v3 Basic Constraints: critical 1108 CA:TRUE 1109 Signature Algorithm: ED25519 1110 53:a5:58:1c:2c:3b:2a:9e:ac:9d:4e:a5:1d:5f:5d:6d:a6:b5: 1111 08:de:12:82:f3:97:20:ae:fa:d8:98:f4:1a:83:32:6b:91:f5: 1112 24:1d:c4:20:7f:2c:e2:4d:da:13:3b:6d:54:1a:d2:a8:28:dc: 1113 60:b9:d4:f4:78:4b:3c:1c:91:00 1114 -----BEGIN CERTIFICATE----- 1115 MIIBWzCCAQ2gAwIBAgIUDIPYISuCyyOYI2Pi95eKQ1vzvZIwBQYDK2VwMCMxITAf 1116 BgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZpY2F0ZTAeFw0xOTA1MDYxNzI3MTZa 1117 Fw0xOTA2MDUxNzI3MTZaMCMxITAfBgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZp 1118 Y2F0ZTAqMAUGAytlcAMhADYpxWwNTxRsgdD/ddNqcF9pzQ9NZtXamH6CSYmjijz6 1119 o1MwUTAdBgNVHQ4EFgQUCTs6nUop2JX/aL57Q1Ry4K2i464wHwYDVR0jBBgwFoAU 1120 CTs6nUop2JX/aL57Q1Ry4K2i464wDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXADQQBT 1121 pVgcLDsqnqydTqUdX11tprUI3hKC85cgrvrYmPQagzJrkfUkHcQgfyziTdoTO21U 1122 GtKoKNxgudT0eEs8HJEA 1123 -----END CERTIFICATE-----` 1124 1125 func TestEd25519SelfSigned(t *testing.T) { 1126 der, _ := pem.Decode([]byte(ed25519Certificate)) 1127 if der == nil { 1128 t.Fatalf("Failed to find PEM block") 1129 } 1130 1131 cert, err := ParseCertificate(der.Bytes) 1132 if err != nil { 1133 t.Fatalf("Failed to parse: %s", err) 1134 } 1135 1136 if cert.PublicKeyAlgorithm != Ed25519 { 1137 t.Fatalf("Parsed key algorithm was not Ed25519") 1138 } 1139 parsedKey, ok := cert.PublicKey.(ed25519.PublicKey) 1140 if !ok { 1141 t.Fatalf("Parsed key was not an Ed25519 key: %s", err) 1142 } 1143 if len(parsedKey) != ed25519.PublicKeySize { 1144 t.Fatalf("Invalid Ed25519 key") 1145 } 1146 1147 if err = cert.CheckSignatureFrom(cert); err != nil { 1148 t.Fatalf("Signature check failed: %s", err) 1149 } 1150 } 1151 1152 const pemCertificate = `-----BEGIN CERTIFICATE----- 1153 MIIDATCCAemgAwIBAgIRAKQkkrFx1T/dgB/Go/xBM5swDQYJKoZIhvcNAQELBQAw 1154 EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjA4MTcyMDM2MDdaFw0xNzA4MTcyMDM2 1155 MDdaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw 1156 ggEKAoIBAQDAoJtjG7M6InsWwIo+l3qq9u+g2rKFXNu9/mZ24XQ8XhV6PUR+5HQ4 1157 jUFWC58ExYhottqK5zQtKGkw5NuhjowFUgWB/VlNGAUBHtJcWR/062wYrHBYRxJH 1158 qVXOpYKbIWwFKoXu3hcpg/CkdOlDWGKoZKBCwQwUBhWE7MDhpVdQ+ZljUJWL+FlK 1159 yQK5iRsJd5TGJ6VUzLzdT4fmN2DzeK6GLeyMpVpU3sWV90JJbxWQ4YrzkKzYhMmB 1160 EcpXTG2wm+ujiHU/k2p8zlf8Sm7VBM/scmnMFt0ynNXop4FWvJzEm1G0xD2t+e2I 1161 5Utr04dOZPCgkm++QJgYhtZvgW7ZZiGTAgMBAAGjUjBQMA4GA1UdDwEB/wQEAwIF 1162 oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBsGA1UdEQQUMBKC 1163 EHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBADpqKQxrthH5InC7 1164 X96UP0OJCu/lLEMkrjoEWYIQaFl7uLPxKH5AmQPH4lYwF7u7gksR7owVG9QU9fs6 1165 1fK7II9CVgCd/4tZ0zm98FmU4D0lHGtPARrrzoZaqVZcAvRnFTlPX5pFkPhVjjai 1166 /mkxX9LpD8oK1445DFHxK5UjLMmPIIWd8EOi+v5a+hgGwnJpoW7hntSl8kHMtTmy 1167 fnnktsblSUV4lRCit0ymC7Ojhe+gzCCwkgs5kDzVVag+tnl/0e2DloIjASwOhpbH 1168 KVcg7fBd484ht/sS+l0dsB4KDOSpd8JzVDMF8OZqlaydizoJO0yWr9GbCN1+OKq5 1169 EhLrEqU= 1170 -----END CERTIFICATE-----` 1171 1172 const ed25519CRLCertificate = ` 1173 Certificate: 1174 Data: 1175 Version: 3 (0x2) 1176 Serial Number: 1177 7a:07:a0:9d:14:04:16:fc:1f:d8:e5:fe:d1:1d:1f:8d 1178 Signature Algorithm: ED25519 1179 Issuer: CN = Ed25519 CRL Test CA 1180 Validity 1181 Not Before: Oct 30 01:20:20 2019 GMT 1182 Not After : Dec 31 23:59:59 9999 GMT 1183 Subject: CN = Ed25519 CRL Test CA 1184 Subject Public Key Info: 1185 Public Key Algorithm: ED25519 1186 ED25519 Public-Key: 1187 pub: 1188 95:73:3b:b0:06:2a:31:5a:b6:a7:a6:6e:ef:71:df: 1189 ac:6f:6b:39:03:85:5e:63:4b:f8:a6:0f:68:c6:6f: 1190 75:21 1191 X509v3 extensions: 1192 X509v3 Key Usage: critical 1193 Digital Signature, Certificate Sign, CRL Sign 1194 X509v3 Extended Key Usage: 1195 TLS Web Client Authentication, TLS Web Server Authentication, OCSP Signing 1196 X509v3 Basic Constraints: critical 1197 CA:TRUE 1198 X509v3 Subject Key Identifier: 1199 B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60 1200 X509v3 Authority Key Identifier: 1201 keyid:B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60 1202 1203 Signature Algorithm: ED25519 1204 fc:3e:14:ea:bb:70:c2:6f:38:34:70:bc:c8:a7:f4:7c:0d:1e: 1205 28:d7:2a:9f:22:8a:45:e8:02:76:84:1e:2d:64:2d:1e:09:b5: 1206 29:71:1f:95:8a:4e:79:87:51:60:9a:e7:86:40:f6:60:c7:d1: 1207 ee:68:76:17:1d:90:cc:92:93:07 1208 -----BEGIN CERTIFICATE----- 1209 MIIBijCCATygAwIBAgIQegegnRQEFvwf2OX+0R0fjTAFBgMrZXAwHjEcMBoGA1UE 1210 AxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAgFw0xOTEwMzAwMTIwMjBaGA85OTk5MTIz 1211 MTIzNTk1OVowHjEcMBoGA1UEAxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAqMAUGAytl 1212 cAMhAJVzO7AGKjFatqembu9x36xvazkDhV5jS/imD2jGb3Uho4GNMIGKMA4GA1Ud 1213 DwEB/wQEAwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUF 1214 BwMJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLcX2hbqxe0fGElE09LjoDUK 1215 gZNgMB8GA1UdIwQYMBaAFLcX2hbqxe0fGElE09LjoDUKgZNgMAUGAytlcANBAPw+ 1216 FOq7cMJvODRwvMin9HwNHijXKp8iikXoAnaEHi1kLR4JtSlxH5WKTnmHUWCa54ZA 1217 9mDH0e5odhcdkMySkwc= 1218 -----END CERTIFICATE-----` 1219 1220 var ed25519CRLKey = testingKey(`-----BEGIN TEST KEY----- 1221 MC4CAQAwBQYDK2VwBCIEINdKh2096vUBYu4EIFpjShsUSh3vimKya1sQ1YTT4RZG 1222 -----END TEST KEY-----`) 1223 1224 func TestCRLCreation(t *testing.T) { 1225 block, _ := pem.Decode([]byte(pemPrivateKey)) 1226 privRSA, _ := ParsePKCS1PrivateKey(block.Bytes) 1227 block, _ = pem.Decode([]byte(pemCertificate)) 1228 certRSA, _ := ParseCertificate(block.Bytes) 1229 1230 block, _ = pem.Decode([]byte(ed25519CRLKey)) 1231 privEd25519, _ := ParsePKCS8PrivateKey(block.Bytes) 1232 block, _ = pem.Decode([]byte(ed25519CRLCertificate)) 1233 certEd25519, _ := ParseCertificate(block.Bytes) 1234 1235 tests := []struct { 1236 name string 1237 priv interface{} 1238 cert *Certificate 1239 }{ 1240 {"RSA CA", privRSA, certRSA}, 1241 {"Ed25519 CA", privEd25519, certEd25519}, 1242 } 1243 1244 loc := time.FixedZone("Oz/Atlantis", int((2 * time.Hour).Seconds())) 1245 1246 now := time.Unix(1000, 0).In(loc) 1247 nowUTC := now.UTC() 1248 expiry := time.Unix(10000, 0) 1249 1250 revokedCerts := []pkix.RevokedCertificate{ 1251 { 1252 SerialNumber: big.NewInt(1), 1253 RevocationTime: nowUTC, 1254 }, 1255 { 1256 SerialNumber: big.NewInt(42), 1257 // RevocationTime should be converted to UTC before marshaling. 1258 RevocationTime: now, 1259 }, 1260 } 1261 expectedCerts := []pkix.RevokedCertificate{ 1262 { 1263 SerialNumber: big.NewInt(1), 1264 RevocationTime: nowUTC, 1265 }, 1266 { 1267 SerialNumber: big.NewInt(42), 1268 RevocationTime: nowUTC, 1269 }, 1270 } 1271 1272 for _, test := range tests { 1273 crlBytes, err := test.cert.CreateCRL(rand.Reader, test.priv, revokedCerts, now, expiry) 1274 if err != nil { 1275 t.Errorf("%s: error creating CRL: %s", test.name, err) 1276 } 1277 1278 parsedCRL, err := ParseDERCRL(crlBytes) 1279 if err != nil { 1280 t.Errorf("%s: error reparsing CRL: %s", test.name, err) 1281 } 1282 if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) { 1283 t.Errorf("%s: RevokedCertificates mismatch: got %v; want %v.", test.name, 1284 parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) 1285 } 1286 } 1287 } 1288 1289 func fromBase64(in string) []byte { 1290 out := make([]byte, base64.StdEncoding.DecodedLen(len(in))) 1291 n, err := base64.StdEncoding.Decode(out, []byte(in)) 1292 if err != nil { 1293 panic("failed to base64 decode") 1294 } 1295 return out[:n] 1296 } 1297 1298 func TestParseDERCRL(t *testing.T) { 1299 derBytes := fromBase64(derCRLBase64) 1300 certList, err := ParseDERCRL(derBytes) 1301 if err != nil { 1302 t.Errorf("error parsing: %s", err) 1303 return 1304 } 1305 numCerts := len(certList.TBSCertList.RevokedCertificates) 1306 expected := 88 1307 if numCerts != expected { 1308 t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected) 1309 } 1310 1311 if certList.HasExpired(time.Unix(1302517272, 0)) { 1312 t.Errorf("CRL has expired (but shouldn't have)") 1313 } 1314 1315 // Can't check the signature here without a package cycle. 1316 } 1317 1318 func TestCRLWithoutExpiry(t *testing.T) { 1319 derBytes := fromBase64("MIHYMIGZMAkGByqGSM44BAMwEjEQMA4GA1UEAxMHQ2FybERTUxcNOTkwODI3MDcwMDAwWjBpMBMCAgDIFw05OTA4MjIwNzAwMDBaMBMCAgDJFw05OTA4MjIwNzAwMDBaMBMCAgDTFw05OTA4MjIwNzAwMDBaMBMCAgDSFw05OTA4MjIwNzAwMDBaMBMCAgDUFw05OTA4MjQwNzAwMDBaMAkGByqGSM44BAMDLwAwLAIUfmVSdjP+NHMX0feW+aDU2G1cfT0CFAJ6W7fVWxjBz4fvftok8yqDnDWh") 1320 certList, err := ParseDERCRL(derBytes) 1321 if err != nil { 1322 t.Fatal(err) 1323 } 1324 if !certList.TBSCertList.NextUpdate.IsZero() { 1325 t.Errorf("NextUpdate is not the zero value") 1326 } 1327 } 1328 1329 func TestParsePEMCRL(t *testing.T) { 1330 pemBytes := fromBase64(pemCRLBase64) 1331 certList, err := ParseCRL(pemBytes) 1332 if err != nil { 1333 t.Errorf("error parsing: %s", err) 1334 return 1335 } 1336 numCerts := len(certList.TBSCertList.RevokedCertificates) 1337 expected := 2 1338 if numCerts != expected { 1339 t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected) 1340 } 1341 1342 if certList.HasExpired(time.Unix(1302517272, 0)) { 1343 t.Errorf("CRL has expired (but shouldn't have)") 1344 } 1345 1346 // Can't check the signature here without a package cycle. 1347 } 1348 1349 func TestImports(t *testing.T) { 1350 if testing.Short() { 1351 t.Skip("skipping in -short mode") 1352 } 1353 testenv.MustHaveGoRun(t) 1354 1355 if out, err := exec.Command(testenv.GoToolPath(t), "run", "x509_test_import.go").CombinedOutput(); err != nil { 1356 t.Errorf("failed to run x509_test_import.go: %s\n%s", err, out) 1357 } 1358 } 1359 1360 const derCRLBase64 = "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" 1361 1362 const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RFFZSktvWklodmNOQVFFRkJRQXdiREVhTUJnR0ExVUVDaE1SVWxOQklGTmxZM1Z5DQphWFI1SUVsdVl5NHhIakFjQmdOVkJBTVRGVkpUUVNCUWRXSnNhV01nVW05dmRDQkRRU0IyTVRFdU1Dd0dDU3FHDQpTSWIzRFFFSkFSWWZjbk5oYTJWdmJuSnZiM1J6YVdkdVFISnpZWE5sWTNWeWFYUjVMbU52YlJjTk1URXdNakl6DQpNVGt5T0RNd1doY05NVEV3T0RJeU1Ua3lPRE13V2pDQmpEQktBaEVBckRxb2g5RkhKSFhUN09QZ3V1bjQrQmNODQpNRGt4TVRBeU1UUXlOekE1V2pBbU1Bb0dBMVVkRlFRRENnRUpNQmdHQTFVZEdBUVJHQTh5TURBNU1URXdNakUwDQpNalExTlZvd1BnSVJBTEd6blowOTVQQjVhQU9MUGc1N2ZNTVhEVEF5TVRBeU16RTBOVEF4TkZvd0dqQVlCZ05WDQpIUmdFRVJnUE1qQXdNakV3TWpNeE5EVXdNVFJhb0RBd0xqQWZCZ05WSFNNRUdEQVdnQlQxVERGNlVRTS9MTmVMDQpsNWx2cUhHUXEzZzltekFMQmdOVkhSUUVCQUlDQUlRd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ1lFQUZVNUFzNk16DQpxNVBSc2lmYW9iUVBHaDFhSkx5QytNczVBZ2MwYld5QTNHQWR4dXI1U3BQWmVSV0NCamlQL01FSEJXSkNsQkhQDQpHUmNxNXlJZDNFakRrYUV5eFJhK2k2N0x6dmhJNmMyOUVlNks5cFNZd2ppLzdSVWhtbW5Qclh0VHhsTDBsckxyDQptUVFKNnhoRFJhNUczUUE0Q21VZHNITnZicnpnbUNZcHZWRT0NCi0tLS0tRU5EIFg1MDkgQ1JMLS0tLS0NCg0K" 1363 1364 func TestCreateCertificateRequest(t *testing.T) { 1365 random := rand.Reader 1366 1367 ecdsa256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 1368 if err != nil { 1369 t.Fatalf("Failed to generate ECDSA key: %s", err) 1370 } 1371 1372 ecdsa384Priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 1373 if err != nil { 1374 t.Fatalf("Failed to generate ECDSA key: %s", err) 1375 } 1376 1377 ecdsa521Priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) 1378 if err != nil { 1379 t.Fatalf("Failed to generate ECDSA key: %s", err) 1380 } 1381 1382 _, ed25519Priv, err := ed25519.GenerateKey(random) 1383 if err != nil { 1384 t.Fatalf("Failed to generate Ed25519 key: %s", err) 1385 } 1386 1387 tests := []struct { 1388 name string 1389 priv interface{} 1390 sigAlgo SignatureAlgorithm 1391 }{ 1392 {"RSA", testPrivateKey, SHA1WithRSA}, 1393 {"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1}, 1394 {"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1}, 1395 {"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1}, 1396 {"Ed25519", ed25519Priv, PureEd25519}, 1397 } 1398 1399 for _, test := range tests { 1400 template := CertificateRequest{ 1401 Subject: pkix.Name{ 1402 CommonName: "test.example.com", 1403 Organization: []string{"Σ Acme Co"}, 1404 }, 1405 SignatureAlgorithm: test.sigAlgo, 1406 DNSNames: []string{"test.example.com"}, 1407 EmailAddresses: []string{"gopher@golang.org"}, 1408 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, 1409 } 1410 1411 derBytes, err := CreateCertificateRequest(random, &template, test.priv) 1412 if err != nil { 1413 t.Errorf("%s: failed to create certificate request: %s", test.name, err) 1414 continue 1415 } 1416 1417 out, err := ParseCertificateRequest(derBytes) 1418 if err != nil { 1419 t.Errorf("%s: failed to create certificate request: %s", test.name, err) 1420 continue 1421 } 1422 1423 err = out.CheckSignature() 1424 if err != nil { 1425 t.Errorf("%s: failed to check certificate request signature: %s", test.name, err) 1426 continue 1427 } 1428 1429 if out.Subject.CommonName != template.Subject.CommonName { 1430 t.Errorf("%s: output subject common name and template subject common name don't match", test.name) 1431 } else if len(out.Subject.Organization) != len(template.Subject.Organization) { 1432 t.Errorf("%s: output subject organisation and template subject organisation don't match", test.name) 1433 } else if len(out.DNSNames) != len(template.DNSNames) { 1434 t.Errorf("%s: output DNS names and template DNS names don't match", test.name) 1435 } else if len(out.EmailAddresses) != len(template.EmailAddresses) { 1436 t.Errorf("%s: output email addresses and template email addresses don't match", test.name) 1437 } else if len(out.IPAddresses) != len(template.IPAddresses) { 1438 t.Errorf("%s: output IP addresses and template IP addresses names don't match", test.name) 1439 } 1440 } 1441 } 1442 1443 func marshalAndParseCSR(t *testing.T, template *CertificateRequest) *CertificateRequest { 1444 derBytes, err := CreateCertificateRequest(rand.Reader, template, testPrivateKey) 1445 if err != nil { 1446 t.Fatal(err) 1447 } 1448 1449 csr, err := ParseCertificateRequest(derBytes) 1450 if err != nil { 1451 t.Fatal(err) 1452 } 1453 1454 return csr 1455 } 1456 1457 func TestCertificateRequestOverrides(t *testing.T) { 1458 sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil, nil) 1459 if err != nil { 1460 t.Fatal(err) 1461 } 1462 1463 template := CertificateRequest{ 1464 Subject: pkix.Name{ 1465 CommonName: "test.example.com", 1466 Organization: []string{"Σ Acme Co"}, 1467 }, 1468 DNSNames: []string{"test.example.com"}, 1469 1470 // An explicit extension should override the DNSNames from the 1471 // template. 1472 ExtraExtensions: []pkix.Extension{ 1473 { 1474 Id: oidExtensionSubjectAltName, 1475 Value: sanContents, 1476 Critical: true, 1477 }, 1478 }, 1479 } 1480 1481 csr := marshalAndParseCSR(t, &template) 1482 1483 if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo.example.com" { 1484 t.Errorf("Extension did not override template. Got %v\n", csr.DNSNames) 1485 } 1486 1487 if len(csr.Extensions) != 1 || !csr.Extensions[0].Id.Equal(oidExtensionSubjectAltName) || !csr.Extensions[0].Critical { 1488 t.Errorf("SAN extension was not faithfully copied, got %#v", csr.Extensions) 1489 } 1490 1491 // If there is already an attribute with X.509 extensions then the 1492 // extra extensions should be added to it rather than creating a CSR 1493 // with two extension attributes. 1494 1495 template.Attributes = []pkix.AttributeTypeAndValueSET{ 1496 { 1497 Type: oidExtensionRequest, 1498 Value: [][]pkix.AttributeTypeAndValue{ 1499 { 1500 { 1501 Type: oidExtensionAuthorityInfoAccess, 1502 Value: []byte("foo"), 1503 }, 1504 }, 1505 }, 1506 }, 1507 } 1508 1509 csr = marshalAndParseCSR(t, &template) 1510 if l := len(csr.Attributes); l != 1 { 1511 t.Errorf("incorrect number of attributes: %d\n", l) 1512 } 1513 1514 if !csr.Attributes[0].Type.Equal(oidExtensionRequest) || 1515 len(csr.Attributes[0].Value) != 1 || 1516 len(csr.Attributes[0].Value[0]) != 2 { 1517 t.Errorf("bad attributes: %#v\n", csr.Attributes) 1518 } 1519 1520 sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil, nil) 1521 if err != nil { 1522 t.Fatal(err) 1523 } 1524 1525 // Extensions in Attributes should override those in ExtraExtensions. 1526 template.Attributes[0].Value[0] = append(template.Attributes[0].Value[0], pkix.AttributeTypeAndValue{ 1527 Type: oidExtensionSubjectAltName, 1528 Value: sanContents2, 1529 }) 1530 1531 csr = marshalAndParseCSR(t, &template) 1532 1533 if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo2.example.com" { 1534 t.Errorf("Attributes did not override ExtraExtensions. Got %v\n", csr.DNSNames) 1535 } 1536 } 1537 1538 func TestParseCertificateRequest(t *testing.T) { 1539 for _, csrBase64 := range csrBase64Array { 1540 csrBytes := fromBase64(csrBase64) 1541 csr, err := ParseCertificateRequest(csrBytes) 1542 if err != nil { 1543 t.Fatalf("failed to parse CSR: %s", err) 1544 } 1545 1546 if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher@golang.org" { 1547 t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses) 1548 } 1549 1550 if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" { 1551 t.Errorf("incorrect DNS names found: %v", csr.DNSNames) 1552 } 1553 1554 if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" { 1555 t.Errorf("incorrect Subject name: %v", csr.Subject) 1556 } 1557 1558 found := false 1559 for _, e := range csr.Extensions { 1560 if e.Id.Equal(oidExtensionBasicConstraints) { 1561 found = true 1562 break 1563 } 1564 } 1565 if !found { 1566 t.Errorf("basic constraints extension not found in CSR") 1567 } 1568 } 1569 } 1570 1571 func TestCriticalFlagInCSRRequestedExtensions(t *testing.T) { 1572 // This CSR contains an extension request where the extensions have a 1573 // critical flag in them. In the past we failed to handle this. 1574 const csrBase64 = "MIICrTCCAZUCAQIwMzEgMB4GA1UEAwwXU0NFUCBDQSBmb3IgRGV2ZWxlciBTcmwxDzANBgNVBAsMBjQzNTk3MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALFMAJ7Zy9YyfgbNlbUWAW0LalNRMPs7aXmLANsCpjhnw3lLlfDPaLeWyKh1nK5I5ojaJOW6KIOSAcJkDUe3rrE0wR0RVt3UxArqs0R/ND3u5Q+bDQY2X1HAFUHzUzcdm5JRAIA355v90teMckaWAIlkRQjDE22Lzc6NAl64KOd1rqOUNj8+PfX6fSo20jm94Pp1+a6mfk3G/RUWVuSm7owO5DZI/Fsi2ijdmb4NUar6K/bDKYTrDFkzcqAyMfP3TitUtBp19Mp3B1yAlHjlbp/r5fSSXfOGHZdgIvp0WkLuK2u5eQrX5l7HMB/5epgUs3HQxKY6ljhh5wAjDwz//LsCAwEAAaA1MDMGCSqGSIb3DQEJDjEmMCQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQEFBQADggEBAAMq3bxJSPQEgzLYR/yaVvgjCDrc3zUbIwdOis6Go06Q4RnjH5yRaSZAqZQTDsPurQcnz2I39VMGEiSkFJFavf4QHIZ7QFLkyXadMtALc87tm17Ej719SbHcBSSZayR9VYJUNXRLayI6HvyUrmqcMKh+iX3WY3ICr59/wlM0tYa8DYN4yzmOa2Onb29gy3YlaF5A2AKAMmk003cRT9gY26mjpv7d21czOSSeNyVIoZ04IR9ee71vWTMdv0hu/af5kSjQ+ZG5/Qgc0+mnECLz/1gtxt1srLYbtYQ/qAY8oX1DCSGFS61tN/vl+4cxGMD/VGcGzADRLRHSlVqy2Qgss6Q=" 1575 1576 csrBytes := fromBase64(csrBase64) 1577 csr, err := ParseCertificateRequest(csrBytes) 1578 if err != nil { 1579 t.Fatalf("failed to parse CSR: %s", err) 1580 } 1581 1582 expected := []struct { 1583 Id asn1.ObjectIdentifier 1584 Value []byte 1585 }{ 1586 {oidExtensionBasicConstraints, fromBase64("MAYBAf8CAQA=")}, 1587 {oidExtensionKeyUsage, fromBase64("AwIChA==")}, 1588 } 1589 1590 if n := len(csr.Extensions); n != len(expected) { 1591 t.Fatalf("expected to find %d extensions but found %d", len(expected), n) 1592 } 1593 1594 for i, extension := range csr.Extensions { 1595 if !extension.Id.Equal(expected[i].Id) { 1596 t.Fatalf("extension #%d has unexpected type %v (expected %v)", i, extension.Id, expected[i].Id) 1597 } 1598 1599 if !bytes.Equal(extension.Value, expected[i].Value) { 1600 t.Fatalf("extension #%d has unexpected contents %x (expected %x)", i, extension.Value, expected[i].Value) 1601 } 1602 } 1603 } 1604 1605 // serialiseAndParse generates a self-signed certificate from template and 1606 // returns a parsed version of it. 1607 func serialiseAndParse(t *testing.T, template *Certificate) *Certificate { 1608 derBytes, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey) 1609 if err != nil { 1610 t.Fatalf("failed to create certificate: %s", err) 1611 return nil 1612 } 1613 1614 cert, err := ParseCertificate(derBytes) 1615 if err != nil { 1616 t.Fatalf("failed to parse certificate: %s", err) 1617 return nil 1618 } 1619 1620 return cert 1621 } 1622 1623 func TestMaxPathLenNotCA(t *testing.T) { 1624 template := &Certificate{ 1625 SerialNumber: big.NewInt(1), 1626 Subject: pkix.Name{ 1627 CommonName: "Σ Acme Co", 1628 }, 1629 NotBefore: time.Unix(1000, 0), 1630 NotAfter: time.Unix(100000, 0), 1631 1632 BasicConstraintsValid: true, 1633 IsCA: false, 1634 } 1635 if m := serialiseAndParse(t, template).MaxPathLen; m != -1 { 1636 t.Errorf("MaxPathLen should be -1 when IsCa is false, got %d", m) 1637 } 1638 1639 template.MaxPathLen = -1 1640 if m := serialiseAndParse(t, template).MaxPathLen; m != -1 { 1641 t.Errorf("MaxPathLen should be -1 when IsCa is false and MaxPathLen set to -1, got %d", m) 1642 } 1643 1644 template.MaxPathLen = 5 1645 if _, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey); err == nil { 1646 t.Error("specifying a MaxPathLen when IsCA is false should fail") 1647 } 1648 1649 template.MaxPathLen = 0 1650 template.MaxPathLenZero = true 1651 if _, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey); err == nil { 1652 t.Error("setting MaxPathLenZero when IsCA is false should fail") 1653 } 1654 1655 template.BasicConstraintsValid = false 1656 if m := serialiseAndParse(t, template).MaxPathLen; m != 0 { 1657 t.Errorf("Bad MaxPathLen should be ignored if BasicConstraintsValid is false, got %d", m) 1658 } 1659 } 1660 1661 func TestMaxPathLen(t *testing.T) { 1662 template := &Certificate{ 1663 SerialNumber: big.NewInt(1), 1664 Subject: pkix.Name{ 1665 CommonName: "Σ Acme Co", 1666 }, 1667 NotBefore: time.Unix(1000, 0), 1668 NotAfter: time.Unix(100000, 0), 1669 1670 BasicConstraintsValid: true, 1671 IsCA: true, 1672 } 1673 1674 cert1 := serialiseAndParse(t, template) 1675 if m := cert1.MaxPathLen; m != -1 { 1676 t.Errorf("Omitting MaxPathLen didn't turn into -1, got %d", m) 1677 } 1678 if cert1.MaxPathLenZero { 1679 t.Errorf("Omitting MaxPathLen resulted in MaxPathLenZero") 1680 } 1681 1682 template.MaxPathLen = 1 1683 cert2 := serialiseAndParse(t, template) 1684 if m := cert2.MaxPathLen; m != 1 { 1685 t.Errorf("Setting MaxPathLen didn't work. Got %d but set 1", m) 1686 } 1687 if cert2.MaxPathLenZero { 1688 t.Errorf("Setting MaxPathLen resulted in MaxPathLenZero") 1689 } 1690 1691 template.MaxPathLen = 0 1692 template.MaxPathLenZero = true 1693 cert3 := serialiseAndParse(t, template) 1694 if m := cert3.MaxPathLen; m != 0 { 1695 t.Errorf("Setting MaxPathLenZero didn't work, got %d", m) 1696 } 1697 if !cert3.MaxPathLenZero { 1698 t.Errorf("Setting MaxPathLen to zero didn't result in MaxPathLenZero") 1699 } 1700 } 1701 1702 func TestNoAuthorityKeyIdInSelfSignedCert(t *testing.T) { 1703 template := &Certificate{ 1704 SerialNumber: big.NewInt(1), 1705 Subject: pkix.Name{ 1706 CommonName: "Σ Acme Co", 1707 }, 1708 NotBefore: time.Unix(1000, 0), 1709 NotAfter: time.Unix(100000, 0), 1710 1711 BasicConstraintsValid: true, 1712 IsCA: true, 1713 SubjectKeyId: []byte{1, 2, 3, 4}, 1714 } 1715 1716 if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) != 0 { 1717 t.Fatalf("self-signed certificate contained default authority key id") 1718 } 1719 1720 template.AuthorityKeyId = []byte{1, 2, 3, 4} 1721 if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) == 0 { 1722 t.Fatalf("self-signed certificate erased explicit authority key id") 1723 } 1724 } 1725 1726 func TestNoSubjectKeyIdInCert(t *testing.T) { 1727 template := &Certificate{ 1728 SerialNumber: big.NewInt(1), 1729 Subject: pkix.Name{ 1730 CommonName: "Σ Acme Co", 1731 }, 1732 NotBefore: time.Unix(1000, 0), 1733 NotAfter: time.Unix(100000, 0), 1734 1735 BasicConstraintsValid: true, 1736 IsCA: true, 1737 } 1738 if cert := serialiseAndParse(t, template); len(cert.SubjectKeyId) == 0 { 1739 t.Fatalf("self-signed certificate did not generate subject key id using the public key") 1740 } 1741 1742 template.IsCA = false 1743 if cert := serialiseAndParse(t, template); len(cert.SubjectKeyId) != 0 { 1744 t.Fatalf("self-signed certificate generated subject key id when it isn't a CA") 1745 } 1746 1747 template.SubjectKeyId = []byte{1, 2, 3, 4} 1748 if cert := serialiseAndParse(t, template); len(cert.SubjectKeyId) == 0 { 1749 t.Fatalf("self-signed certificate erased explicit subject key id") 1750 } 1751 } 1752 1753 func TestASN1BitLength(t *testing.T) { 1754 tests := []struct { 1755 bytes []byte 1756 bitLen int 1757 }{ 1758 {nil, 0}, 1759 {[]byte{0x00}, 0}, 1760 {[]byte{0x00, 0x00}, 0}, 1761 {[]byte{0xf0}, 4}, 1762 {[]byte{0x88}, 5}, 1763 {[]byte{0xff}, 8}, 1764 {[]byte{0xff, 0x80}, 9}, 1765 {[]byte{0xff, 0x81}, 16}, 1766 } 1767 1768 for i, test := range tests { 1769 if got := asn1BitLength(test.bytes); got != test.bitLen { 1770 t.Errorf("#%d: calculated bit-length of %d for %x, wanted %d", i, got, test.bytes, test.bitLen) 1771 } 1772 } 1773 } 1774 1775 func TestVerifyEmptyCertificate(t *testing.T) { 1776 if _, err := new(Certificate).Verify(VerifyOptions{}); err != errNotParsed { 1777 t.Errorf("Verifying empty certificate resulted in unexpected error: %q (wanted %q)", err, errNotParsed) 1778 } 1779 } 1780 1781 func TestInsecureAlgorithmErrorString(t *testing.T) { 1782 tests := []struct { 1783 sa SignatureAlgorithm 1784 want string 1785 }{ 1786 {MD2WithRSA, "x509: cannot verify signature: insecure algorithm MD2-RSA"}, 1787 {-1, "x509: cannot verify signature: insecure algorithm -1"}, 1788 {0, "x509: cannot verify signature: insecure algorithm 0"}, 1789 {9999, "x509: cannot verify signature: insecure algorithm 9999"}, 1790 } 1791 for i, tt := range tests { 1792 if got := fmt.Sprint(InsecureAlgorithmError(tt.sa)); got != tt.want { 1793 t.Errorf("%d. mismatch.\n got: %s\nwant: %s\n", i, got, tt.want) 1794 } 1795 } 1796 } 1797 1798 // These CSR was generated with OpenSSL: 1799 // openssl req -out CSR.csr -new -sha256 -nodes -keyout privateKey.key -config openssl.cnf 1800 // 1801 // With openssl.cnf containing the following sections: 1802 // [ v3_req ] 1803 // basicConstraints = CA:FALSE 1804 // keyUsage = nonRepudiation, digitalSignature, keyEncipherment 1805 // subjectAltName = email:gopher@golang.org,DNS:test.example.com 1806 // [ req_attributes ] 1807 // challengePassword = ignored challenge 1808 // unstructuredName = ignored unstructured name 1809 var csrBase64Array = [...]string{ 1810 // Just [ v3_req ] 1811 "MIIDHDCCAgQCAQAwfjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLQ29tbW9uIE5hbWUxITAfBgkqhkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1GY4YFx2ujlZEOJxQVYmsjUnLsd5nFVnNpLE4cV+77sgv9NPNlB8uhn3MXt5leD34rm/2BisCHOifPucYlSrszo2beuKhvwn4+2FxDmWtBEMu/QA16L5IvoOfYZm/gJTsPwKDqvaR0tTU67a9OtxwNTBMI56YKtmwd/o8d3hYv9cg+9ZGAZ/gKONcg/OWYx/XRh6bd0g8DMbCikpWgXKDsvvK1Nk+VtkDO1JxuBaj4Lz/p/MifTfnHoqHxWOWl4EaTs4Ychxsv34/rSj1KD1tJqorIv5Xv2aqv4sjxfbrYzX4kvS5SC1goIovLnhj5UjmQ3Qy8u65eow/LLWw+YFcCAwEAAaBZMFcGCSqGSIb3DQEJDjFKMEgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLgYDVR0RBCcwJYERZ29waGVyQGdvbGFuZy5vcmeCEHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAB6VPMRrchvNW61Tokyq3ZvO6/NoGIbuwUn54q6l5VZW0Ep5Nq8juhegSSnaJ0jrovmUgKDN9vEo2KxuAtwG6udS6Ami3zP+hRd4k9Q8djJPb78nrjzWiindLK5Fps9U5mMoi1ER8ViveyAOTfnZt/jsKUaRsscY2FzE9t9/o5moE6LTcHUS4Ap1eheR+J72WOnQYn3cifYaemsA9MJuLko+kQ6xseqttbh9zjqd9fiCSh/LNkzos9c+mg2yMADitaZinAh+HZi50ooEbjaT3erNq9O6RqwJlgD00g6MQdoz9bTAryCUhCQfkIaepmQ7BxS0pqWNW3MMwfDwx/Snz6g=", 1812 // Both [ v3_req ] and [ req_attributes ] 1813 "MIIDaTCCAlECAQAwfjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLQ29tbW9uIE5hbWUxITAfBgkqhkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1GY4YFx2ujlZEOJxQVYmsjUnLsd5nFVnNpLE4cV+77sgv9NPNlB8uhn3MXt5leD34rm/2BisCHOifPucYlSrszo2beuKhvwn4+2FxDmWtBEMu/QA16L5IvoOfYZm/gJTsPwKDqvaR0tTU67a9OtxwNTBMI56YKtmwd/o8d3hYv9cg+9ZGAZ/gKONcg/OWYx/XRh6bd0g8DMbCikpWgXKDsvvK1Nk+VtkDO1JxuBaj4Lz/p/MifTfnHoqHxWOWl4EaTs4Ychxsv34/rSj1KD1tJqorIv5Xv2aqv4sjxfbrYzX4kvS5SC1goIovLnhj5UjmQ3Qy8u65eow/LLWw+YFcCAwEAAaCBpTAgBgkqhkiG9w0BCQcxEwwRaWdub3JlZCBjaGFsbGVuZ2UwKAYJKoZIhvcNAQkCMRsMGWlnbm9yZWQgdW5zdHJ1Y3R1cmVkIG5hbWUwVwYJKoZIhvcNAQkOMUowSDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAuBgNVHREEJzAlgRFnb3BoZXJAZ29sYW5nLm9yZ4IQdGVzdC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAgxe2N5O48EMsYE7o0rZBB0wi3Ov5/yYfnmmVI22Y3sP6VXbLDW0+UWIeSccOhzUCcZ/G4qcrfhhx6gTZTeA01nP7TdTJURvWAH5iFqj9sQ0qnLq6nEcVHij3sG6M5+BxAIVClQBk6lTCzgphc835Fjj6qSLuJ20XHdL5UfUbiJxx299CHgyBRL+hBUIPfz8p+ZgamyAuDLfnj54zzcRVyLlrmMLNPZNll1Q70RxoU6uWvLH8wB8vQe3Q/guSGubLyLRTUQVPh+dw1L4t8MKFWfX/48jwRM4gIRHFHPeAAE9D9YAoqdIvj/iFm/eQ++7DP8MDwOZWsXeB6jjwHuLmkQ==", 1814 } 1815 1816 var md5cert = ` 1817 -----BEGIN CERTIFICATE----- 1818 MIIB4TCCAUoCCQCfmw3vMgPS5TANBgkqhkiG9w0BAQQFADA1MQswCQYDVQQGEwJB 1819 VTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wHhcNMTUx 1820 MjAzMTkyOTMyWhcNMjkwODEyMTkyOTMyWjA1MQswCQYDVQQGEwJBVTETMBEGA1UE 1821 CBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wgZ8wDQYJKoZIhvcNAQEB 1822 BQADgY0AMIGJAoGBANrq2nhLQj5mlXbpVX3QUPhfEm/vdEqPkoWtR/jRZIWm4WGf 1823 Wpq/LKHJx2Pqwn+t117syN8l4U5unyAi1BJSXjBwPZNd7dXjcuJ+bRLV7FZ/iuvs 1824 cfYyQQFTxan4TaJMd0x1HoNDbNbjHa02IyjjYE/r3mb/PIg+J2t5AZEh80lPAgMB 1825 AAEwDQYJKoZIhvcNAQEEBQADgYEAjGzp3K3ey/YfKHohf33yHHWd695HQxDAP+wY 1826 cs9/TAyLR+gJzJP7d18EcDDLJWVi7bhfa4EAD86di05azOh9kWSn4b3o9QYRGCSw 1827 GNnI3Zk0cwNKA49hZntKKiy22DhRk7JAHF01d6Bu3KkHkmENrtJ+zj/+159WAnUa 1828 qViorq4= 1829 -----END CERTIFICATE----- 1830 ` 1831 1832 func TestMD5(t *testing.T) { 1833 pemBlock, _ := pem.Decode([]byte(md5cert)) 1834 cert, err := ParseCertificate(pemBlock.Bytes) 1835 if err != nil { 1836 t.Fatalf("failed to parse certificate: %s", err) 1837 } 1838 if sa := cert.SignatureAlgorithm; sa != MD5WithRSA { 1839 t.Errorf("signature algorithm is %v, want %v", sa, MD5WithRSA) 1840 } 1841 if err = cert.CheckSignatureFrom(cert); err == nil { 1842 t.Fatalf("certificate verification succeeded incorrectly") 1843 } 1844 if _, ok := err.(InsecureAlgorithmError); !ok { 1845 t.Fatalf("certificate verification returned %v (%T), wanted InsecureAlgorithmError", err, err) 1846 } 1847 } 1848 1849 // certMissingRSANULL contains an RSA public key where the AlgorithmIdentifier 1850 // parameters are omitted rather than being an ASN.1 NULL. 1851 const certMissingRSANULL = ` 1852 -----BEGIN CERTIFICATE----- 1853 MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD 1854 bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4 1855 MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc 1856 MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG 1857 hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE 1858 ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e 1859 E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw 1860 DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A 1861 p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4 1862 hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE 1863 GFGNEH5PlGffo05wc46QkYU= 1864 -----END CERTIFICATE-----` 1865 1866 func TestRSAMissingNULLParameters(t *testing.T) { 1867 block, _ := pem.Decode([]byte(certMissingRSANULL)) 1868 if _, err := ParseCertificate(block.Bytes); err == nil { 1869 t.Error("unexpected success when parsing certificate with missing RSA NULL parameter") 1870 } else if !strings.Contains(err.Error(), "missing NULL") { 1871 t.Errorf("unrecognised error when parsing certificate with missing RSA NULL parameter: %s", err) 1872 } 1873 } 1874 1875 const certISOOID = ` 1876 -----BEGIN CERTIFICATE----- 1877 MIIB5TCCAVKgAwIBAgIQtwyL3RPWV7dJQp34HwZG9DAJBgUrDgMCHQUAMBExDzAN 1878 BgNVBAMTBm15dGVzdDAeFw0xNjA4MDkyMjExMDVaFw0zOTEyMzEyMzU5NTlaMBEx 1879 DzANBgNVBAMTBm15dGVzdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArzIH 1880 GsyDB3ohIGkkvijF2PTRUX1bvOtY1eUUpjwHyu0twpAKSuaQv2Ha+/63+aHe8O86 1881 BT+98wjXFX6RFSagtAujo80rIF2dSm33BGt18pDN8v6zp93dnAm0jRaSQrHJ75xw 1882 5O+S1oEYR1LtUoFJy6qB104j6aINBAgOiLIKiMkCAwEAAaNGMEQwQgYDVR0BBDsw 1883 OYAQVuYVQ/WDjdGSkZRlTtJDNKETMBExDzANBgNVBAMTBm15dGVzdIIQtwyL3RPW 1884 V7dJQp34HwZG9DAJBgUrDgMCHQUAA4GBABngrSkH7vG5lY4sa4AZF59lAAXqBVJE 1885 J4TBiKC62hCdZv18rBleP6ETfhbPg7pTs8p4ebQbpmtNxRS9Lw3MzQ8Ya5Ybwzj2 1886 NwBSyCtCQl7mrEg4nJqJl4A2EUhnET/oVxU0oTV/SZ3ziGXcY1oG1s6vidV7TZTu 1887 MCRtdSdaM7g3 1888 -----END CERTIFICATE-----` 1889 1890 func TestISOOIDInCertificate(t *testing.T) { 1891 block, _ := pem.Decode([]byte(certISOOID)) 1892 if cert, err := ParseCertificate(block.Bytes); err != nil { 1893 t.Errorf("certificate with ISO OID failed to parse: %s", err) 1894 } else if cert.SignatureAlgorithm == UnknownSignatureAlgorithm { 1895 t.Errorf("ISO OID not recognised in certificate") 1896 } 1897 } 1898 1899 // certMultipleRDN contains a RelativeDistinguishedName with two elements (the 1900 // common name and serial number). This particular certificate was the first 1901 // such certificate in the “Pilot” Certificate Transparency log. 1902 const certMultipleRDN = ` 1903 -----BEGIN CERTIFICATE----- 1904 MIIFRzCCBC+gAwIBAgIEOl59NTANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJz 1905 aTEbMBkGA1UEChMSc3RhdGUtaW5zdGl0dXRpb25zMREwDwYDVQQLEwhzaWdvdi1j 1906 YTAeFw0xMjExMTYxMDUyNTdaFw0xNzExMTYxMjQ5MDVaMIGLMQswCQYDVQQGEwJz 1907 aTEbMBkGA1UEChMSc3RhdGUtaW5zdGl0dXRpb25zMRkwFwYDVQQLExB3ZWItY2Vy 1908 dGlmaWNhdGVzMRAwDgYDVQQLEwdTZXJ2ZXJzMTIwFAYDVQQFEw0xMjM2NDg0MDEw 1909 MDEwMBoGA1UEAxMTZXBvcnRhbC5tc3MuZWR1cy5zaTCCASIwDQYJKoZIhvcNAQEB 1910 BQADggEPADCCAQoCggEBAMrNkZH9MPuBTjMGNk3sJX8V+CkFx/4ru7RTlLS6dlYM 1911 098dtSfJ3s2w0p/1NB9UmR8j0yS0Kg6yoZ3ShsSO4DWBtcQD8820a6BYwqxxQTNf 1912 HSRZOc+N/4TQrvmK6t4k9Aw+YEYTMrWOU4UTeyhDeCcUsBdh7HjfWsVaqNky+2sv 1913 oic3zP5gF+2QfPkvOoHT3FLR8olNhViIE6Kk3eFIEs4dkq/ZzlYdLb8pHQoj/sGI 1914 zFmA5AFvm1HURqOmJriFjBwaCtn8AVEYOtQrnUCzJYu1ex8azyS2ZgYMX0u8A5Z/ 1915 y2aMS/B2W+H79WcgLpK28vPwe7vam0oFrVytAd+u65ECAwEAAaOCAf4wggH6MA4G 1916 A1UdDwEB/wQEAwIFoDBABgNVHSAEOTA3MDUGCisGAQQBr1kBAwMwJzAlBggrBgEF 1917 BQcCARYZaHR0cDovL3d3dy5jYS5nb3Yuc2kvY3BzLzAfBgNVHREEGDAWgRRwb2Rw 1918 b3JhLm1pemtzQGdvdi5zaTCB8QYDVR0fBIHpMIHmMFWgU6BRpE8wTTELMAkGA1UE 1919 BhMCc2kxGzAZBgNVBAoTEnN0YXRlLWluc3RpdHV0aW9uczERMA8GA1UECxMIc2ln 1920 b3YtY2ExDjAMBgNVBAMTBUNSTDM5MIGMoIGJoIGGhldsZGFwOi8veDUwMC5nb3Yu 1921 c2kvb3U9c2lnb3YtY2Esbz1zdGF0ZS1pbnN0aXR1dGlvbnMsYz1zaT9jZXJ0aWZp 1922 Y2F0ZVJldm9jYXRpb25MaXN0P2Jhc2WGK2h0dHA6Ly93d3cuc2lnb3YtY2EuZ292 1923 LnNpL2NybC9zaWdvdi1jYS5jcmwwKwYDVR0QBCQwIoAPMjAxMjExMTYxMDUyNTda 1924 gQ8yMDE3MTExNjEyNDkwNVowHwYDVR0jBBgwFoAUHvjUU2uzgwbpBAZXAvmlv8ZY 1925 PHIwHQYDVR0OBBYEFGI1Duuu+wTGDZka/xHNbwcbM69ZMAkGA1UdEwQCMAAwGQYJ 1926 KoZIhvZ9B0EABAwwChsEVjcuMQMCA6gwDQYJKoZIhvcNAQEFBQADggEBAHny0K1y 1927 BQznrzDu3DDpBcGYguKU0dvU9rqsV1ua4nxkriSMWjgsX6XJFDdDW60I3P4VWab5 1928 ag5fZzbGqi8kva/CzGgZh+CES0aWCPy+4Gb8lwOTt+854/laaJvd6kgKTER7z7U9 1929 9C86Ch2y4sXNwwwPJ1A9dmrZJZOcJjS/WYZgwaafY2Hdxub5jqPE5nehwYUPVu9R 1930 uH6/skk4OEKcfOtN0hCnISOVuKYyS4ANARWRG5VGHIH06z3lGUVARFRJ61gtAprd 1931 La+fgSS+LVZ+kU2TkeoWAKvGq8MAgDq4D4Xqwekg7WKFeuyusi/NI5rm40XgjBMF 1932 DF72IUofoVt7wo0= 1933 -----END CERTIFICATE-----` 1934 1935 func TestMultipleRDN(t *testing.T) { 1936 block, _ := pem.Decode([]byte(certMultipleRDN)) 1937 cert, err := ParseCertificate(block.Bytes) 1938 if err != nil { 1939 t.Fatalf("certificate with two elements in an RDN failed to parse: %v", err) 1940 } 1941 1942 if want := "eportal.mss.edus.si"; cert.Subject.CommonName != want { 1943 t.Errorf("got common name of %q, but want %q", cert.Subject.CommonName, want) 1944 } 1945 1946 if want := "1236484010010"; cert.Subject.SerialNumber != want { 1947 t.Errorf("got serial number of %q, but want %q", cert.Subject.SerialNumber, want) 1948 } 1949 } 1950 1951 func TestSystemCertPool(t *testing.T) { 1952 if runtime.GOOS == "windows" { 1953 t.Skip("not implemented on Windows; Issue 16736, 18609") 1954 } 1955 a, err := SystemCertPool() 1956 if err != nil { 1957 t.Fatal(err) 1958 } 1959 b, err := SystemCertPool() 1960 if err != nil { 1961 t.Fatal(err) 1962 } 1963 if !certPoolEqual(a, b) { 1964 t.Fatal("two calls to SystemCertPool had different results") 1965 } 1966 if ok := b.AppendCertsFromPEM([]byte(` 1967 -----BEGIN CERTIFICATE----- 1968 MIIDBjCCAe6gAwIBAgIRANXM5I3gjuqDfTp/PYrs+u8wDQYJKoZIhvcNAQELBQAw 1969 EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xODAzMjcxOTU2MjFaFw0xOTAzMjcxOTU2 1970 MjFaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw 1971 ggEKAoIBAQDK+9m3rjsO2Djes6bIYQZ3eV29JF09ZrjOrEHLtaKrD6/acsoSoTsf 1972 cQr+rzzztdB5ijWXCS64zo/0OiqBeZUNZ67jVdToa9qW5UYe2H0Y+ZNdfA5GYMFD 1973 yk/l3/uBu3suTZPfXiW2TjEi27Q8ruNUIZ54DpTcs6y2rBRFzadPWwn/VQMlvRXM 1974 jrzl8Y08dgnYmaAHprxVzwMXcQ/Brol+v9GvjaH1DooHqkn8O178wsPQNhdtvN01 1975 IXL46cYdcUwWrE/GX5u+9DaSi+0KWxAPQ+NVD5qUI0CKl4714yGGh7feXMjJdHgl 1976 VG4QJZlJvC4FsURgCHJT6uHGIelnSwhbAgMBAAGjVzBVMA4GA1UdDwEB/wQEAwIF 1977 oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCAGA1UdEQQZMBeC 1978 FVRlc3RTeXN0ZW1DZXJ0UG9vbC5nbzANBgkqhkiG9w0BAQsFAAOCAQEAwuSRx/VR 1979 BKh2ICxZjL6jBwk/7UlU1XKbhQD96RqkidDNGEc6eLZ90Z5XXTurEsXqdm5jQYPs 1980 1cdcSW+fOSMl7MfW9e5tM66FaIPZl9rKZ1r7GkOfgn93xdLAWe8XHd19xRfDreub 1981 YC8DVqgLASOEYFupVSl76ktPfxkU5KCvmUf3P2PrRybk1qLGFytGxfyice2gHSNI 1982 gify3K/+H/7wCkyFW4xYvzl7WW4mXxoqPRPjQt1J423DhnnQ4G1P8V/vhUpXNXOq 1983 N9IEPnWuihC09cyx/WMQIUlWnaQLHdfpPS04Iez3yy2PdfXJzwfPrja7rNE+skK6 1984 pa/O1nF0AfWOpw== 1985 -----END CERTIFICATE----- 1986 `)); !ok { 1987 t.Fatal("AppendCertsFromPEM failed") 1988 } 1989 if reflect.DeepEqual(a, b) { 1990 t.Fatal("changing one pool modified the other") 1991 } 1992 } 1993 1994 const emptyNameConstraintsPEM = ` 1995 -----BEGIN CERTIFICATE----- 1996 MIIC1jCCAb6gAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w 1997 dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw 1998 NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB 1999 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD 2000 F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx 2001 f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq 2002 Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0 2003 LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD 2004 blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID 2005 AQABoxEwDzANBgNVHR4EBjAEoAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMH 2006 QhP8uNCtgSHyim/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb 2007 6L+iJa4ElREJOi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6H 2008 v5SsvpYW+1XleYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6M 2009 LYPmRhTioROA/drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOga 2010 nCOSyFYfGhqOANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8 2011 o+WoY6IsCKXV/g== 2012 -----END CERTIFICATE-----` 2013 2014 func TestEmptyNameConstraints(t *testing.T) { 2015 block, _ := pem.Decode([]byte(emptyNameConstraintsPEM)) 2016 _, err := ParseCertificate(block.Bytes) 2017 if err == nil { 2018 t.Fatal("unexpected success") 2019 } 2020 2021 const expected = "empty name constraints" 2022 if str := err.Error(); !strings.Contains(str, expected) { 2023 t.Errorf("expected %q in error but got %q", expected, str) 2024 } 2025 } 2026 2027 func TestPKIXNameString(t *testing.T) { 2028 der, err := base64.StdEncoding.DecodeString(certBytes) 2029 if err != nil { 2030 t.Fatal(err) 2031 } 2032 certs, err := ParseCertificates(der) 2033 if err != nil { 2034 t.Fatal(err) 2035 } 2036 2037 // Check that parsed non-standard attributes are printed. 2038 rdns := pkix.Name{ 2039 Locality: []string{"Gophertown"}, 2040 ExtraNames: []pkix.AttributeTypeAndValue{ 2041 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, 2042 }.ToRDNSequence() 2043 nn := pkix.Name{} 2044 nn.FillFromRDNSequence(&rdns) 2045 2046 // Check that zero-length non-nil ExtraNames hide Names. 2047 extra := []pkix.AttributeTypeAndValue{ 2048 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "backing array"}} 2049 extraNotNil := pkix.Name{ 2050 Locality: []string{"Gophertown"}, 2051 ExtraNames: extra[:0], 2052 Names: []pkix.AttributeTypeAndValue{ 2053 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, 2054 } 2055 2056 tests := []struct { 2057 dn pkix.Name 2058 want string 2059 }{ 2060 {nn, "L=Gophertown,1.2.3.4.5=#130a676f6c616e672e6f7267"}, 2061 {extraNotNil, "L=Gophertown"}, 2062 {pkix.Name{ 2063 CommonName: "Steve Kille", 2064 Organization: []string{"Isode Limited"}, 2065 OrganizationalUnit: []string{"RFCs"}, 2066 Locality: []string{"Richmond"}, 2067 Province: []string{"Surrey"}, 2068 StreetAddress: []string{"The Square"}, 2069 PostalCode: []string{"TW9 1DT"}, 2070 SerialNumber: "RFC 2253", 2071 Country: []string{"GB"}, 2072 }, "SERIALNUMBER=RFC 2253,CN=Steve Kille,OU=RFCs,O=Isode Limited,POSTALCODE=TW9 1DT,STREET=The Square,L=Richmond,ST=Surrey,C=GB"}, 2073 {certs[0].Subject, 2074 "CN=mail.google.com,O=Google LLC,L=Mountain View,ST=California,C=US"}, 2075 {pkix.Name{ 2076 Organization: []string{"#Google, Inc. \n-> 'Alphabet\" "}, 2077 Country: []string{"US"}, 2078 }, "O=\\#Google\\, Inc. \n-\\> 'Alphabet\\\"\\ ,C=US"}, 2079 {pkix.Name{ 2080 CommonName: "foo.com", 2081 Organization: []string{"Gopher Industries"}, 2082 ExtraNames: []pkix.AttributeTypeAndValue{ 2083 {Type: asn1.ObjectIdentifier([]int{2, 5, 4, 3}), Value: "bar.com"}}, 2084 }, "CN=bar.com,O=Gopher Industries"}, 2085 {pkix.Name{ 2086 Locality: []string{"Gophertown"}, 2087 ExtraNames: []pkix.AttributeTypeAndValue{ 2088 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, 2089 }, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"}, 2090 // If there are no ExtraNames, the Names are printed instead. 2091 {pkix.Name{ 2092 Locality: []string{"Gophertown"}, 2093 Names: []pkix.AttributeTypeAndValue{ 2094 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, 2095 }, "L=Gophertown,1.2.3.4.5=#130a676f6c616e672e6f7267"}, 2096 // If there are both, print only the ExtraNames. 2097 {pkix.Name{ 2098 Locality: []string{"Gophertown"}, 2099 ExtraNames: []pkix.AttributeTypeAndValue{ 2100 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, 2101 Names: []pkix.AttributeTypeAndValue{ 2102 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 6}), Value: "example.com"}}, 2103 }, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"}, 2104 } 2105 2106 for i, test := range tests { 2107 if got := test.dn.String(); got != test.want { 2108 t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want) 2109 } 2110 } 2111 2112 if extra[0].Value != "backing array" { 2113 t.Errorf("the backing array of an empty ExtraNames got modified by String") 2114 } 2115 } 2116 2117 func TestRDNSequenceString(t *testing.T) { 2118 // Test some extra cases that get lost in pkix.Name conversions such as 2119 // multi-valued attributes. 2120 2121 var ( 2122 oidCountry = []int{2, 5, 4, 6} 2123 oidOrganization = []int{2, 5, 4, 10} 2124 oidOrganizationalUnit = []int{2, 5, 4, 11} 2125 oidCommonName = []int{2, 5, 4, 3} 2126 ) 2127 2128 tests := []struct { 2129 seq pkix.RDNSequence 2130 want string 2131 }{ 2132 { 2133 seq: pkix.RDNSequence{ 2134 pkix.RelativeDistinguishedNameSET{ 2135 pkix.AttributeTypeAndValue{Type: oidCountry, Value: "US"}, 2136 }, 2137 pkix.RelativeDistinguishedNameSET{ 2138 pkix.AttributeTypeAndValue{Type: oidOrganization, Value: "Widget Inc."}, 2139 }, 2140 pkix.RelativeDistinguishedNameSET{ 2141 pkix.AttributeTypeAndValue{Type: oidOrganizationalUnit, Value: "Sales"}, 2142 pkix.AttributeTypeAndValue{Type: oidCommonName, Value: "J. Smith"}, 2143 }, 2144 }, 2145 want: "OU=Sales+CN=J. Smith,O=Widget Inc.,C=US", 2146 }, 2147 } 2148 2149 for i, test := range tests { 2150 if got := test.seq.String(); got != test.want { 2151 t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want) 2152 } 2153 } 2154 } 2155 2156 const criticalNameConstraintWithUnknownTypePEM = ` 2157 -----BEGIN CERTIFICATE----- 2158 MIIC/TCCAeWgAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w 2159 dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw 2160 NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB 2161 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD 2162 F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx 2163 f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq 2164 Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0 2165 LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD 2166 blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID 2167 AQABozgwNjA0BgNVHR4BAf8EKjAooCQwIokgIACrzQAAAAAAAAAAAAAAAP////8A 2168 AAAAAAAAAAAAAAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMHQhP8uNCtgSHy 2169 im/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb6L+iJa4ElREJ 2170 Oi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6Hv5SsvpYW+1Xl 2171 eYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6MLYPmRhTioROA 2172 /drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOganCOSyFYfGhqO 2173 ANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8o+WoY6IsCKXV 2174 /g== 2175 -----END CERTIFICATE-----` 2176 2177 func TestCriticalNameConstraintWithUnknownType(t *testing.T) { 2178 block, _ := pem.Decode([]byte(criticalNameConstraintWithUnknownTypePEM)) 2179 cert, err := ParseCertificate(block.Bytes) 2180 if err != nil { 2181 t.Fatalf("unexpected parsing failure: %s", err) 2182 } 2183 2184 if l := len(cert.UnhandledCriticalExtensions); l != 1 { 2185 t.Fatalf("expected one unhandled critical extension, but found %d", l) 2186 } 2187 } 2188 2189 const badIPMaskPEM = ` 2190 -----BEGIN CERTIFICATE----- 2191 MIICzzCCAbegAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UEAxMSQmFk 2192 IElQIG1hc2sgaXNzdWVyMB4XDTEzMDIwMTAwMDAwMFoXDTIwMDUzMDEwNDgzOFow 2193 FjEUMBIGA1UEAxMLQmFkIElQIG1hc2swggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw 2194 ggEKAoIBAQDCuISVQi3csKqYk5uz7IOhY8MXkiqBaTqagihtiM997G1mJhTojcR+ 2195 8DCg3E8OQ3ZajByhxRkwlsR4Srl5sGSwWfF/XaAHGUhWIhjBkDO7toW+EMzI8pAj 2196 cLwIbRlIL0AFnUTe6Z0DcIS5406Y/9MKE2oKXbf4EbVBv88mSkA74Z+lZJWFNxXn 2197 cx/9wq8UdyMY2vHN1Kir1/JbtrqB9wYRBjQtWSbAVZR8nTBPyRp4uvQTS2jOQh+j 2198 TUo1Y3O/o1xg/zRA4FEOUCla704OYRUkc8NuXHiPNNDcktr7gO8E06NVQ6n6aBGa 2199 OJbSst2vHA7Eiog7A2PB4wKn+GDFf+FNAgMBAAGjIDAeMBwGA1UdHgEB/wQSMBCg 2200 DDAKhwgBAgME//8BAKEAMA0GCSqGSIb3DQEBCwUAA4IBAQBYb7/NQwdCE/y40K2B 2201 IfKKb++HvCaKfAC9aAwrGWQsEWezqdl5Cqw5XWUAFjtTRm6iprVnmdvov6IlrgSV 2202 EQk6L96stz24vAF0MIBHSFRMoPtrqLiihLf0NOV7ztxSePQxbUJRroe/lKy+lhb7 2203 VeV5gmT9rFA45NzLgSznd2+dmyNcfQQD9AeeftRX4maUTeu1XFxinowtg+ZGFOKh 2204 E4D92uCGJxGSK72HF0/LGRhLXozmDdmPfSN2b6T/oLo942031iY46BqcI5LIVh8a 2205 Go4A1jOma5X6gh50Cw+kht8jM3yeNhSzXOKj7Uigjijx10z2wJu09Tyj5ahjoiwI 2206 pdX+ 2207 -----END CERTIFICATE-----` 2208 2209 func TestBadIPMask(t *testing.T) { 2210 block, _ := pem.Decode([]byte(badIPMaskPEM)) 2211 _, err := ParseCertificate(block.Bytes) 2212 if err == nil { 2213 t.Fatalf("unexpected success") 2214 } 2215 2216 const expected = "contained invalid mask" 2217 if !strings.Contains(err.Error(), expected) { 2218 t.Fatalf("expected %q in error but got: %s", expected, err) 2219 } 2220 } 2221 2222 const additionalGeneralSubtreePEM = ` 2223 -----BEGIN CERTIFICATE----- 2224 MIIG4TCCBMmgAwIBAgIRALss+4rLw2Ia7tFFhxE8g5cwDQYJKoZIhvcNAQELBQAw 2225 bjELMAkGA1UEBhMCTkwxIDAeBgNVBAoMF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll 2226 MT0wOwYDVQQDDDRNaW5pc3RlcmllIHZhbiBEZWZlbnNpZSBDZXJ0aWZpY2F0aWUg 2227 QXV0b3JpdGVpdCAtIEcyMB4XDTEzMDMwNjEyMDM0OVoXDTEzMTEzMDEyMDM1MFow 2228 bDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUNlcnRpUGF0aCBMTEMxIjAgBgNVBAsT 2229 GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxITAfBgNVBAMTGENlcnRpUGF0aCBC 2230 cmlkZ2UgQ0EgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANLW 2231 4kXiRqvwBhJfN9uz12FA+P2D34MPxOt7TGXljm2plJ2CLzvaH8/ymsMdSWdJBS1M 2232 8FmwvNL1w3A6ZuzksJjPikAu8kY3dcp3mrkk9eCPORDAwGtfsXwZysLiuEaDWpbD 2233 dHOaHnI6qWU0N6OI+hNX58EjDpIGC1WQdho1tHOTPc5Hf5/hOpM/29v/wr7kySjs 2234 Z+7nsvkm5rNhuJNzPsLsgzVaJ5/BVyOplZy24FKM8Y43MjR4osZm+a2e0zniqw6/ 2235 rvcjcGYabYaznZfQG1GXoyf2Vea+CCgpgUhlVafgkwEs8izl8rIpvBzXiFAgFQuG 2236 Ituoy92PJbDs430fA/cCAwEAAaOCAnowggJ2MEUGCCsGAQUFBwEBBDkwNzA1Bggr 2237 BgEFBQcwAoYpaHR0cDovL2NlcnRzLmNhLm1pbmRlZi5ubC9taW5kZWYtY2EtMi5w 2238 N2MwHwYDVR0jBBgwFoAUzln9WSPz2M64Rl2HYf2/KD8StmQwDwYDVR0TAQH/BAUw 2239 AwEB/zCB6QYDVR0gBIHhMIHeMEgGCmCEEAGHawECBQEwOjA4BggrBgEFBQcCARYs 2240 aHR0cDovL2Nwcy5kcC5jYS5taW5kZWYubmwvbWluZGVmLWNhLWRwLWNwcy8wSAYK 2241 YIQQAYdrAQIFAjA6MDgGCCsGAQUFBwIBFixodHRwOi8vY3BzLmRwLmNhLm1pbmRl 2242 Zi5ubC9taW5kZWYtY2EtZHAtY3BzLzBIBgpghBABh2sBAgUDMDowOAYIKwYBBQUH 2243 AgEWLGh0dHA6Ly9jcHMuZHAuY2EubWluZGVmLm5sL21pbmRlZi1jYS1kcC1jcHMv 2244 MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmxzLmNhLm1pbmRlZi5ubC9taW5k 2245 ZWYtY2EtMi5jcmwwDgYDVR0PAQH/BAQDAgEGMEYGA1UdHgEB/wQ8MDqhODA2pDEw 2246 LzELMAkGA1UEBhMCTkwxIDAeBgNVBAoTF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll 2247 gQFjMF0GA1UdIQRWMFQwGgYKYIQQAYdrAQIFAQYMKwYBBAGBu1MBAQECMBoGCmCE 2248 EAGHawECBQIGDCsGAQQBgbtTAQEBAjAaBgpghBABh2sBAgUDBgwrBgEEAYG7UwEB 2249 AQIwHQYDVR0OBBYEFNDCjBM3M3ZKkag84ei3/aKc0d0UMA0GCSqGSIb3DQEBCwUA 2250 A4ICAQAQXFn9jF90/DNFf15JhoGtta/0dNInb14PMu3PAjcdrXYCDPpQZOArTUng 2251 5YT1WuzfmjnXiTsziT3my0r9Mxvz/btKK/lnVOMW4c2q/8sIsIPnnW5ZaRGrsANB 2252 dNDZkzMYmeG2Pfgvd0AQSOrpE/TVgWfu/+MMRWwX9y6VbooBR7BLv7zMuVH0WqLn 2253 6OMFth7fqsThlfMSzkE/RDSaU6n3wXAWT1SIqBITtccRjSUQUFm/q3xrb2cwcZA6 2254 8vdS4hzNd+ttS905ay31Ks4/1Wrm1bH5RhEfRSH0VSXnc0b+z+RyBbmiwtVZqzxE 2255 u3UQg/rAmtLDclLFEzjp8YDTIRYSLwstDbEXO/0ArdGrQm79HQ8i/3ZbP2357myW 2256 i15qd6gMJIgGHS4b8Hc7R1K8LQ9Gm1aLKBEWVNGZlPK/cpXThpVmoEyslN2DHCrc 2257 fbMbjNZpXlTMa+/b9z7Fa4X8dY8u/ELzZuJXJv5Rmqtg29eopFFYDCl0Nkh1XAjo 2258 QejEoHHUvYV8TThHZr6Z6Ib8CECgTehU4QvepkgDXNoNrKRZBG0JhLjkwxh2whZq 2259 nvWBfALC2VuNOM6C0rDY+HmhMlVt0XeqnybD9MuQALMit7Z00Cw2CIjNsBI9xBqD 2260 xKK9CjUb7gzRUWSpB9jGHsvpEMHOzIFhufvH2Bz1XJw+Cl7khw== 2261 -----END CERTIFICATE-----` 2262 2263 func TestAdditionFieldsInGeneralSubtree(t *testing.T) { 2264 // Very rarely, certificates can include additional fields in the 2265 // GeneralSubtree structure. This tests that such certificates can be 2266 // parsed. 2267 block, _ := pem.Decode([]byte(additionalGeneralSubtreePEM)) 2268 if _, err := ParseCertificate(block.Bytes); err != nil { 2269 t.Fatalf("failed to parse certificate: %s", err) 2270 } 2271 } 2272 2273 func TestEmptySubject(t *testing.T) { 2274 template := Certificate{ 2275 SerialNumber: big.NewInt(1), 2276 DNSNames: []string{"example.com"}, 2277 } 2278 2279 derBytes, err := CreateCertificate(rand.Reader, &template, &template, &testPrivateKey.PublicKey, testPrivateKey) 2280 if err != nil { 2281 t.Fatalf("failed to create certificate: %s", err) 2282 } 2283 2284 cert, err := ParseCertificate(derBytes) 2285 if err != nil { 2286 t.Fatalf("failed to parse certificate: %s", err) 2287 } 2288 2289 for _, ext := range cert.Extensions { 2290 if ext.Id.Equal(oidExtensionSubjectAltName) { 2291 if !ext.Critical { 2292 t.Fatal("SAN extension is not critical") 2293 } 2294 return 2295 } 2296 } 2297 2298 t.Fatal("SAN extension is missing") 2299 } 2300 2301 // multipleURLsInCRLDPPEM contains two URLs in a single CRL DistributionPoint 2302 // structure. It is taken from https://crt.sh/?id=12721534. 2303 const multipleURLsInCRLDPPEM = ` 2304 -----BEGIN CERTIFICATE----- 2305 MIIF4TCCBMmgAwIBAgIQc+6uFePfrahUGpXs8lhiTzANBgkqhkiG9w0BAQsFADCB 2306 8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy 2307 dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 2308 YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 2309 dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh 2310 IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD 2311 LUFDQzAeFw0xNDA5MTgwODIxMDBaFw0zMDA5MTgwODIxMDBaMIGGMQswCQYDVQQG 2312 EwJFUzEzMDEGA1UECgwqQ09OU09SQ0kgQURNSU5JU1RSQUNJTyBPQkVSVEEgREUg 2313 Q0FUQUxVTllBMSowKAYDVQQLDCFTZXJ2ZWlzIFDDumJsaWNzIGRlIENlcnRpZmlj 2314 YWNpw7MxFjAUBgNVBAMMDUVDLUNpdXRhZGFuaWEwggEiMA0GCSqGSIb3DQEBAQUA 2315 A4IBDwAwggEKAoIBAQDFkHPRZPZlXTWZ5psJhbS/Gx+bxcTpGrlVQHHtIkgGz77y 2316 TA7UZUFb2EQMncfbOhR0OkvQQn1aMvhObFJSR6nI+caf2D+h/m/InMl1MyH3S0Ak 2317 YGZZsthnyC6KxqK2A/NApncrOreh70ULkQs45aOKsi1kR1W0zE+iFN+/P19P7AkL 2318 Rl3bXBCVd8w+DLhcwRrkf1FCDw6cEqaFm3cGgf5cbBDMaVYAweWTxwBZAq2RbQAW 2319 jE7mledcYghcZa4U6bUmCBPuLOnO8KMFAvH+aRzaf3ws5/ZoOVmryyLLJVZ54peZ 2320 OwnP9EL4OuWzmXCjBifXR2IAblxs5JYj57tls45nAgMBAAGjggHaMIIB1jASBgNV 2321 HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUC2hZPofI 2322 oxUa4ECCIl+fHbLFNxUwHwYDVR0jBBgwFoAUoMOLRKo3pUW/l4Ba0fF4opvpXY0w 2323 gdYGA1UdIASBzjCByzCByAYEVR0gADCBvzAxBggrBgEFBQcCARYlaHR0cHM6Ly93 2324 d3cuYW9jLmNhdC9DQVRDZXJ0L1JlZ3VsYWNpbzCBiQYIKwYBBQUHAgIwfQx7QXF1 2325 ZXN0IGNlcnRpZmljYXQgw6lzIGVtw6hzIMO6bmljYSBpIGV4Y2x1c2l2YW1lbnQg 2326 YSBFbnRpdGF0cyBkZSBDZXJ0aWZpY2FjacOzLiBWZWdldSBodHRwczovL3d3dy5h 2327 b2MuY2F0L0NBVENlcnQvUmVndWxhY2lvMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEF 2328 BQcwAYYXaHR0cDovL29jc3AuY2F0Y2VydC5jYXQwYgYDVR0fBFswWTBXoFWgU4Yn 2329 aHR0cDovL2Vwc2NkLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JshihodHRwOi8v 2330 ZXBzY2QyLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JsMA0GCSqGSIb3DQEBCwUA 2331 A4IBAQChqFTjlAH5PyIhLjLgEs68CyNNC1+vDuZXRhy22TI83JcvGmQrZosPvVIL 2332 PsUXx+C06Pfqmh48Q9S89X9K8w1SdJxP/rZeGEoRiKpwvQzM4ArD9QxyC8jirxex 2333 3Umg9Ai/sXQ+1lBf6xw4HfUUr1WIp7pNHj0ZWLo106urqktcdeAFWme+/klis5fu 2334 labCSVPuT/QpwakPrtqOhRms8vgpKiXa/eLtL9ZiA28X/Mker0zlAeTA7Z7uAnp6 2335 oPJTlZu1Gg1ZDJueTWWsLlO+P+Wzm3MRRIbcgdRzm4mdO7ubu26SzX/aQXDhuih+ 2336 eVxXDTCfs7GUlxnjOp5j559X/N0A 2337 -----END CERTIFICATE----- 2338 ` 2339 2340 func TestMultipleURLsInCRLDP(t *testing.T) { 2341 block, _ := pem.Decode([]byte(multipleURLsInCRLDPPEM)) 2342 cert, err := ParseCertificate(block.Bytes) 2343 if err != nil { 2344 t.Fatalf("failed to parse certificate: %s", err) 2345 } 2346 2347 want := []string{ 2348 "http://epscd.catcert.net/crl/ec-acc.crl", 2349 "http://epscd2.catcert.net/crl/ec-acc.crl", 2350 } 2351 if got := cert.CRLDistributionPoints; !reflect.DeepEqual(got, want) { 2352 t.Errorf("CRL distribution points = %#v, want #%v", got, want) 2353 } 2354 } 2355 2356 const hexPKCS1TestPKCS8Key = "30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031" 2357 const hexPKCS1TestECKey = "3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50" 2358 2359 var pkcs1MismatchKeyTests = []struct { 2360 hexKey string 2361 errorContains string 2362 }{ 2363 {hexKey: hexPKCS1TestPKCS8Key, errorContains: "use ParsePKCS8PrivateKey instead"}, 2364 {hexKey: hexPKCS1TestECKey, errorContains: "use ParseECPrivateKey instead"}, 2365 } 2366 2367 func TestPKCS1MismatchKeyFormat(t *testing.T) { 2368 for i, test := range pkcs1MismatchKeyTests { 2369 derBytes, _ := hex.DecodeString(test.hexKey) 2370 _, err := ParsePKCS1PrivateKey(derBytes) 2371 if !strings.Contains(err.Error(), test.errorContains) { 2372 t.Errorf("#%d: expected error containing %q, got %s", i, test.errorContains, err) 2373 } 2374 } 2375 } 2376 2377 func TestCreateRevocationList(t *testing.T) { 2378 ec256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 2379 if err != nil { 2380 t.Fatalf("Failed to generate ECDSA P256 key: %s", err) 2381 } 2382 _, ed25519Priv, err := ed25519.GenerateKey(rand.Reader) 2383 if err != nil { 2384 t.Fatalf("Failed to generate Ed25519 key: %s", err) 2385 } 2386 tests := []struct { 2387 name string 2388 key crypto.Signer 2389 issuer *Certificate 2390 template *RevocationList 2391 expectedError string 2392 }{ 2393 { 2394 name: "nil template", 2395 key: ec256Priv, 2396 issuer: nil, 2397 template: nil, 2398 expectedError: "x509: template can not be nil", 2399 }, 2400 { 2401 name: "nil issuer", 2402 key: ec256Priv, 2403 issuer: nil, 2404 template: &RevocationList{}, 2405 expectedError: "x509: issuer can not be nil", 2406 }, 2407 { 2408 name: "issuer doesn't have crlSign key usage bit set", 2409 key: ec256Priv, 2410 issuer: &Certificate{ 2411 KeyUsage: KeyUsageCertSign, 2412 }, 2413 template: &RevocationList{}, 2414 expectedError: "x509: issuer must have the crlSign key usage bit set", 2415 }, 2416 { 2417 name: "issuer missing SubjectKeyId", 2418 key: ec256Priv, 2419 issuer: &Certificate{ 2420 KeyUsage: KeyUsageCRLSign, 2421 }, 2422 template: &RevocationList{}, 2423 expectedError: "x509: issuer certificate doesn't contain a subject key identifier", 2424 }, 2425 { 2426 name: "nextUpdate before thisUpdate", 2427 key: ec256Priv, 2428 issuer: &Certificate{ 2429 KeyUsage: KeyUsageCRLSign, 2430 Subject: pkix.Name{ 2431 CommonName: "testing", 2432 }, 2433 SubjectKeyId: []byte{1, 2, 3}, 2434 }, 2435 template: &RevocationList{ 2436 ThisUpdate: time.Time{}.Add(time.Hour), 2437 NextUpdate: time.Time{}, 2438 }, 2439 expectedError: "x509: template.ThisUpdate is after template.NextUpdate", 2440 }, 2441 { 2442 name: "nil Number", 2443 key: ec256Priv, 2444 issuer: &Certificate{ 2445 KeyUsage: KeyUsageCRLSign, 2446 Subject: pkix.Name{ 2447 CommonName: "testing", 2448 }, 2449 SubjectKeyId: []byte{1, 2, 3}, 2450 }, 2451 template: &RevocationList{ 2452 ThisUpdate: time.Time{}.Add(time.Hour * 24), 2453 NextUpdate: time.Time{}.Add(time.Hour * 48), 2454 }, 2455 expectedError: "x509: template contains nil Number field", 2456 }, 2457 { 2458 name: "invalid signature algorithm", 2459 key: ec256Priv, 2460 issuer: &Certificate{ 2461 KeyUsage: KeyUsageCRLSign, 2462 Subject: pkix.Name{ 2463 CommonName: "testing", 2464 }, 2465 SubjectKeyId: []byte{1, 2, 3}, 2466 }, 2467 template: &RevocationList{ 2468 SignatureAlgorithm: SHA256WithRSA, 2469 RevokedCertificates: []pkix.RevokedCertificate{ 2470 { 2471 SerialNumber: big.NewInt(2), 2472 RevocationTime: time.Time{}.Add(time.Hour), 2473 }, 2474 }, 2475 Number: big.NewInt(5), 2476 ThisUpdate: time.Time{}.Add(time.Hour * 24), 2477 NextUpdate: time.Time{}.Add(time.Hour * 48), 2478 }, 2479 expectedError: "x509: requested SignatureAlgorithm does not match private key type", 2480 }, 2481 { 2482 name: "valid", 2483 key: ec256Priv, 2484 issuer: &Certificate{ 2485 KeyUsage: KeyUsageCRLSign, 2486 Subject: pkix.Name{ 2487 CommonName: "testing", 2488 }, 2489 SubjectKeyId: []byte{1, 2, 3}, 2490 }, 2491 template: &RevocationList{ 2492 RevokedCertificates: []pkix.RevokedCertificate{ 2493 { 2494 SerialNumber: big.NewInt(2), 2495 RevocationTime: time.Time{}.Add(time.Hour), 2496 }, 2497 }, 2498 Number: big.NewInt(5), 2499 ThisUpdate: time.Time{}.Add(time.Hour * 24), 2500 NextUpdate: time.Time{}.Add(time.Hour * 48), 2501 }, 2502 }, 2503 { 2504 name: "valid, Ed25519 key", 2505 key: ed25519Priv, 2506 issuer: &Certificate{ 2507 KeyUsage: KeyUsageCRLSign, 2508 Subject: pkix.Name{ 2509 CommonName: "testing", 2510 }, 2511 SubjectKeyId: []byte{1, 2, 3}, 2512 }, 2513 template: &RevocationList{ 2514 RevokedCertificates: []pkix.RevokedCertificate{ 2515 { 2516 SerialNumber: big.NewInt(2), 2517 RevocationTime: time.Time{}.Add(time.Hour), 2518 }, 2519 }, 2520 Number: big.NewInt(5), 2521 ThisUpdate: time.Time{}.Add(time.Hour * 24), 2522 NextUpdate: time.Time{}.Add(time.Hour * 48), 2523 }, 2524 }, 2525 { 2526 name: "valid, non-default signature algorithm", 2527 key: ec256Priv, 2528 issuer: &Certificate{ 2529 KeyUsage: KeyUsageCRLSign, 2530 Subject: pkix.Name{ 2531 CommonName: "testing", 2532 }, 2533 SubjectKeyId: []byte{1, 2, 3}, 2534 }, 2535 template: &RevocationList{ 2536 SignatureAlgorithm: ECDSAWithSHA512, 2537 RevokedCertificates: []pkix.RevokedCertificate{ 2538 { 2539 SerialNumber: big.NewInt(2), 2540 RevocationTime: time.Time{}.Add(time.Hour), 2541 }, 2542 }, 2543 Number: big.NewInt(5), 2544 ThisUpdate: time.Time{}.Add(time.Hour * 24), 2545 NextUpdate: time.Time{}.Add(time.Hour * 48), 2546 }, 2547 }, 2548 { 2549 name: "valid, extra extension", 2550 key: ec256Priv, 2551 issuer: &Certificate{ 2552 KeyUsage: KeyUsageCRLSign, 2553 Subject: pkix.Name{ 2554 CommonName: "testing", 2555 }, 2556 SubjectKeyId: []byte{1, 2, 3}, 2557 }, 2558 template: &RevocationList{ 2559 RevokedCertificates: []pkix.RevokedCertificate{ 2560 { 2561 SerialNumber: big.NewInt(2), 2562 RevocationTime: time.Time{}.Add(time.Hour), 2563 }, 2564 }, 2565 Number: big.NewInt(5), 2566 ThisUpdate: time.Time{}.Add(time.Hour * 24), 2567 NextUpdate: time.Time{}.Add(time.Hour * 48), 2568 ExtraExtensions: []pkix.Extension{ 2569 { 2570 Id: []int{2, 5, 29, 99}, 2571 Value: []byte{5, 0}, 2572 }, 2573 }, 2574 }, 2575 }, 2576 { 2577 name: "valid, empty list", 2578 key: ec256Priv, 2579 issuer: &Certificate{ 2580 KeyUsage: KeyUsageCRLSign, 2581 Subject: pkix.Name{ 2582 CommonName: "testing", 2583 }, 2584 SubjectKeyId: []byte{1, 2, 3}, 2585 }, 2586 template: &RevocationList{ 2587 Number: big.NewInt(5), 2588 ThisUpdate: time.Time{}.Add(time.Hour * 24), 2589 NextUpdate: time.Time{}.Add(time.Hour * 48), 2590 }, 2591 }, 2592 } 2593 2594 for _, tc := range tests { 2595 t.Run(tc.name, func(t *testing.T) { 2596 crl, err := CreateRevocationList(rand.Reader, tc.template, tc.issuer, tc.key) 2597 if err != nil && tc.expectedError == "" { 2598 t.Fatalf("CreateRevocationList failed unexpectedly: %s", err) 2599 } else if err != nil && tc.expectedError != err.Error() { 2600 t.Fatalf("CreateRevocationList failed unexpectedly, wanted: %s, got: %s", tc.expectedError, err) 2601 } else if err == nil && tc.expectedError != "" { 2602 t.Fatalf("CreateRevocationList didn't fail, expected: %s", tc.expectedError) 2603 } 2604 if tc.expectedError != "" { 2605 return 2606 } 2607 2608 parsedCRL, err := ParseDERCRL(crl) 2609 if err != nil { 2610 t.Fatalf("Failed to parse generated CRL: %s", err) 2611 } 2612 2613 if tc.template.SignatureAlgorithm != UnknownSignatureAlgorithm && 2614 parsedCRL.SignatureAlgorithm.Algorithm.Equal(signatureAlgorithmDetails[tc.template.SignatureAlgorithm].oid) { 2615 t.Fatalf("SignatureAlgorithm mismatch: got %v; want %v.", parsedCRL.SignatureAlgorithm, 2616 tc.template.SignatureAlgorithm) 2617 } 2618 2619 if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, tc.template.RevokedCertificates) { 2620 t.Fatalf("RevokedCertificates mismatch: got %v; want %v.", 2621 parsedCRL.TBSCertList.RevokedCertificates, tc.template.RevokedCertificates) 2622 } 2623 2624 if len(parsedCRL.TBSCertList.Extensions) != 2+len(tc.template.ExtraExtensions) { 2625 t.Fatalf("Generated CRL has wrong number of extensions, wanted: %d, got: %d", 2+len(tc.template.ExtraExtensions), len(parsedCRL.TBSCertList.Extensions)) 2626 } 2627 expectedAKI, err := asn1.Marshal(authKeyId{Id: tc.issuer.SubjectKeyId}) 2628 if err != nil { 2629 t.Fatalf("asn1.Marshal failed: %s", err) 2630 } 2631 akiExt := pkix.Extension{ 2632 Id: oidExtensionAuthorityKeyId, 2633 Value: expectedAKI, 2634 } 2635 if !reflect.DeepEqual(parsedCRL.TBSCertList.Extensions[0], akiExt) { 2636 t.Fatalf("Unexpected first extension: got %v, want %v", 2637 parsedCRL.TBSCertList.Extensions[0], akiExt) 2638 } 2639 expectedNum, err := asn1.Marshal(tc.template.Number) 2640 if err != nil { 2641 t.Fatalf("asn1.Marshal failed: %s", err) 2642 } 2643 crlExt := pkix.Extension{ 2644 Id: oidExtensionCRLNumber, 2645 Value: expectedNum, 2646 } 2647 if !reflect.DeepEqual(parsedCRL.TBSCertList.Extensions[1], crlExt) { 2648 t.Fatalf("Unexpected second extension: got %v, want %v", 2649 parsedCRL.TBSCertList.Extensions[1], crlExt) 2650 } 2651 if len(parsedCRL.TBSCertList.Extensions[2:]) == 0 && len(tc.template.ExtraExtensions) == 0 { 2652 // If we don't have anything to check return early so we don't 2653 // hit a [] != nil false positive below. 2654 return 2655 } 2656 if !reflect.DeepEqual(parsedCRL.TBSCertList.Extensions[2:], tc.template.ExtraExtensions) { 2657 t.Fatalf("Extensions mismatch: got %v; want %v.", 2658 parsedCRL.TBSCertList.Extensions[2:], tc.template.ExtraExtensions) 2659 } 2660 }) 2661 } 2662 } 2663 2664 func TestRSAPSAParameters(t *testing.T) { 2665 generateParams := func(hashFunc crypto.Hash) []byte { 2666 var hashOID asn1.ObjectIdentifier 2667 2668 switch hashFunc { 2669 case crypto.SHA256: 2670 hashOID = oidSHA256 2671 case crypto.SHA384: 2672 hashOID = oidSHA384 2673 case crypto.SHA512: 2674 hashOID = oidSHA512 2675 } 2676 2677 params := pssParameters{ 2678 Hash: pkix.AlgorithmIdentifier{ 2679 Algorithm: hashOID, 2680 Parameters: asn1.NullRawValue, 2681 }, 2682 MGF: pkix.AlgorithmIdentifier{ 2683 Algorithm: oidMGF1, 2684 }, 2685 SaltLength: hashFunc.Size(), 2686 TrailerField: 1, 2687 } 2688 2689 mgf1Params := pkix.AlgorithmIdentifier{ 2690 Algorithm: hashOID, 2691 Parameters: asn1.NullRawValue, 2692 } 2693 2694 var err error 2695 params.MGF.Parameters.FullBytes, err = asn1.Marshal(mgf1Params) 2696 if err != nil { 2697 t.Fatalf("failed to marshal MGF parameters: %s", err) 2698 } 2699 2700 serialized, err := asn1.Marshal(params) 2701 if err != nil { 2702 t.Fatalf("failed to marshal parameters: %s", err) 2703 } 2704 2705 return serialized 2706 } 2707 2708 for h, params := range hashToPSSParameters { 2709 generated := generateParams(h) 2710 if !bytes.Equal(params.FullBytes, generated) { 2711 t.Errorf("hardcoded parameters for %s didn't match generated parameters: got (generated) %x, wanted (hardcoded) %x", h, generated, params.FullBytes) 2712 } 2713 } 2714 } 2715 2716 func TestUnknownExtKey(t *testing.T) { 2717 const errorContains = "unknown extended key usage" 2718 2719 template := &Certificate{ 2720 SerialNumber: big.NewInt(10), 2721 DNSNames: []string{"foo"}, 2722 ExtKeyUsage: []ExtKeyUsage{ExtKeyUsage(-1)}, 2723 } 2724 signer, err := rsa.GenerateKey(rand.Reader, 1024) 2725 if err != nil { 2726 t.Errorf("failed to generate key for TestUnknownExtKey") 2727 } 2728 2729 _, err = CreateCertificate(rand.Reader, template, template, signer.Public(), signer) 2730 if !strings.Contains(err.Error(), errorContains) { 2731 t.Errorf("expected error containing %q, got %s", errorContains, err) 2732 } 2733 } 2734 2735 func TestIA5SANEnforcement(t *testing.T) { 2736 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 2737 if err != nil { 2738 t.Fatalf("ecdsa.GenerateKey failed: %s", err) 2739 } 2740 2741 testURL, err := url.Parse("https://example.com/") 2742 if err != nil { 2743 t.Fatalf("url.Parse failed: %s", err) 2744 } 2745 testURL.RawQuery = "∞" 2746 2747 marshalTests := []struct { 2748 name string 2749 template *Certificate 2750 expectedError string 2751 }{ 2752 { 2753 name: "marshal: unicode dNSName", 2754 template: &Certificate{ 2755 SerialNumber: big.NewInt(0), 2756 DNSNames: []string{"∞"}, 2757 }, 2758 expectedError: "x509: \"∞\" cannot be encoded as an IA5String", 2759 }, 2760 { 2761 name: "marshal: unicode rfc822Name", 2762 template: &Certificate{ 2763 SerialNumber: big.NewInt(0), 2764 EmailAddresses: []string{"∞"}, 2765 }, 2766 expectedError: "x509: \"∞\" cannot be encoded as an IA5String", 2767 }, 2768 { 2769 name: "marshal: unicode uniformResourceIdentifier", 2770 template: &Certificate{ 2771 SerialNumber: big.NewInt(0), 2772 URIs: []*url.URL{testURL}, 2773 }, 2774 expectedError: "x509: \"https://example.com/?∞\" cannot be encoded as an IA5String", 2775 }, 2776 } 2777 2778 for _, tc := range marshalTests { 2779 t.Run(tc.name, func(t *testing.T) { 2780 _, err := CreateCertificate(rand.Reader, tc.template, tc.template, k.Public(), k) 2781 if err == nil { 2782 t.Errorf("expected CreateCertificate to fail with template: %v", tc.template) 2783 } else if err.Error() != tc.expectedError { 2784 t.Errorf("unexpected error: got %q, want %q", err.Error(), tc.expectedError) 2785 } 2786 }) 2787 } 2788 2789 unmarshalTests := []struct { 2790 name string 2791 cert string 2792 expectedError string 2793 }{ 2794 { 2795 name: "unmarshal: unicode dNSName", 2796 cert: "308201083081aea003020102020100300a06082a8648ce3d04030230003022180f30303031303130313030303030305a180f30303031303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d0301070342000424bcc48180d8d9db794028f2575ebe3cac79f04d7b0d0151c5292e588aac3668c495f108c626168462e0668c9705e08a211dd103a659d2684e0adf8c2bfd47baa315301330110603551d110101ff040730058203e2889e300a06082a8648ce3d04030203490030460221008ac7827ac326a6ee0fa70b2afe99af575ec60b975f820f3c25f60fff43fbccd0022100bffeed93556722d43d13e461d5b3e33efc61f6349300327d3a0196cb6da501c2", 2797 expectedError: "x509: SAN dNSName is malformed", 2798 }, 2799 { 2800 name: "unmarshal: unicode rfc822Name", 2801 cert: "308201083081aea003020102020100300a06082a8648ce3d04030230003022180f30303031303130313030303030305a180f30303031303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d0301070342000405cb4c4ba72aac980f7b11b0285191425e29e196ce7c5df1c83f56886566e517f196657cc1b73de89ab84ce503fd634e2f2af88fde24c63ca536dc3a5eed2665a315301330110603551d110101ff040730058103e2889e300a06082a8648ce3d0403020349003046022100ed1431cd4b9bb03d88d1511a0ec128a51204375764c716280dc36e2a60142c8902210088c96d25cfaf97eea851ff17d87bb6fe619d6546656e1739f35c3566051c3d0f", 2802 expectedError: "x509: SAN rfc822Name is malformed", 2803 }, 2804 { 2805 name: "unmarshal: unicode uniformResourceIdentifier", 2806 cert: "3082011b3081c3a003020102020100300a06082a8648ce3d04030230003022180f30303031303130313030303030305a180f30303031303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d03010703420004ce0a79b511701d9188e1ea76bcc5907f1db51de6cc1a037b803f256e8588145ca409d120288bfeb4e38f3088104674d374b35bb91fc80d768d1d519dbe2b0b5aa32a302830260603551d110101ff041c301a861868747470733a2f2f6578616d706c652e636f6d2f3fe2889e300a06082a8648ce3d0403020347003044022044f4697779fd1dae1e382d2452413c5c5ca67851e267d6bc64a8d164977c172c0220505015e657637aa1945d46e7650b6f59b968fc1508ca8b152c99f782446dfc81", 2807 expectedError: "x509: SAN uniformResourceIdentifier is malformed", 2808 }, 2809 } 2810 2811 for _, tc := range unmarshalTests { 2812 der, err := hex.DecodeString(tc.cert) 2813 if err != nil { 2814 t.Fatalf("failed to decode test cert: %s", err) 2815 } 2816 _, err = ParseCertificate(der) 2817 if err == nil { 2818 t.Error("expected CreateCertificate to fail") 2819 } else if err.Error() != tc.expectedError { 2820 t.Errorf("unexpected error: got %q, want %q", err.Error(), tc.expectedError) 2821 } 2822 } 2823 } 2824 2825 func BenchmarkCreateCertificate(b *testing.B) { 2826 template := &Certificate{ 2827 SerialNumber: big.NewInt(10), 2828 DNSNames: []string{"example.com"}, 2829 } 2830 tests := []struct { 2831 name string 2832 gen func() crypto.Signer 2833 }{ 2834 { 2835 name: "RSA 2048", 2836 gen: func() crypto.Signer { 2837 k, err := rsa.GenerateKey(rand.Reader, 2048) 2838 if err != nil { 2839 b.Fatalf("failed to generate test key: %s", err) 2840 } 2841 return k 2842 }, 2843 }, 2844 { 2845 name: "ECDSA P256", 2846 gen: func() crypto.Signer { 2847 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 2848 if err != nil { 2849 b.Fatalf("failed to generate test key: %s", err) 2850 } 2851 return k 2852 }, 2853 }, 2854 } 2855 2856 for _, tc := range tests { 2857 k := tc.gen() 2858 b.ResetTimer() 2859 b.Run(tc.name, func(b *testing.B) { 2860 for i := 0; i < b.N; i++ { 2861 _, err := CreateCertificate(rand.Reader, template, template, k.Public(), k) 2862 if err != nil { 2863 b.Fatalf("failed to create certificate: %s", err) 2864 } 2865 } 2866 }) 2867 } 2868 } 2869 2870 type brokenSigner struct { 2871 pub crypto.PublicKey 2872 } 2873 2874 func (bs *brokenSigner) Public() crypto.PublicKey { 2875 return bs.pub 2876 } 2877 2878 func (bs *brokenSigner) Sign(_ io.Reader, _ []byte, _ crypto.SignerOpts) ([]byte, error) { 2879 return []byte{1, 2, 3}, nil 2880 } 2881 2882 func TestCreateCertificateBrokenSigner(t *testing.T) { 2883 template := &Certificate{ 2884 SerialNumber: big.NewInt(10), 2885 DNSNames: []string{"example.com"}, 2886 } 2887 k, err := rsa.GenerateKey(rand.Reader, 1024) 2888 if err != nil { 2889 t.Fatalf("failed to generate test key: %s", err) 2890 } 2891 expectedErr := "x509: signature over certificate returned by signer is invalid: crypto/rsa: verification error" 2892 _, err = CreateCertificate(rand.Reader, template, template, k.Public(), &brokenSigner{k.Public()}) 2893 if err == nil { 2894 t.Fatal("expected CreateCertificate to fail with a broken signer") 2895 } else if err.Error() != expectedErr { 2896 t.Fatalf("CreateCertificate returned an unexpected error: got %q, want %q", err, expectedErr) 2897 } 2898 } 2899 2900 func TestCreateCertificateMD5(t *testing.T) { 2901 template := &Certificate{ 2902 SerialNumber: big.NewInt(10), 2903 DNSNames: []string{"example.com"}, 2904 SignatureAlgorithm: MD5WithRSA, 2905 } 2906 k, err := rsa.GenerateKey(rand.Reader, 1024) 2907 if err != nil { 2908 t.Fatalf("failed to generate test key: %s", err) 2909 } 2910 _, err = CreateCertificate(rand.Reader, template, template, k.Public(), &brokenSigner{k.Public()}) 2911 if err != nil { 2912 t.Fatalf("CreateCertificate failed when SignatureAlgorithm = MD5WithRSA: %s", err) 2913 } 2914 } 2915 2916 func (s *CertPool) mustCert(t *testing.T, n int) *Certificate { 2917 c, err := s.lazyCerts[n].getCert() 2918 if err != nil { 2919 t.Fatalf("failed to load cert %d: %v", n, err) 2920 } 2921 return c 2922 } 2923 2924 func allCerts(t *testing.T, p *CertPool) []*Certificate { 2925 all := make([]*Certificate, p.len()) 2926 for i := range all { 2927 all[i] = p.mustCert(t, i) 2928 } 2929 return all 2930 } 2931 2932 // certPoolEqual reports whether a and b are equal, except for the 2933 // function pointers. 2934 func certPoolEqual(a, b *CertPool) bool { 2935 if (a != nil) != (b != nil) { 2936 return false 2937 } 2938 if a == nil { 2939 return true 2940 } 2941 if !reflect.DeepEqual(a.byName, b.byName) || 2942 len(a.lazyCerts) != len(b.lazyCerts) { 2943 return false 2944 } 2945 for i := range a.lazyCerts { 2946 la, lb := a.lazyCerts[i], b.lazyCerts[i] 2947 if !bytes.Equal(la.rawSubject, lb.rawSubject) { 2948 return false 2949 } 2950 ca, err := la.getCert() 2951 if err != nil { 2952 panic(err) 2953 } 2954 cb, err := la.getCert() 2955 if err != nil { 2956 panic(err) 2957 } 2958 if !ca.Equal(cb) { 2959 return false 2960 } 2961 } 2962 2963 return true 2964 } 2965 2966 func TestCertificateRequestRoundtripFields(t *testing.T) { 2967 urlA, err := url.Parse("https://example.com/_") 2968 if err != nil { 2969 t.Fatal(err) 2970 } 2971 urlB, err := url.Parse("https://example.org/_") 2972 if err != nil { 2973 t.Fatal(err) 2974 } 2975 in := &CertificateRequest{ 2976 DNSNames: []string{"example.com", "example.org"}, 2977 EmailAddresses: []string{"a@example.com", "b@example.com"}, 2978 IPAddresses: []net.IP{net.IPv4(192, 0, 2, 0), net.IPv6loopback}, 2979 URIs: []*url.URL{urlA, urlB}, 2980 KeyUsage: KeyUsageCertSign, 2981 } 2982 out := marshalAndParseCSR(t, in) 2983 2984 if !reflect.DeepEqual(in.DNSNames, out.DNSNames) { 2985 t.Fatalf("Unexpected DNSNames: got %v, want %v", out.DNSNames, in.DNSNames) 2986 } 2987 if !reflect.DeepEqual(in.EmailAddresses, out.EmailAddresses) { 2988 t.Fatalf("Unexpected EmailAddresses: got %v, want %v", out.EmailAddresses, in.EmailAddresses) 2989 } 2990 if len(in.IPAddresses) != len(out.IPAddresses) || 2991 !in.IPAddresses[0].Equal(out.IPAddresses[0]) || 2992 !in.IPAddresses[1].Equal(out.IPAddresses[1]) { 2993 t.Fatalf("Unexpected IPAddresses: got %v, want %v", out.IPAddresses, in.IPAddresses) 2994 } 2995 if !reflect.DeepEqual(in.URIs, out.URIs) { 2996 t.Fatalf("Unexpected URIs: got %v, want %v", out.URIs, in.URIs) 2997 } 2998 if in.KeyUsage != out.KeyUsage { 2999 t.Fatalf("Unexpected KeyUsage: got %v, want %v", out.KeyUsage, in.KeyUsage) 3000 } 3001 }