1
2
3
4
5 package x509
6
7 import (
8 "bytes"
9 "crypto/dsa"
10 "crypto/ecdsa"
11 "crypto/elliptic"
12 "crypto/rand"
13 "crypto/rsa"
14 _ "crypto/sha256"
15 _ "crypto/sha512"
16 "encoding/base64"
17 "encoding/hex"
18 "encoding/pem"
19 "errors"
20 "fmt"
21 "math/big"
22 "net"
23 "net/url"
24 "os"
25 "os/exec"
26 "reflect"
27 "runtime"
28 "strings"
29 "testing"
30 "time"
31
32 "github.com/google/certificate-transparency-go/asn1"
33 "github.com/google/certificate-transparency-go/x509/pkix"
34 "golang.org/x/crypto/ed25519"
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
53
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 testParsePKIXPublicKey(t *testing.T, pemBytes string) (pub interface{}) {
61 block, _ := pem.Decode([]byte(pemBytes))
62 pub, err := ParsePKIXPublicKey(block.Bytes)
63 if err != nil {
64 t.Fatalf("Failed to parse public key: %s", err)
65 }
66
67 pubBytes2, err := MarshalPKIXPublicKey(pub)
68 if err != nil {
69 t.Errorf("Failed to marshal public key for the second time: %s", err)
70 return
71 }
72 if !bytes.Equal(pubBytes2, block.Bytes) {
73 t.Errorf("Reserialization of public key didn't match. got %x, want %x", pubBytes2, block.Bytes)
74 }
75 return
76 }
77
78 func TestParsePKIXPublicKey(t *testing.T) {
79 t.Run("RSA", func(t *testing.T) {
80 pub := testParsePKIXPublicKey(t, pemPublicKey)
81 _, ok := pub.(*rsa.PublicKey)
82 if !ok {
83 t.Errorf("Value returned from ParsePKIXPublicKey was not an RSA public key")
84 }
85 })
86 t.Run("Ed25519", func(t *testing.T) {
87 pub := testParsePKIXPublicKey(t, pemEd25519Key)
88 _, ok := pub.(ed25519.PublicKey)
89 if !ok {
90 t.Errorf("Value returned from ParsePKIXPublicKey was not an Ed25519 public key")
91 }
92 })
93 }
94
95 func TestParsePKIXPublicKeyEd25519(t *testing.T) {
96 block, _ := pem.Decode([]byte(pemPublicKeyEd25519))
97 pub, err := ParsePKIXPublicKey(block.Bytes)
98 if err != nil {
99 t.Fatalf("ParsePKIXPublicKey(Ed25519)=nil,%v; want _,nil", err)
100 }
101 edPub, ok := pub.(ed25519.PublicKey)
102 if !ok {
103 t.Fatalf("ParsePKIXPublicKey.(ed25519.PublicKey)=nil,%v; want _,true", ok)
104 }
105
106 pubBytes2, err := MarshalPKIXPublicKey(edPub)
107 if err != nil {
108 t.Fatalf("MarshalPKIXPublicKey(Ed25519)=nil,%v; want _,nil", err)
109 }
110 if !bytes.Equal(pubBytes2, block.Bytes) {
111 t.Errorf("MarshalPKIXPublicKey(Ed25519)=%x; want %x", pubBytes2, block.Bytes)
112 }
113 }
114
115
116 var pemPublicKeyEd25519 = `-----BEGIN PUBLIC KEY-----
117 MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=
118 -----END PUBLIC KEY-----`
119
120 var pemPublicKey = `-----BEGIN PUBLIC KEY-----
121 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VoPN9PKUjKFLMwOge6+
122 wnDi8sbETGIx2FKXGgqtAKpzmem53kRGEQg8WeqRmp12wgp74TGpkEXsGae7RS1k
123 enJCnma4fii+noGH7R0qKgHvPrI2Bwa9hzsH8tHxpyM3qrXslOmD45EH9SxIDUBJ
124 FehNdaPbLP1gFyahKMsdfxFJLUvbUycuZSJ2ZnIgeVxwm4qbSvZInL9Iu4FzuPtg
125 fINKcbbovy1qq4KvPIrXzhbY3PWDc6btxCf3SE0JdE1MCPThntB62/bLMSQ7xdDR
126 FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ
127 +QIDAQAB
128 -----END PUBLIC KEY-----
129 `
130
131 var pemPrivateKey = testingKey(`
132 -----BEGIN RSA TESTING KEY-----
133 MIICXAIBAAKBgQCxoeCUW5KJxNPxMp+KmCxKLc1Zv9Ny+4CFqcUXVUYH69L3mQ7v
134 IWrJ9GBfcaA7BPQqUlWxWM+OCEQZH1EZNIuqRMNQVuIGCbz5UQ8w6tS0gcgdeGX7
135 J7jgCQ4RK3F/PuCM38QBLaHx988qG8NMc6VKErBjctCXFHQt14lerd5KpQIDAQAB
136 AoGAYrf6Hbk+mT5AI33k2Jt1kcweodBP7UkExkPxeuQzRVe0KVJw0EkcFhywKpr1
137 V5eLMrILWcJnpyHE5slWwtFHBG6a5fLaNtsBBtcAIfqTQ0Vfj5c6SzVaJv0Z5rOd
138 7gQF6isy3t3w9IF3We9wXQKzT6q5ypPGdm6fciKQ8RnzREkCQQDZwppKATqQ41/R
139 vhSj90fFifrGE6aVKC1hgSpxGQa4oIdsYYHwMzyhBmWW9Xv/R+fPyr8ZwPxp2c12
140 33QwOLPLAkEA0NNUb+z4ebVVHyvSwF5jhfJxigim+s49KuzJ1+A2RaSApGyBZiwS
141 rWvWkB471POAKUYt5ykIWVZ83zcceQiNTwJBAMJUFQZX5GDqWFc/zwGoKkeR49Yi
142 MTXIvf7Wmv6E++eFcnT461FlGAUHRV+bQQXGsItR/opIG7mGogIkVXa3E1MCQARX
143 AAA7eoZ9AEHflUeuLn9QJI/r0hyQQLEtrpwv6rDT1GCWaLII5HJ6NUFVf4TTcqxo
144 6vdM4QGKTJoO+SaCyP0CQFdpcxSAuzpFcKv0IlJ8XzS/cy+mweCMwyJ1PFEc4FX6
145 wg/HcAJWY60xZTJDFN+Qfx8ZQvBEin6c2/h+zZi5IVY=
146 -----END RSA TESTING KEY-----
147 `)
148
149
150 var pemEd25519Key = `
151 -----BEGIN PUBLIC KEY-----
152 MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=
153 -----END PUBLIC KEY-----
154 `
155
156 var testPrivateKey *rsa.PrivateKey
157
158 func init() {
159 block, _ := pem.Decode([]byte(pemPrivateKey))
160
161 var err error
162 if testPrivateKey, err = ParsePKCS1PrivateKey(block.Bytes); err != nil {
163 panic("Failed to parse private key: " + err.Error())
164 }
165 }
166
167 func bigFromString(s string) *big.Int {
168 ret := new(big.Int)
169 ret.SetString(s, 10)
170 return ret
171 }
172
173 func fromBase10(base10 string) *big.Int {
174 i := new(big.Int)
175 i.SetString(base10, 10)
176 return i
177 }
178
179 func bigFromHexString(s string) *big.Int {
180 ret := new(big.Int)
181 ret.SetString(s, 16)
182 return ret
183 }
184
185 var rsaPrivateKey = &rsa.PrivateKey{
186 PublicKey: rsa.PublicKey{
187 N: bigFromString("124737666279038955318614287965056875799409043964547386061640914307192830334599556034328900586693254156136128122194531292927142396093148164407300419162827624945636708870992355233833321488652786796134504707628792159725681555822420087112284637501705261187690946267527866880072856272532711620639179596808018872997"),
188 E: 65537,
189 },
190 D: bigFromString("69322600686866301945688231018559005300304807960033948687567105312977055197015197977971637657636780793670599180105424702854759606794705928621125408040473426339714144598640466128488132656829419518221592374964225347786430566310906679585739468938549035854760501049443920822523780156843263434219450229353270690889"),
191 Primes: []*big.Int{
192 bigFromString("11405025354575369741595561190164746858706645478381139288033759331174478411254205003127028642766986913445391069745480057674348716675323735886284176682955723"),
193 bigFromString("10937079261204603443118731009201819560867324167189758120988909645641782263430128449826989846631183550578761324239709121189827307416350485191350050332642639"),
194 },
195 }
196
197 func TestMarshalRSAPrivateKey(t *testing.T) {
198 priv := &rsa.PrivateKey{
199 PublicKey: rsa.PublicKey{
200 N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
201 E: 3,
202 },
203 D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"),
204 Primes: []*big.Int{
205 fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
206 fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
207 fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
208 },
209 }
210
211 derBytes := MarshalPKCS1PrivateKey(priv)
212
213 priv2, err := ParsePKCS1PrivateKey(derBytes)
214 if err != nil {
215 t.Errorf("error parsing serialized key: %s", err)
216 return
217 }
218 if priv.PublicKey.N.Cmp(priv2.PublicKey.N) != 0 ||
219 priv.PublicKey.E != priv2.PublicKey.E ||
220 priv.D.Cmp(priv2.D) != 0 ||
221 len(priv2.Primes) != 3 ||
222 priv.Primes[0].Cmp(priv2.Primes[0]) != 0 ||
223 priv.Primes[1].Cmp(priv2.Primes[1]) != 0 ||
224 priv.Primes[2].Cmp(priv2.Primes[2]) != 0 {
225 t.Errorf("got:%+v want:%+v", priv, priv2)
226 }
227 }
228
229 func TestMarshalRSAPublicKey(t *testing.T) {
230 pub := &rsa.PublicKey{
231 N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
232 E: 3,
233 }
234 derBytes := MarshalPKCS1PublicKey(pub)
235 pub2, err := ParsePKCS1PublicKey(derBytes)
236 if err != nil {
237 t.Errorf("ParsePKCS1PublicKey: %s", err)
238 }
239 if pub.N.Cmp(pub2.N) != 0 || pub.E != pub2.E {
240 t.Errorf("ParsePKCS1PublicKey = %+v, want %+v", pub, pub2)
241 }
242
243
244
245
246 derBytes2, err := asn1.Marshal(*pub)
247 if err != nil {
248 t.Errorf("Marshal(rsa.PublicKey): %v", err)
249 } else if !bytes.Equal(derBytes, derBytes2) {
250 t.Errorf("Marshal(rsa.PublicKey) = %x, want %x", derBytes2, derBytes)
251 }
252 pub3 := new(rsa.PublicKey)
253 rest, err := asn1.Unmarshal(derBytes, pub3)
254 if err != nil {
255 t.Errorf("Unmarshal(rsa.PublicKey): %v", err)
256 }
257 if len(rest) != 0 || pub.N.Cmp(pub3.N) != 0 || pub.E != pub3.E {
258 t.Errorf("Unmarshal(rsa.PublicKey) = %+v, %q want %+v, %q", pub, rest, pub2, []byte(nil))
259 }
260
261 publicKeys := []struct {
262 derBytes []byte
263 expectedErrSubstr string
264 }{
265 {
266 derBytes: []byte{
267 0x30, 6,
268 0x02, 1,
269 17,
270 0x02, 1,
271 3,
272 },
273 }, {
274 derBytes: []byte{
275 0x30, 6,
276 0x02, 1,
277 0xff,
278 0x02, 1,
279 3,
280 },
281 expectedErrSubstr: "zero or negative",
282 }, {
283 derBytes: []byte{
284 0x30, 6,
285 0x02, 1,
286 17,
287 0x02, 1,
288 0xff,
289 },
290 expectedErrSubstr: "zero or negative",
291 }, {
292 derBytes: []byte{
293 0x30, 6,
294 0x02, 1,
295 17,
296 0x02, 1,
297 3,
298 1,
299 },
300 expectedErrSubstr: "trailing data",
301 }, {
302 derBytes: []byte{
303 0x30, 9,
304 0x02, 1,
305 17,
306 0x02, 4,
307 0x7f, 0xff, 0xff, 0xff,
308 },
309 }, {
310 derBytes: []byte{
311 0x30, 10,
312 0x02, 1,
313 17,
314 0x02, 5,
315 0x00, 0x80, 0x00, 0x00, 0x00,
316 },
317
318
319
320
321
322 expectedErrSubstr: "large",
323 },
324 }
325
326 for i, test := range publicKeys {
327 shouldFail := len(test.expectedErrSubstr) > 0
328 pub, err := ParsePKCS1PublicKey(test.derBytes)
329 if shouldFail {
330 if err == nil {
331 t.Errorf("#%d: unexpected success, got %#v", i, pub)
332 } else if !strings.Contains(err.Error(), test.expectedErrSubstr) {
333 t.Errorf("#%d: expected error containing %q, got %s", i, test.expectedErrSubstr, err)
334 }
335 } else {
336 if err != nil {
337 t.Errorf("#%d: unexpected failure: %s", i, err)
338 continue
339 }
340 reserialized := MarshalPKCS1PublicKey(pub)
341 if !bytes.Equal(reserialized, test.derBytes) {
342 t.Errorf("#%d: failed to reserialize: got %x, expected %x", i, reserialized, test.derBytes)
343 }
344 }
345 }
346 }
347
348 type matchHostnamesTest struct {
349 pattern, host string
350 ok bool
351 }
352
353 var matchHostnamesTests = []matchHostnamesTest{
354 {"a.b.c", "a.b.c", true},
355 {"a.b.c", "b.b.c", false},
356 {"", "b.b.c", false},
357 {"a.b.c", "", false},
358 {"example.com", "example.com", true},
359 {"example.com", "www.example.com", false},
360 {"*.example.com", "example.com", false},
361 {"*.example.com", "www.example.com", true},
362 {"*.example.com", "www.example.com.", true},
363 {"*.example.com", "xyz.www.example.com", false},
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 {"", ".", false},
369 {".", "", false},
370 {".", ".", false},
371 {"example.com", "example.com.", true},
372 {"example.com.", "example.com", true},
373 {"example.com.", "example.com.", true},
374 {"*.com.", "example.com.", true},
375 {"*.com.", "example.com", true},
376 {"*.com", "example.com", true},
377 {"*.com", "example.com.", true},
378 }
379
380 func TestMatchHostnames(t *testing.T) {
381 for i, test := range matchHostnamesTests {
382 r := matchHostnames(test.pattern, test.host)
383 if r != test.ok {
384 t.Errorf("#%d mismatch got: %t want: %t when matching '%s' against '%s'", i, r, test.ok, test.host, test.pattern)
385 }
386 }
387 }
388
389 func TestMatchIP(t *testing.T) {
390
391 c := &Certificate{
392 DNSNames: []string{"*.foo.bar.baz"},
393 Subject: pkix.Name{
394 CommonName: "*.foo.bar.baz",
395 },
396 }
397 err := c.VerifyHostname("quux.foo.bar.baz")
398 if err != nil {
399 t.Fatalf("VerifyHostname(quux.foo.bar.baz): %v", err)
400 }
401
402
403
404 c = &Certificate{
405 DNSNames: []string{"*.2.3.4"},
406 Subject: pkix.Name{
407 CommonName: "*.2.3.4",
408 },
409 }
410 err = c.VerifyHostname("1.2.3.4")
411 if err == nil {
412 t.Fatalf("VerifyHostname(1.2.3.4) should have failed, did not")
413 }
414
415 c = &Certificate{
416 IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")},
417 }
418 err = c.VerifyHostname("127.0.0.1")
419 if err != nil {
420 t.Fatalf("VerifyHostname(127.0.0.1): %v", err)
421 }
422 err = c.VerifyHostname("::1")
423 if err != nil {
424 t.Fatalf("VerifyHostname(::1): %v", err)
425 }
426 err = c.VerifyHostname("[::1]")
427 if err != nil {
428 t.Fatalf("VerifyHostname([::1]): %v", err)
429 }
430 }
431
432 func TestCertificateParse(t *testing.T) {
433 s, _ := hex.DecodeString(certBytes)
434 certs, err := ParseCertificates(s)
435 if IsFatal(err) {
436 t.Error(err)
437 }
438 if len(certs) != 2 {
439 t.Errorf("Wrong number of certs: got %d want 2", len(certs))
440 return
441 }
442
443 err = certs[0].CheckSignatureFrom(certs[1])
444 if err != nil {
445 t.Error(err)
446 }
447
448 if err := certs[0].VerifyHostname("mail.google.com"); err != nil {
449 t.Error(err)
450 }
451
452 const expectedExtensions = 4
453 if n := len(certs[0].Extensions); n != expectedExtensions {
454 t.Errorf("want %d extensions, got %d", expectedExtensions, n)
455 }
456 }
457
458 func TestCertificateEqualOnNil(t *testing.T) {
459 cNonNil := new(Certificate)
460 var cNil1, cNil2 *Certificate
461 if !cNil1.Equal(cNil2) {
462 t.Error("Nil certificates: cNil1 is not equal to cNil2")
463 }
464 if !cNil2.Equal(cNil1) {
465 t.Error("Nil certificates: cNil2 is not equal to cNil1")
466 }
467 if cNil1.Equal(cNonNil) {
468 t.Error("Unexpectedly cNil1 is equal to cNonNil")
469 }
470 if cNonNil.Equal(cNil1) {
471 t.Error("Unexpectedly cNonNil is equal to cNil1")
472 }
473 }
474
475 func TestMismatchedSignatureAlgorithm(t *testing.T) {
476 der, _ := pem.Decode([]byte(rsaPSSSelfSignedPEM))
477 if der == nil {
478 t.Fatal("Failed to find PEM block")
479 }
480
481 cert, err := ParseCertificate(der.Bytes)
482 if err != nil {
483 t.Fatal(err)
484 }
485
486 if err = cert.CheckSignature(ECDSAWithSHA256, nil, nil); err == nil {
487 t.Fatal("CheckSignature unexpectedly return no error")
488 }
489
490 const expectedSubstring = " but have public key of type "
491 if !strings.Contains(err.Error(), expectedSubstring) {
492 t.Errorf("Expected error containing %q, but got %q", expectedSubstring, err)
493 }
494 }
495
496 var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" +
497 "f70d0101050500304c310b3009060355040613025a4131253023060355040a131c546861777465" +
498 "20436f6e73756c74696e67202850747929204c74642e311630140603550403130d546861777465" +
499 "20534743204341301e170d3039303332353136343932395a170d3130303332353136343932395a" +
500 "3069310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630" +
501 "140603550407130d4d6f756e7461696e205669657731133011060355040a130a476f6f676c6520" +
502 "496e63311830160603550403130f6d61696c2e676f6f676c652e636f6d30819f300d06092a8648" +
503 "86f70d010101050003818d0030818902818100c5d6f892fccaf5614b064149e80a2c9581a218ef" +
504 "41ec35bd7a58125ae76f9ea54ddc893abbeb029f6b73616bf0ffd868791fba7af9c4aebf3706ba" +
505 "3eeaeed27435b4ddcfb157c05f351d66aa87fee0de072d66d773affbd36ab78bef090e0cc861a9" +
506 "03ac90dd98b51c9c41566c017f0beec3bff391051ffba0f5cc6850ad2a590203010001a381e730" +
507 "81e430280603551d250421301f06082b0601050507030106082b06010505070302060960864801" +
508 "86f842040130360603551d1f042f302d302ba029a0278625687474703a2f2f63726c2e74686177" +
509 "74652e636f6d2f54686177746553474343412e63726c307206082b060105050701010466306430" +
510 "2206082b060105050730018616687474703a2f2f6f6373702e7468617774652e636f6d303e0608" +
511 "2b060105050730028632687474703a2f2f7777772e7468617774652e636f6d2f7265706f736974" +
512 "6f72792f5468617774655f5347435f43412e637274300c0603551d130101ff04023000300d0609" +
513 "2a864886f70d01010505000381810062f1f3050ebc105e497c7aedf87e24d2f4a986bb3b837bd1" +
514 "9b91ebcad98b065992f6bd2b49b7d6d3cb2e427a99d606c7b1d46352527fac39e6a8b6726de5bf" +
515 "70212a52cba07634a5e332011bd1868e78eb5e3c93cf03072276786f207494feaa0ed9d53b2110" +
516 "a76571f90209cdae884385c882587030ee15f33d761e2e45a6bc308203233082028ca003020102" +
517 "020430000002300d06092a864886f70d0101050500305f310b3009060355040613025553311730" +
518 "15060355040a130e566572695369676e2c20496e632e31373035060355040b132e436c61737320" +
519 "33205075626c6963205072696d6172792043657274696669636174696f6e20417574686f726974" +
520 "79301e170d3034303531333030303030305a170d3134303531323233353935395a304c310b3009" +
521 "060355040613025a4131253023060355040a131c54686177746520436f6e73756c74696e672028" +
522 "50747929204c74642e311630140603550403130d5468617774652053474320434130819f300d06" +
523 "092a864886f70d010101050003818d0030818902818100d4d367d08d157faecd31fe7d1d91a13f" +
524 "0b713cacccc864fb63fc324b0794bd6f80ba2fe10493c033fc093323e90b742b71c403c6d2cde2" +
525 "2ff50963cdff48a500bfe0e7f388b72d32de9836e60aad007bc4644a3b847503f270927d0e62f5" +
526 "21ab693684317590f8bfc76c881b06957cc9e5a8de75a12c7a68dfd5ca1c875860190203010001" +
527 "a381fe3081fb30120603551d130101ff040830060101ff020100300b0603551d0f040403020106" +
528 "301106096086480186f842010104040302010630280603551d110421301fa41d301b3119301706" +
529 "035504031310507269766174654c6162656c332d313530310603551d1f042a30283026a024a022" +
530 "8620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c303206082b" +
531 "0601050507010104263024302206082b060105050730018616687474703a2f2f6f6373702e7468" +
532 "617774652e636f6d30340603551d25042d302b06082b0601050507030106082b06010505070302" +
533 "06096086480186f8420401060a6086480186f845010801300d06092a864886f70d010105050003" +
534 "81810055ac63eadea1ddd2905f9f0bce76be13518f93d9052bc81b774bad6950a1eededcfddb07" +
535 "e9e83994dcab72792f06bfab8170c4a8edea5334edef1e53d906c7562bd15cf4d18a8eb42bb137" +
536 "9048084225c53e8acb7feb6f04d16dc574a2f7a27c7b603c77cd0ece48027f012fb69b37e02a2a" +
537 "36dcd585d6ace53f546f961e05af"
538
539 var certWithSCTListPEM = `
540 -----BEGIN CERTIFICATE-----
541 MIIHkzCCBnugAwIBAgIUHz6ZOwEjk6zhU9v3n2Jo3qeucqYwDQYJKoZIhvcNAQEL
542 BQAwSTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHzAd
543 BgNVBAMTFlF1b1ZhZGlzIEVWIFNTTCBJQ0EgRzEwHhcNMTcwMjA4MTQxNTU3WhcN
544 MTgwMjA4MTQyNTAwWjCByzETMBEGCysGAQQBgjc8AgEDEwJHQjEYMBYGA1UEDwwP
545 QnVzaW5lc3MgRW50aXR5MREwDwYDVQQFEwhTQzA5NTAwMDELMAkGA1UEBhMCR0Ix
546 EjAQBgNVBAgMCUVkaW5idXJnaDESMBAGA1UEBwwJRWRpbmJ1cmdoMSEwHwYDVQQK
547 DBhMbG95ZHMgQmFua2luZyBHcm91cCBQTEMxEjAQBgNVBAsMCUdST1VQIElUMjEb
548 MBkGA1UEAwwSd3d3Lmxsb3lkc2JhbmsuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
549 AQ8AMIIBCgKCAQEAyRkzN3UmnYbuIW7V4P5qyF/3iCdJwaw/avb0tpOJTa/svtM2
550 9KxtVtgwqAPCSuWgjHh6lx+OzXBOh0cM1+gOvjscIJ7k6J0UKouhxrZ02G6CHiNS
551 0P3ztsW1CVYAnEQqnhC+hBSl+Ut7DdcsReOUaUrIbO8T0psfsBnez6VtcLB74Hi0
552 y6s2AOwPKG7zRjMcMEylOYyGMrUI4ooGsf7IBzMOdMZpkAMUEe6KZ/8AssZOH7F9
553 OacCBcGHwN3qp/AG02+tXGaS9DWCS9/seMWqyhE8YPk+iGV3sFZEueBMxixVObFZ
554 0Ezwv3cCel6v2mlA5OweteDI57VG4/7OI45CawIDAQABo4ID7jCCA+owdwYIKwYB
555 BQUHAQEEazBpMDgGCCsGAQUFBzAChixodHRwOi8vdHJ1c3QucXVvdmFkaXNnbG9i
556 YWwuY29tL3F2ZXZzc2wxLmNydDAtBggrBgEFBQcwAYYhaHR0cDovL2V2Lm9jc3Au
557 cXVvdmFkaXNnbG9iYWwuY29tMB0GA1UdDgQWBBSIASoK0Cmqs5B06CJUUzq5nQ6c
558 IDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFFVYhs66fHZOmROpD9Nsn8L10zzj
559 MFEGA1UdIARKMEgwRgYMKwYBBAG+WAACZAECMDYwNAYIKwYBBQUHAgEWKGh0dHA6
560 Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL3JlcG9zaXRvcnkwOwYDVR0fBDQwMjAw
561 oC6gLIYqaHR0cDovL2NybC5xdW92YWRpc2dsb2JhbC5jb20vcXZldnNzbDEuY3Js
562 MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw
563 gd8GA1UdEQSB1zCB1IISd3d3Lmxsb3lkc2JhbmsuY29tghRzdGF0aWMuaGFsaWZh
564 eC5jby51a4IUd3d3Lmxsb3lkc2JhbmsuY28udWuCFGltYWdlcy5oYWxpZmF4LmNv
565 LnVrghh3d3cuYmFua29mc2NvdGxhbmQuY28udWuCD3d3dy5oYWxpZmF4LmNvbYIT
566 d3d3Lmxsb3lkc3RzYi5jby51a4IRd3d3Lmxsb3lkc3RzYi5jb22CEXd3dy5oYWxp
567 ZmF4LmNvLnVrghZ3d3cuYmFua29mc2NvdGxhbmQuY29tMIIBfgYKKwYBBAHWeQIE
568 AgSCAW4EggFqAWgAdgC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAA
569 AVoeHdwIAAAEAwBHMEUCIQD3fh/6Cp3I44poKfhA7IkhjInvl8qC9JkooycB7NfE
570 lgIgMihc8F0Ap1gIU7WUCxWgV0nUxeWp34mp+g0IPnNJ1KcAdgCkuQmQtBhYFIe7
571 E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAVoeHdwaAAAEAwBHMEUCIA45u9pfeirN
572 Hn8K0xHDCUfCihQSFJo0YYmFxYEgO8GEAiEAwDXdmIkkv3lJ1td+RjTzXMBIjp9R
573 3Ii1GumOGKe8IqcAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAA
574 AVoeHdxAAAAEAwBHMEUCIEfe5grRiTvaHZJ4e4glbGftZ87n1pQf2lVeyBMUq0Xa
575 AiEA/+W+qCcVd3hHVaYJryO67SYCbUBinU5/6je8eDLOEM4wDQYJKoZIhvcNAQEL
576 BQADggEBADGdRf8XpQRPzxv+NeUr5i4q49JI8M/umbwSEXkHJmaDD4CDiUGkFUNR
577 Tte0HDRvjbu5y9xub09MgdMl84qvfjsph54rUVK7LWVphi6CC21XbRP5gEwKBeA2
578 wAZU1IhhWBy6DaW4CjpTu1Ji3FJqHqKklFrZTMSS+xoqfYbbN96q1mJHQhyDdRlC
579 JvNuS1lDM0u3+g/MHNpQM1aGZVKtwpzRABIYhydSJrO14TzWJjbKm1UTnKiwvHbt
580 p1ATnYNDZKj3Ec8EASXGTHHoorX0jZpMiNxHv4p4BUinsNFttkhudMGbCfbjjqef
581 UfUJESblkeQVpcnndMfnsHSahCVd96k=
582 -----END CERTIFICATE-----
583 `
584
585
586
587
606
607 var wantSCTs = []string{
608 ("00" +
609 "bbd9dfbc1f8a71b593942397aa927b473857950aab52e81a909664368e1ed185" +
610 "0000015a1e1ddc08" +
611 "0000" +
612 ("04" + "03" +
613 ("0047" +
614 "3045022100f77e1ffa0a9dc8e38a6829f840ec89218c89ef97ca82f49928a32701ecd7c496022032285cf05d00a7580853b5940b15a05749d4c5e5a9df89a9fa0d083e7349d4a7"))),
615
616 ("00" +
617 "a4b90990b418581487bb13a2cc67700a3c359804f91bdfb8e377cd0ec80ddc10" +
618 "0000015a1e1ddc1a" +
619 "0000" +
620 ("04" + "03" +
621 ("0047" +
622 "304502200e39bbda5f7a2acd1e7f0ad311c30947c28a1412149a34618985c581203bc184022100c035dd988924bf7949d6d77e4634f35cc0488e9f51dc88b51ae98e18a7bc22a7"))),
623 ("00" +
624 "5614069a2fd7c2ecd3f5e1bd44b23ec74676b9bc99115cc0ef949855d689d0dd" +
625 "0000015a1e1ddc40" +
626 "0000" +
627 ("04" + "03" +
628 ("0047" +
629 "3045022047dee60ad1893bda1d92787b88256c67ed67cee7d6941fda555ec81314ab45da022100ffe5bea8271577784755a609af23baed26026d40629d4e7fea37bc7832ce10ce"))),
630 }
631
632 func TestParseCertificateSCTs(t *testing.T) {
633 pemBlock, _ := pem.Decode([]byte(certWithSCTListPEM))
634 cert, err := ParseCertificate(pemBlock.Bytes)
635 if err != nil {
636 t.Fatalf("ParseCertificate()=_,%v; want _, nil", err)
637 }
638 if len(cert.RawSCT) == 0 {
639 t.Errorf("len(cert.RawSCT)=0, want >0")
640 }
641 for i, got := range cert.SCTList.SCTList {
642 want, _ := hex.DecodeString(wantSCTs[i])
643 if !bytes.Equal(got.Val, want) {
644 t.Errorf("SCT[%d]=%x; want %x", i, got.Val, want)
645 }
646 }
647 }
648
649 func parseCIDR(s string) *net.IPNet {
650 _, net, err := net.ParseCIDR(s)
651 if err != nil {
652 panic(err)
653 }
654 return net
655 }
656
657 func parseURI(s string) *url.URL {
658 uri, err := url.Parse(s)
659 if err != nil {
660 panic(err)
661 }
662 return uri
663 }
664
665 func TestCreateSelfSignedCertificate(t *testing.T) {
666 random := rand.Reader
667
668 ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
669 if err != nil {
670 t.Fatalf("Failed to generate ECDSA key: %s", err)
671 }
672
673 ed25519Pub, ed25519Priv, err := ed25519.GenerateKey(random)
674 if err != nil {
675 t.Fatalf("Failed to generate Ed25519 key: %s", err)
676 }
677
678 tests := []struct {
679 name string
680 pub, priv interface{}
681 checkSig bool
682 sigAlgo SignatureAlgorithm
683 }{
684 {"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, SHA1WithRSA},
685 {"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
686 {"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA},
687 {"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1},
688 {"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, SHA256WithRSAPSS},
689 {"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS},
690 {"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
691 {"Ed25519", ed25519Pub, ed25519Priv, true, PureEd25519},
692 }
693
694 testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth}
695 testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
696 extraExtensionData := []byte("extra extension")
697
698 for _, test := range tests {
699 commonName := "test.example.com"
700 template := Certificate{
701
702
703
704
705 SerialNumber: big.NewInt(-1),
706 Subject: pkix.Name{
707 CommonName: commonName,
708 Organization: []string{"Σ Acme Co"},
709 Country: []string{"US"},
710 ExtraNames: []pkix.AttributeTypeAndValue{
711 {
712 Type: []int{2, 5, 4, 42},
713 Value: "Gopher",
714 },
715
716 {
717 Type: []int{2, 5, 4, 6},
718 Value: "NL",
719 },
720 },
721 },
722 NotBefore: time.Unix(1000, 0),
723 NotAfter: time.Unix(100000, 0),
724
725 SignatureAlgorithm: test.sigAlgo,
726
727 SubjectKeyId: []byte{1, 2, 3, 4},
728 KeyUsage: KeyUsageCertSign,
729
730 ExtKeyUsage: testExtKeyUsage,
731 UnknownExtKeyUsage: testUnknownExtKeyUsage,
732
733 BasicConstraintsValid: true,
734 IsCA: true,
735
736 OCSPServer: []string{"http://ocsp.example.com"},
737 IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"},
738
739 DNSNames: []string{"test.example.com"},
740 EmailAddresses: []string{"gopher@golang.org"},
741 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
742 URIs: []*url.URL{parseURI("https://foo.com/wibble#foo")},
743
744 PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
745 PermittedDNSDomains: []string{".example.com", "example.com"},
746 ExcludedDNSDomains: []string{"bar.example.com"},
747 PermittedIPRanges: []*net.IPNet{parseCIDR("192.168.1.1/16"), parseCIDR("1.2.3.4/8")},
748 ExcludedIPRanges: []*net.IPNet{parseCIDR("2001:db8::/48")},
749 PermittedEmailAddresses: []string{"foo@example.com"},
750 ExcludedEmailAddresses: []string{".example.com", "example.com"},
751 PermittedURIDomains: []string{".bar.com", "bar.com"},
752 ExcludedURIDomains: []string{".bar2.com", "bar2.com"},
753
754 CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
755
756 RawSCT: []byte{0xde, 0xad},
757 SCTList: SignedCertificateTimestampList{
758 SCTList: []SerializedSCT{
759 {Val: []byte{0x01, 0x02, 0x03}},
760 {Val: []byte{0x04, 0x05, 0x06}},
761 },
762 },
763
764 ExtraExtensions: []pkix.Extension{
765 {
766 Id: []int{1, 2, 3, 4},
767 Value: extraExtensionData,
768 },
769
770 {
771 Id: OIDExtensionSubjectKeyId,
772 Critical: false,
773 Value: []byte{0x04, 0x04, 4, 3, 2, 1},
774 },
775 },
776 }
777
778 derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv)
779 if err != nil {
780 t.Errorf("%s: failed to create certificate: %s", test.name, err)
781 continue
782 }
783
784 cert, err := ParseCertificate(derBytes)
785 if err != nil {
786 t.Errorf("%s: failed to parse certificate: %s", test.name, err)
787 continue
788 }
789
790 if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) {
791 t.Errorf("%s: failed to parse policy identifiers: got:%#v want:%#v", test.name, cert.PolicyIdentifiers, template.PolicyIdentifiers)
792 }
793
794 if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" {
795 t.Errorf("%s: failed to parse name constraints: %#v", test.name, cert.PermittedDNSDomains)
796 }
797
798 if len(cert.ExcludedDNSDomains) != 1 || cert.ExcludedDNSDomains[0] != "bar.example.com" {
799 t.Errorf("%s: failed to parse name constraint exclusions: %#v", test.name, cert.ExcludedDNSDomains)
800 }
801
802 if len(cert.PermittedIPRanges) != 2 || cert.PermittedIPRanges[0].String() != "192.168.0.0/16" || cert.PermittedIPRanges[1].String() != "1.0.0.0/8" {
803 t.Errorf("%s: failed to parse IP constraints: %#v", test.name, cert.PermittedIPRanges)
804 }
805
806 if len(cert.ExcludedIPRanges) != 1 || cert.ExcludedIPRanges[0].String() != "2001:db8::/48" {
807 t.Errorf("%s: failed to parse IP constraint exclusions: %#v", test.name, cert.ExcludedIPRanges)
808 }
809
810 if len(cert.PermittedEmailAddresses) != 1 || cert.PermittedEmailAddresses[0] != "foo@example.com" {
811 t.Errorf("%s: failed to parse permitted email addreses: %#v", test.name, cert.PermittedEmailAddresses)
812 }
813
814 if len(cert.ExcludedEmailAddresses) != 2 || cert.ExcludedEmailAddresses[0] != ".example.com" || cert.ExcludedEmailAddresses[1] != "example.com" {
815 t.Errorf("%s: failed to parse excluded email addreses: %#v", test.name, cert.ExcludedEmailAddresses)
816 }
817
818 if len(cert.PermittedURIDomains) != 2 || cert.PermittedURIDomains[0] != ".bar.com" || cert.PermittedURIDomains[1] != "bar.com" {
819 t.Errorf("%s: failed to parse permitted URIs: %#v", test.name, cert.PermittedURIDomains)
820 }
821
822 if len(cert.ExcludedURIDomains) != 2 || cert.ExcludedURIDomains[0] != ".bar2.com" || cert.ExcludedURIDomains[1] != "bar2.com" {
823 t.Errorf("%s: failed to parse excluded URIs: %#v", test.name, cert.ExcludedURIDomains)
824 }
825
826 if cert.Subject.CommonName != commonName {
827 t.Errorf("%s: subject wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Subject.CommonName, commonName)
828 }
829
830 if len(cert.Subject.Country) != 1 || cert.Subject.Country[0] != "NL" {
831 t.Errorf("%s: ExtraNames didn't override Country", test.name)
832 }
833
834 for _, ext := range cert.Extensions {
835 if ext.Id.Equal(OIDExtensionSubjectAltName) {
836 if ext.Critical {
837 t.Fatal("SAN extension is marked critical")
838 }
839 }
840 }
841
842 found := false
843 for _, atv := range cert.Subject.Names {
844 if atv.Type.Equal([]int{2, 5, 4, 42}) {
845 found = true
846 break
847 }
848 }
849 if !found {
850 t.Errorf("%s: Names didn't contain oid 2.5.4.42 from ExtraNames", test.name)
851 }
852
853 if cert.Issuer.CommonName != commonName {
854 t.Errorf("%s: issuer wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Issuer.CommonName, commonName)
855 }
856
857 if cert.SignatureAlgorithm != test.sigAlgo {
858 t.Errorf("%s: SignatureAlgorithm wasn't copied from template. Got %v, want %v", test.name, cert.SignatureAlgorithm, test.sigAlgo)
859 }
860
861 if !reflect.DeepEqual(cert.ExtKeyUsage, testExtKeyUsage) {
862 t.Errorf("%s: extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.ExtKeyUsage, testExtKeyUsage)
863 }
864
865 if !reflect.DeepEqual(cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) {
866 t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage)
867 }
868
869 if !reflect.DeepEqual(cert.OCSPServer, template.OCSPServer) {
870 t.Errorf("%s: OCSP servers differ from template. Got %v, want %v", test.name, cert.OCSPServer, template.OCSPServer)
871 }
872
873 if !reflect.DeepEqual(cert.IssuingCertificateURL, template.IssuingCertificateURL) {
874 t.Errorf("%s: Issuing certificate URLs differ from template. Got %v, want %v", test.name, cert.IssuingCertificateURL, template.IssuingCertificateURL)
875 }
876
877 if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) {
878 t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames)
879 }
880
881 if !reflect.DeepEqual(cert.EmailAddresses, template.EmailAddresses) {
882 t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses)
883 }
884
885 if len(cert.URIs) != 1 || cert.URIs[0].String() != "https://foo.com/wibble#foo" {
886 t.Errorf("%s: URIs differ from template. Got %v, want %v", test.name, cert.URIs, template.URIs)
887 }
888
889 if !reflect.DeepEqual(cert.IPAddresses, template.IPAddresses) {
890 t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses)
891 }
892
893 if !reflect.DeepEqual(cert.CRLDistributionPoints, template.CRLDistributionPoints) {
894 t.Errorf("%s: CRL distribution points differ from template. Got %v, want %v", test.name, cert.CRLDistributionPoints, template.CRLDistributionPoints)
895 }
896
897 if !reflect.DeepEqual(cert.SCTList, template.SCTList) {
898 t.Errorf("%s: SCTList differs from template. Got %v, want %v", test.name, cert.SCTList, template.SCTList)
899 }
900
901 if !bytes.Equal(cert.SubjectKeyId, []byte{4, 3, 2, 1}) {
902 t.Errorf("%s: ExtraExtensions didn't override SubjectKeyId", test.name)
903 }
904
905 if !bytes.Contains(derBytes, extraExtensionData) {
906 t.Errorf("%s: didn't find extra extension in DER output", test.name)
907 }
908
909 if test.checkSig {
910 err = cert.CheckSignatureFrom(cert)
911 if err != nil {
912 t.Errorf("%s: signature verification failed: %s", test.name, err)
913 }
914 }
915 }
916 }
917
918
919 var ecdsaSHA1CertPem = `
920 -----BEGIN CERTIFICATE-----
921 MIICDjCCAbUCCQDF6SfN0nsnrjAJBgcqhkjOPQQBMIGPMQswCQYDVQQGEwJVUzET
922 MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEVMBMG
923 A1UECgwMR29vZ2xlLCBJbmMuMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
924 CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIwMjAyMDUw
925 WhcNMjIwNTE4MjAyMDUwWjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
926 b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTATBgNVBAoMDEdvb2dsZSwg
927 SW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAhBgkqhkiG9w0BCQEWFGdv
928 bGFuZy1kZXZAZ21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/Wgn
929 WQDo5+bz71T0327ERgd5SDDXFbXLpzIZDXTkjpe8QTEbsF+ezsQfrekrpDPC4Cd3
930 P9LY0tG+aI8IyVKdUjAJBgcqhkjOPQQBA0gAMEUCIGlsqMcRqWVIWTD6wXwe6Jk2
931 DKxL46r/FLgJYnzBEH99AiEA3fBouObsvV1R3oVkb4BQYnD4/4LeId6lAT43YvyV
932 a/A=
933 -----END CERTIFICATE-----
934 `
935
936
937 var ecdsaSHA256p256CertPem = `
938 -----BEGIN CERTIFICATE-----
939 MIICDzCCAbYCCQDlsuMWvgQzhTAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCVVMx
940 EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT
941 BgNVBAoMDEdvb2dsZSwgSW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAh
942 BgkqhkiG9w0BCQEWFGdvbGFuZy1kZXZAZ21haWwuY29tMB4XDTEyMDUyMTAwMTkx
943 NloXDTIyMDUxOTAwMTkxNlowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
944 Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYDVQQKDAxHb29nbGUs
945 IEluYy4xFzAVBgNVBAMMDnd3dy5nb29nbGUuY29tMSMwIQYJKoZIhvcNAQkBFhRn
946 b2xhbmctZGV2QGdtYWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPMt
947 2ErhxAty5EJRu9yM+MTy+hUXm3pdW1ensAv382KoGExSXAFWP7pjJnNtHO+XSwVm
948 YNtqjcAGFKpweoN//kQwCgYIKoZIzj0EAwIDRwAwRAIgIYSaUA/IB81gjbIw/hUV
949 70twxJr5EcgOo0hLp3Jm+EYCIFDO3NNcgmURbJ1kfoS3N/0O+irUtoPw38YoNkqJ
950 h5wi
951 -----END CERTIFICATE-----
952 `
953
954
955 var ecdsaSHA256p384CertPem = `
956 -----BEGIN CERTIFICATE-----
957 MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx
958 EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
959 BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
960 CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0
961 WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
962 b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
963 SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
964 YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK
965 jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze
966 qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI
967 zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr
968 PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh
969 3yILeYQzllt/g0rKVRk=
970 -----END CERTIFICATE-----
971 `
972
973
974 var ecdsaSHA384p521CertPem = `
975 -----BEGIN CERTIFICATE-----
976 MIICljCCAfcCCQDhp1AFD/ahKjAKBggqhkjOPQQDAzCBjjELMAkGA1UEBhMCVVMx
977 EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
978 BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
979 CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMTUwNDI5
980 WhcNMjIwNTE5MTUwNDI5WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
981 b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
982 SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
983 YW5nLWRldkBnbWFpbC5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACqx9Rv
984 IssRs1LWYcNN+WffwlHw4Tv3y8/LIAA9MF1ZScIonU9nRMxt4a2uGJVCPDw6JHpz
985 PaYc0E9puLoE9AfKpwFr59Jkot7dBg55SKPEFkddoip/rvmN7NPAWjMBirOwjOkm
986 8FPthvPhGPqsu9AvgVuHu3PosWiHGNrhh379pva8MzAKBggqhkjOPQQDAwOBjAAw
987 gYgCQgEHNmswkUdPpHqrVxp9PvLVl+xxPuHBkT+75z9JizyxtqykHQo9Uh6SWCYH
988 BF9KLolo01wMt8DjoYP5Fb3j5MH7xwJCAbWZzTOp4l4DPkIvAh4LeC4VWbwPPyqh
989 kBg71w/iEcSY3wUKgHGcJJrObZw7wys91I5kENljqw/Samdr3ka+jBJa
990 -----END CERTIFICATE-----
991 `
992
993 var ecdsaTests = []struct {
994 sigAlgo SignatureAlgorithm
995 pemCert string
996 }{
997 {ECDSAWithSHA1, ecdsaSHA1CertPem},
998 {ECDSAWithSHA256, ecdsaSHA256p256CertPem},
999 {ECDSAWithSHA256, ecdsaSHA256p384CertPem},
1000 {ECDSAWithSHA384, ecdsaSHA384p521CertPem},
1001 }
1002
1003 func TestECDSA(t *testing.T) {
1004 for i, test := range ecdsaTests {
1005 pemBlock, _ := pem.Decode([]byte(test.pemCert))
1006 cert, err := ParseCertificate(pemBlock.Bytes)
1007 if err != nil {
1008 t.Errorf("%d: failed to parse certificate: %s", i, err)
1009 continue
1010 }
1011 if sa := cert.SignatureAlgorithm; sa != test.sigAlgo {
1012 t.Errorf("%d: signature algorithm is %v, want %v", i, sa, test.sigAlgo)
1013 }
1014 if parsedKey, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok {
1015 t.Errorf("%d: wanted an ECDSA public key but found: %#v", i, parsedKey)
1016 }
1017 if pka := cert.PublicKeyAlgorithm; pka != ECDSA {
1018 t.Errorf("%d: public key algorithm is %v, want ECDSA", i, pka)
1019 }
1020 if err = cert.CheckSignatureFrom(cert); err != nil {
1021 t.Errorf("%d: certificate verification failed: %s", i, err)
1022 }
1023 }
1024 }
1025
1026
1027 var dsaCertPem = `-----BEGIN CERTIFICATE-----
1028 MIIEDTCCA82gAwIBAgIJALHPghaoxeDhMAkGByqGSM44BAMweTELMAkGA1UEBhMC
1029 VVMxCzAJBgNVBAgTAk5DMQ8wDQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2ds
1030 ZSwgSW5jMRIwEAYDVQQDEwlKb24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFs
1031 bGllQGdvb2dsZS5jb20wHhcNMTEwNTE0MDMwMTQ1WhcNMTEwNjEzMDMwMTQ1WjB5
1032 MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTkMxDzANBgNVBAcTBk5ld3RvbjEUMBIG
1033 A1UEChMLR29vZ2xlLCBJbmMxEjAQBgNVBAMTCUpvbiBBbGxpZTEiMCAGCSqGSIb3
1034 DQEJARYTam9uYWxsaWVAZ29vZ2xlLmNvbTCCAbcwggEsBgcqhkjOOAQBMIIBHwKB
1035 gQC8hLUnQ7FpFYu4WXTj6DKvXvz8QrJkNJCVMTpKAT7uBpobk32S5RrPKXocd4gN
1036 8lyGB9ggS03EVlEwXvSmO0DH2MQtke2jl9j1HLydClMf4sbx5V6TV9IFw505U1iW
1037 jL7awRMgxge+FsudtJK254FjMFo03ZnOQ8ZJJ9E6AEDrlwIVAJpnBn9moyP11Ox5
1038 Asc/5dnjb6dPAoGBAJFHd4KVv1iTVCvEG6gGiYop5DJh28hUQcN9kul+2A0yPUSC
1039 X93oN00P8Vh3eYgSaCWZsha7zDG53MrVJ0Zf6v/X/CoZNhLldeNOepivTRAzn+Rz
1040 kKUYy5l1sxYLHQKF0UGNCXfFKZT0PCmgU+PWhYNBBMn6/cIh44vp85ideo5CA4GE
1041 AAKBgFmifCafzeRaohYKXJgMGSEaggCVCRq5xdyDCat+wbOkjC4mfG01/um3G8u5
1042 LxasjlWRKTR/tcAL7t0QuokVyQaYdVypZXNaMtx1db7YBuHjj3aP+8JOQRI9xz8c
1043 bp5NDJ5pISiFOv4p3GZfqZPcqckDt78AtkQrmnal2txhhjF6o4HeMIHbMB0GA1Ud
1044 DgQWBBQVyyr7hO11ZFFpWX50298Sa3V+rzCBqwYDVR0jBIGjMIGggBQVyyr7hO11
1045 ZFFpWX50298Sa3V+r6F9pHsweTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5DMQ8w
1046 DQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2dsZSwgSW5jMRIwEAYDVQQDEwlK
1047 b24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFsbGllQGdvb2dsZS5jb22CCQCx
1048 z4IWqMXg4TAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUPtn/5j8Q1jJI
1049 7ggOIsgrhgUdjGQCFCsmDq1H11q9+9Wp9IMeGrTSKHIM
1050 -----END CERTIFICATE-----
1051 `
1052
1053 func TestParseCertificateWithDsaPublicKey(t *testing.T) {
1054 expectedKey := &dsa.PublicKey{
1055 Parameters: dsa.Parameters{
1056 P: bigFromHexString("00BC84B52743B169158BB85974E3E832AF5EFCFC42B264349095313A4A013EEE069A1B937D92E51ACF297A1C77880DF25C8607D8204B4DC45651305EF4A63B40C7D8C42D91EDA397D8F51CBC9D0A531FE2C6F1E55E9357D205C39D395358968CBEDAC11320C607BE16CB9DB492B6E78163305A34DD99CE43C64927D13A0040EB97"),
1057 Q: bigFromHexString("009A67067F66A323F5D4EC7902C73FE5D9E36FA74F"),
1058 G: bigFromHexString("009147778295BF5893542BC41BA806898A29E43261DBC85441C37D92E97ED80D323D44825FDDE8374D0FF15877798812682599B216BBCC31B9DCCAD527465FEAFFD7FC2A193612E575E34E7A98AF4D10339FE47390A518CB9975B3160B1D0285D1418D0977C52994F43C29A053E3D685834104C9FAFDC221E38BE9F3989D7A8E42"),
1059 },
1060 Y: bigFromHexString("59A27C269FCDE45AA2160A5C980C19211A820095091AB9C5DC8309AB7EC1B3A48C2E267C6D35FEE9B71BCBB92F16AC8E559129347FB5C00BEEDD10BA8915C90698755CA965735A32DC7575BED806E1E38F768FFBC24E41123DC73F1C6E9E4D0C9E692128853AFE29DC665FA993DCA9C903B7BF00B6442B9A76A5DADC6186317A"),
1061 }
1062 pemBlock, _ := pem.Decode([]byte(dsaCertPem))
1063 cert, err := ParseCertificate(pemBlock.Bytes)
1064 if err != nil {
1065 t.Fatalf("Failed to parse certificate: %s", err)
1066 }
1067 if cert.PublicKeyAlgorithm != DSA {
1068 t.Errorf("Parsed key algorithm was not DSA")
1069 }
1070 parsedKey, ok := cert.PublicKey.(*dsa.PublicKey)
1071 if !ok {
1072 t.Fatalf("Parsed key was not a DSA key: %s", err)
1073 }
1074 if expectedKey.Y.Cmp(parsedKey.Y) != 0 ||
1075 expectedKey.P.Cmp(parsedKey.P) != 0 ||
1076 expectedKey.Q.Cmp(parsedKey.Q) != 0 ||
1077 expectedKey.G.Cmp(parsedKey.G) != 0 {
1078 t.Fatal("Parsed key differs from expected key")
1079 }
1080 }
1081
1082 func TestParseCertificateWithDSASignatureAlgorithm(t *testing.T) {
1083 pemBlock, _ := pem.Decode([]byte(dsaCertPem))
1084 cert, err := ParseCertificate(pemBlock.Bytes)
1085 if err != nil {
1086 t.Fatalf("Failed to parse certificate: %s", err)
1087 }
1088 if cert.SignatureAlgorithm != DSAWithSHA1 {
1089 t.Errorf("Parsed signature algorithm was not DSAWithSHA1")
1090 }
1091 }
1092
1093 func TestVerifyCertificateWithDSASignature(t *testing.T) {
1094 pemBlock, _ := pem.Decode([]byte(dsaCertPem))
1095 cert, err := ParseCertificate(pemBlock.Bytes)
1096 if err != nil {
1097 t.Fatalf("Failed to parse certificate: %s", err)
1098 }
1099
1100 if err = cert.CheckSignatureFrom(cert); err != nil {
1101 t.Fatalf("DSA Certificate verification failed: %s", err)
1102 }
1103 }
1104
1105 const dsaCert1024WithSha256 = `-----BEGIN CERTIFICATE-----
1106 MIIDKzCCAumgAwIBAgIUOXWPK4gTRZVVY7OSXTU00QEWQU8wCwYJYIZIAWUDBAMC
1107 MEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJ
1108 bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMTkxMDAxMDYxODUyWhgPMzAxOTAy
1109 MDEwNjE4NTJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
1110 HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggG4MIIBLAYHKoZIzjgE
1111 ATCCAR8CgYEAr79m/1ypU1aUbbLX1jikTyX7w2QYP+EkxNtXUiiTuxkC1KBqqxT3
1112 0Aht2vxFR47ODEK4B79rHO+UevhaqDaAHSH7Z/9umS0h0aS32KLDLb+LI5AneCrn
1113 eW5YbVhfD03N7uR4kKUCKOnWj5hAk9xiE3y7oFR0bBXzqrrHJF9LMd0CFQCB6lSj
1114 HSW0rGmNxIZsBl72u7JFLQKBgQCOFd1PGEQmddn0cdFgby5QQfjrqmoD1zNlFZEt
1115 L0x1EbndFwelLlF1ChNh3NPNUkjwRbla07FDlONs1GMJq6w4vW11ns+pUvAZ2+RM
1116 EVFjugip8az2ncn3UujGTVdFxnSTLBsRlMP/tFDK3ky//8zn/5ha9SKKw4v1uv6M
1117 JuoIbwOBhQACgYEAoeKeR90nwrnoPi5MOUPBLQvuzB87slfr+3kL8vFCmgjA6MtB
1118 7TxQKoBTOo5aVgWDp0lMIMxLd6btzBrm6r3VdRlh/cL8/PtbxkFwBa+Upe4o5NAh
1119 ISCe2/f2leT1PxtF8xxYjz/fszeUeHsJbVMilE2cuB2SYrR5tMExiqy+QpqjUzBR
1120 MB0GA1UdDgQWBBQDMIEL8Z3jc1d9wCxWtksUWc8RkjAfBgNVHSMEGDAWgBQDMIEL
1121 8Z3jc1d9wCxWtksUWc8RkjAPBgNVHRMBAf8EBTADAQH/MAsGCWCGSAFlAwQDAgMv
1122 ADAsAhQFehZgI4OyKBGpfnXvyJ0Z/0a6nAIUTO265Ane87LfJuQr3FrqvuCI354=
1123 -----END CERTIFICATE-----
1124 `
1125
1126 func TestVerifyCertificateWithDSATooLongHash(t *testing.T) {
1127 pemBlock, _ := pem.Decode([]byte(dsaCert1024WithSha256))
1128 cert, err := ParseCertificate(pemBlock.Bytes)
1129 if err != nil {
1130 t.Fatalf("Failed to parse certificate: %s", err)
1131 }
1132
1133
1134 if err = cert.CheckSignatureFrom(cert); err != nil {
1135 t.Fatalf("DSA Certificate self-signature verification failed: %s", err)
1136 }
1137
1138 signed := []byte("A wild Gopher appears!\n")
1139 signature, _ := hex.DecodeString("302c0214417aca7ff458f5b566e43e7b82f994953da84be50214625901e249e33f4e4838f8b5966020c286dd610e")
1140
1141
1142
1143 if err = cert.CheckSignature(DSAWithSHA256, signed, signature); err != nil {
1144 t.Fatalf("DSA signature verification failed: %s", err)
1145 }
1146 }
1147
1148 var rsaPSSSelfSignedPEM = `-----BEGIN CERTIFICATE-----
1149 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
1182 -----END CERTIFICATE-----`
1183
1184
1185
1186
1187
1188 var rsaPSSSelfSignedOpenSSL110PEM = `-----BEGIN CERTIFICATE-----
1189 MIIDwDCCAnigAwIBAgIJAM9LAMHTE5xpMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZI
1190 AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgMEUxCzAJBgNV
1191 BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDTALBgNVBAoMBFRlc3Qx
1192 DTALBgNVBAMMBFRlc3QwHhcNMTgwMjIyMjIxMzE4WhcNMjgwMjIwMjIxMzE4WjBF
1193 MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMQ0wCwYDVQQK
1194 DARUZXN0MQ0wCwYDVQQDDARUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
1195 CgKCAQEA4Zrsydod+GoTAJLLutWNF87qhhVPBsK1zB1Gj+NAAe4+VbrZ1E41H1wp
1196 qITx7DA8DRtJEf+NqrTAnAdZWBG/tAOA5LfXVax0ZSQtLnYLSeylLoMtDyY3eFAj
1197 TmuTOoyVy6raktowCnHCh01NsstqqTfrx6SbmzOmDmKTkq/I+7K0MCVsn41xRDVM
1198 +ShD0WGFGioEGoiWnFSWupxJDA3Q6jIDEygVwNKHwnhv/2NgG2kqZzrZSQA67en0
1199 iKAXtoDNPpmyD5oS9YbEJ+2Nbm7oLeON30i6kZvXKIzJXx+UWViazHZqnsi5rQ8G
1200 RHF+iVFXsqd0MzDKmkKOT5FDhrsbKQIDAQABo1MwUTAdBgNVHQ4EFgQU9uFY/nlg
1201 gLH00NBnr/o7QvpN9ugwHwYDVR0jBBgwFoAU9uFY/nlggLH00NBnr/o7QvpN9ugw
1202 DwYDVR0TAQH/BAUwAwEB/zA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEa
1203 MBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIAOCAQEAhJzpwxBNGKvzKWDe
1204 WLqv6RMrl/q4GcH3b7M9wjxe0yOm4F+Tb2zJ7re4h+D39YkJf8cX1NV9UQVu6z4s
1205 Fvo2kmlR0qZOXAg5augmCQ1xS0WHFoF6B52anNzHkZQbAIYJ3kGoFsUHzs7Sz7F/
1206 656FsRpHA9UzJQ3avPPMrA4Y4aoJ7ANJ6XIwTrdWrhULOVuvYRLCl4CdTVztVFX6
1207 wxX8nS1ISYd8jXPUMgsBKVbWufvLoIymMJW8CZbpprVZel5zFn0bmPrON8IHS30w
1208 Gs+ITJjKEnZgXmAQ25SLKVzkZkBcGANs2GsdHNJ370Puisy0FIPD2NXR5uASAf7J
1209 +w9fjQ==
1210 -----END CERTIFICATE-----`
1211
1212 func TestRSAPSSSelfSigned(t *testing.T) {
1213 for i, pemBlock := range []string{rsaPSSSelfSignedPEM, rsaPSSSelfSignedOpenSSL110PEM} {
1214 der, _ := pem.Decode([]byte(pemBlock))
1215 if der == nil {
1216 t.Errorf("#%d: failed to find PEM block", i)
1217 continue
1218 }
1219
1220 cert, err := ParseCertificate(der.Bytes)
1221 if err != nil {
1222 t.Errorf("#%d: failed to parse: %s", i, err)
1223 continue
1224 }
1225
1226 if err = cert.CheckSignatureFrom(cert); err != nil {
1227 t.Errorf("#%d: signature check failed: %s", i, err)
1228 continue
1229 }
1230 }
1231 }
1232
1233 const ed25519Certificate = `
1234 Certificate:
1235 Data:
1236 Version: 3 (0x2)
1237 Serial Number:
1238 0c:83:d8:21:2b:82:cb:23:98:23:63:e2:f7:97:8a:43:5b:f3:bd:92
1239 Signature Algorithm: ED25519
1240 Issuer: CN = Ed25519 test certificate
1241 Validity
1242 Not Before: May 6 17:27:16 2019 GMT
1243 Not After : Jun 5 17:27:16 2019 GMT
1244 Subject: CN = Ed25519 test certificate
1245 Subject Public Key Info:
1246 Public Key Algorithm: ED25519
1247 ED25519 Public-Key:
1248 pub:
1249 36:29:c5:6c:0d:4f:14:6c:81:d0:ff:75:d3:6a:70:
1250 5f:69:cd:0f:4d:66:d5:da:98:7e:82:49:89:a3:8a:
1251 3c:fa
1252 X509v3 extensions:
1253 X509v3 Subject Key Identifier:
1254 09:3B:3A:9D:4A:29:D8:95:FF:68:BE:7B:43:54:72:E0:AD:A2:E3:AE
1255 X509v3 Authority Key Identifier:
1256 keyid:09:3B:3A:9D:4A:29:D8:95:FF:68:BE:7B:43:54:72:E0:AD:A2:E3:AE
1257
1258 X509v3 Basic Constraints: critical
1259 CA:TRUE
1260 Signature Algorithm: ED25519
1261 53:a5:58:1c:2c:3b:2a:9e:ac:9d:4e:a5:1d:5f:5d:6d:a6:b5:
1262 08:de:12:82:f3:97:20:ae:fa:d8:98:f4:1a:83:32:6b:91:f5:
1263 24:1d:c4:20:7f:2c:e2:4d:da:13:3b:6d:54:1a:d2:a8:28:dc:
1264 60:b9:d4:f4:78:4b:3c:1c:91:00
1265 -----BEGIN CERTIFICATE-----
1266 MIIBWzCCAQ2gAwIBAgIUDIPYISuCyyOYI2Pi95eKQ1vzvZIwBQYDK2VwMCMxITAf
1267 BgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZpY2F0ZTAeFw0xOTA1MDYxNzI3MTZa
1268 Fw0xOTA2MDUxNzI3MTZaMCMxITAfBgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZp
1269 Y2F0ZTAqMAUGAytlcAMhADYpxWwNTxRsgdD/ddNqcF9pzQ9NZtXamH6CSYmjijz6
1270 o1MwUTAdBgNVHQ4EFgQUCTs6nUop2JX/aL57Q1Ry4K2i464wHwYDVR0jBBgwFoAU
1271 CTs6nUop2JX/aL57Q1Ry4K2i464wDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXADQQBT
1272 pVgcLDsqnqydTqUdX11tprUI3hKC85cgrvrYmPQagzJrkfUkHcQgfyziTdoTO21U
1273 GtKoKNxgudT0eEs8HJEA
1274 -----END CERTIFICATE-----`
1275
1276 func TestEd25519SelfSigned(t *testing.T) {
1277 der, _ := pem.Decode([]byte(ed25519Certificate))
1278 if der == nil {
1279 t.Fatalf("Failed to find PEM block")
1280 }
1281
1282 cert, err := ParseCertificate(der.Bytes)
1283 if err != nil {
1284 t.Fatalf("Failed to parse: %s", err)
1285 }
1286
1287 if cert.PublicKeyAlgorithm != Ed25519 {
1288 t.Fatalf("Parsed key algorithm was not Ed25519")
1289 }
1290 parsedKey, ok := cert.PublicKey.(ed25519.PublicKey)
1291 if !ok {
1292 t.Fatalf("Parsed key was not an Ed25519 key: %s", err)
1293 }
1294 if len(parsedKey) != ed25519.PublicKeySize {
1295 t.Fatalf("Invalid Ed25519 key")
1296 }
1297
1298 if err = cert.CheckSignatureFrom(cert); err != nil {
1299 t.Fatalf("Signature check failed: %s", err)
1300 }
1301 }
1302
1303
1304
1305
1306
1307
1308 var oaepCertPEM = `-----BEGIN CERTIFICATE-----
1309 MIIFbjCCBFagAwIBAgIEZPW9pTANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJE
1310 RTEPMA0GA1UECBMGU2F4b255MSEwHwYDVQQKExhJbmZpbmVvbiBUZWNobm9sb2dp
1311 ZXMgQUcxDDAKBgNVBAsTA0FJTTEmMCQGA1UEAxMdSUZYIFRQTSBFSyBJbnRlcm1l
1312 ZGlhdGUgQ0EgMjAwHhcNMTUwOTIxMjEyOTI4WhcNMjUwOTIxMjEyOTI4WjAAMIIB
1313 NzAiBgkqhkiG9w0BAQcwFaITMBEGCSqGSIb3DQEBCQQEVENQQQOCAQ8AMIIBCgKC
1314 AQEAjnmDEFBjo/HC5318i09BHbnHbxE2bMuxF1cAH6UYBbu/aLbczZrSioLGqDHh
1315 WR8GGBwuMowmHPmhT/FwTcMmHMFtp1F2AUGWkzCnWz/Frhhax21japejOYOL0EKq
1316 fFmZ9j+UbGmHsOi+j1kI0IVj9ivG7pUQ42dSvTsue1UoG8kqjcyLqKMNaqp1gLZy
1317 2DgCRJ00v+oENO3qTbw6myAfPeC/WrLKlqUlT052pYrcjTvDhb6U6T4AUuQGbyOK
1318 nBGV6qzaAqbceDkwYzQAVOPOmXVKh3DI78ykWtj8mZ96qmeoqDlgFB5fS4ktOvMz
1319 8JttE+YJAODqi9O17qMPTyuImwIDAQABo4ICYjCCAl4wVQYDVR0RAQH/BEswSaRH
1320 MEUxFjAUBgVngQUCAQwLaWQ6NDk0NjU4MDAxFzAVBgVngQUCAgwMU0xCOTY2MHh4
1321 MS4yMRIwEAYFZ4EFAgMMB2lkOjA0MjgwDAYDVR0TAQH/BAIwADCBvAYDVR0gAQH/
1322 BIGxMIGuMIGrBgtghkgBhvhFAQcvATCBmzA5BggrBgEFBQcCARYtaHR0cDovL3d3
1323 dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9pbmRleC5odG1sMF4GCCsGAQUFBwIC
1324 MFIeUABUAEMAUABBACAAVAByAHUAcwB0AGUAZAAgAFAAbABhAHQAZgBvAHIAbQAg
1325 AE0AbwBkAHUAbABlACAARQBuAGQAbwByAHMAZQBtAGUAbgB0MIGhBgNVHSMEgZkw
1326 gZaAFI/9R4gOI5o6OiDeE+3xAeiCqdIdoXukeTB3MQswCQYDVQQGEwJERTEPMA0G
1327 A1UECBMGU2F4b255MSEwHwYDVQQKExhJbmZpbmVvbiBUZWNobm9sb2dpZXMgQUcx
1328 DDAKBgNVBAsTA0FJTTEmMCQGA1UEAxMdSUZYIFRQTSBFSyBJbnRlcm1lZGlhdGUg
1329 Q0EgMjCCAQUwgZMGA1UdCQSBizCBiDA6BgNVBDQxMzALMAkGBSsOAwIaBQAwJDAi
1330 BgkqhkiG9w0BAQcwFaITMBEGCSqGSIb3DQEBCQQEVENQQTAWBgVngQUCEDENMAsM
1331 AzEuMgIBAgIBAzAyBgVngQUCEjEpMCcBAf+gAwoBAaEDCgEAogMKAQCjEDAOFgMz
1332 LjEKAQQKAQEBAf8BAf8wDQYJKoZIhvcNAQEFBQADggEBADsl05WM8IssMs77QFcP
1333 hF4l+pj9OKR76MFuTvZj2PBXgk/1UAUrSjOONTsIv+cDZM2geWHT9Ptcv1SElzia
1334 WrWcNGnRS29b/cJ9s90MvSGsgYpkoUAyzUM6K/+5ObX1RVXCtokrX2R548OL1LMC
1335 g9Lo7lfsrXedrpC9nWBSrWvz77sw9jngOwojn1OaR2sSlUC8mAbi3HAR0mXcqKlT
1336 Aaq6hytOF2vbZw5lt1Cwr9wsqXs/C+9VhirhNb2GsdOijU7t/l7kRaPx1lu60K2u
1337 SZmeYT6rsTMWZGHPRxRt4Hin1/VQlAoaR17Mg07nhKam5C+krXhp740rIlHIMO+z
1338 hJY=
1339 -----END CERTIFICATE-----`
1340
1341 func TestParseCertificateWithRSAESOAEPPublicKey(t *testing.T) {
1342 wantKey := &rsa.PublicKey{
1343 E: 65537,
1344 N: bigFromHexString("8e7983105063a3f1c2e77d7c8b4f411db9c76f11366ccbb11757001fa51805bbbf68b6dccd9ad28a82c6a831e1591f06181c2e328c261cf9a14ff1704dc3261cc16da751760141969330a75b3fc5ae185ac76d636a97a339838bd042aa7c5999f63f946c6987b0e8be8f5908d08563f62bc6ee9510e36752bd3b2e7b55281bc92a8dcc8ba8a30d6aaa7580b672d83802449d34bfea0434edea4dbc3a9b201f3de0bf5ab2ca96a5254f4e76a58adc8d3bc385be94e93e0052e4066f238a9c1195eaacda02a6dc78393063340054e3ce99754a8770c8efcca45ad8fc999f7aaa67a8a83960141e5f4b892d3af333f09b6d13e60900e0ea8bd3b5eea30f4f2b889b"),
1345 }
1346 der, _ := pem.Decode([]byte(oaepCertPEM))
1347 if der == nil {
1348 t.Fatalf("Failed to decode PEM cert")
1349 }
1350 cert, err := ParseCertificate(der.Bytes)
1351 if err != nil {
1352 t.Fatalf("Failed to parse certificate: %s", err)
1353 }
1354 if cert.PublicKeyAlgorithm != RSAESOAEP {
1355 t.Errorf("Parsed key algorithm was not RSAESOAEP")
1356 }
1357 parsedKey, ok := cert.PublicKey.(*rsa.PublicKey)
1358 if !ok {
1359 t.Fatalf("Parsed key was not an RSA key: %s", err)
1360 }
1361 if wantKey.E != parsedKey.E ||
1362 wantKey.N.Cmp(parsedKey.N) != 0 {
1363 t.Fatal("Parsed key differs from expected key")
1364 }
1365 }
1366
1367 const (
1368 pemCertificate = `-----BEGIN CERTIFICATE-----
1369 MIIDATCCAemgAwIBAgIRAKQkkrFx1T/dgB/Go/xBM5swDQYJKoZIhvcNAQELBQAw
1370 EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjA4MTcyMDM2MDdaFw0xNzA4MTcyMDM2
1371 MDdaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
1372 ggEKAoIBAQDAoJtjG7M6InsWwIo+l3qq9u+g2rKFXNu9/mZ24XQ8XhV6PUR+5HQ4
1373 jUFWC58ExYhottqK5zQtKGkw5NuhjowFUgWB/VlNGAUBHtJcWR/062wYrHBYRxJH
1374 qVXOpYKbIWwFKoXu3hcpg/CkdOlDWGKoZKBCwQwUBhWE7MDhpVdQ+ZljUJWL+FlK
1375 yQK5iRsJd5TGJ6VUzLzdT4fmN2DzeK6GLeyMpVpU3sWV90JJbxWQ4YrzkKzYhMmB
1376 EcpXTG2wm+ujiHU/k2p8zlf8Sm7VBM/scmnMFt0ynNXop4FWvJzEm1G0xD2t+e2I
1377 5Utr04dOZPCgkm++QJgYhtZvgW7ZZiGTAgMBAAGjUjBQMA4GA1UdDwEB/wQEAwIF
1378 oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBsGA1UdEQQUMBKC
1379 EHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBADpqKQxrthH5InC7
1380 X96UP0OJCu/lLEMkrjoEWYIQaFl7uLPxKH5AmQPH4lYwF7u7gksR7owVG9QU9fs6
1381 1fK7II9CVgCd/4tZ0zm98FmU4D0lHGtPARrrzoZaqVZcAvRnFTlPX5pFkPhVjjai
1382 /mkxX9LpD8oK1445DFHxK5UjLMmPIIWd8EOi+v5a+hgGwnJpoW7hntSl8kHMtTmy
1383 fnnktsblSUV4lRCit0ymC7Ojhe+gzCCwkgs5kDzVVag+tnl/0e2DloIjASwOhpbH
1384 KVcg7fBd484ht/sS+l0dsB4KDOSpd8JzVDMF8OZqlaydizoJO0yWr9GbCN1+OKq5
1385 EhLrEqU=
1386 -----END CERTIFICATE-----`
1387 pemPrecertificate = `-----BEGIN CERTIFICATE-----
1388 MIIC3zCCAkigAwIBAgIBBzANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk
1389 MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX
1390 YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw
1391 MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu
1392 c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G
1393 CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+75jnwmh3rjhfdTJaDB0ym+3xj6r015a/
1394 BH634c4VyVui+A7kWL19uG+KSyUhkaeb1wDDjpwDibRc1NyaEgqyHgy0HNDnKAWk
1395 EM2cW9tdSSdyba8XEPYBhzd+olsaHjnu0LiBGdwVTcaPfajjDK8VijPmyVCfSgWw
1396 FAn/Xdh+tQIDAQABo4HBMIG+MB0GA1UdDgQWBBQgMVQa8lwF/9hli2hDeU9ekDb3
1397 tDB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkGA1UE
1398 BhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEOMAwG
1399 A1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwCQYDVR0TBAIwADATBgor
1400 BgEEAdZ5AgQDAQH/BAIFADANBgkqhkiG9w0BAQUFAAOBgQACocOeAVr1Tf8CPDNg
1401 h1//NDdVLx8JAb3CVDFfM3K3I/sV+87MTfRxoM5NjFRlXYSHl/soHj36u0YtLGhL
1402 BW/qe2O0cP8WbjLURgY1s9K8bagkmyYw5x/DTwjyPdTuIo+PdPY9eGMR3QpYEUBf
1403 kGzKLC0+6/yBmWTr2M98CIY/vg==
1404 -----END CERTIFICATE-----`
1405 )
1406
1407 func TestIsPrecertificate(t *testing.T) {
1408 tests := []struct {
1409 desc string
1410 certPEM string
1411 want bool
1412 }{
1413 {
1414 desc: "certificate",
1415 certPEM: pemCertificate,
1416 want: false,
1417 },
1418 {
1419 desc: "precertificate",
1420 certPEM: pemPrecertificate,
1421 want: true,
1422 },
1423 {
1424 desc: "nil",
1425 certPEM: "",
1426 want: false,
1427 },
1428 }
1429
1430 for _, test := range tests {
1431 var cert *Certificate
1432 if test.certPEM != "" {
1433 var err error
1434 cert, err = certificateFromPEM(test.certPEM)
1435 if err != nil {
1436 t.Errorf("%s: error parsing certificate: %s", test.desc, err)
1437 continue
1438 }
1439 }
1440 if got := cert.IsPrecertificate(); got != test.want {
1441 t.Errorf("%s: c.IsPrecertificate() = %t, want %t", test.desc, got, test.want)
1442 }
1443 }
1444 }
1445
1446 const ed25519CRLCertificate = `
1447 Certificate:
1448 Data:
1449 Version: 3 (0x2)
1450 Serial Number:
1451 7a:07:a0:9d:14:04:16:fc:1f:d8:e5:fe:d1:1d:1f:8d
1452 Signature Algorithm: ED25519
1453 Issuer: CN = Ed25519 CRL Test CA
1454 Validity
1455 Not Before: Oct 30 01:20:20 2019 GMT
1456 Not After : Dec 31 23:59:59 9999 GMT
1457 Subject: CN = Ed25519 CRL Test CA
1458 Subject Public Key Info:
1459 Public Key Algorithm: ED25519
1460 ED25519 Public-Key:
1461 pub:
1462 95:73:3b:b0:06:2a:31:5a:b6:a7:a6:6e:ef:71:df:
1463 ac:6f:6b:39:03:85:5e:63:4b:f8:a6:0f:68:c6:6f:
1464 75:21
1465 X509v3 extensions:
1466 X509v3 Key Usage: critical
1467 Digital Signature, Certificate Sign, CRL Sign
1468 X509v3 Extended Key Usage:
1469 TLS Web Client Authentication, TLS Web Server Authentication, OCSP Signing
1470 X509v3 Basic Constraints: critical
1471 CA:TRUE
1472 X509v3 Subject Key Identifier:
1473 B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
1474 X509v3 Authority Key Identifier:
1475 keyid:B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
1476
1477 Signature Algorithm: ED25519
1478 fc:3e:14:ea:bb:70:c2:6f:38:34:70:bc:c8:a7:f4:7c:0d:1e:
1479 28:d7:2a:9f:22:8a:45:e8:02:76:84:1e:2d:64:2d:1e:09:b5:
1480 29:71:1f:95:8a:4e:79:87:51:60:9a:e7:86:40:f6:60:c7:d1:
1481 ee:68:76:17:1d:90:cc:92:93:07
1482 -----BEGIN CERTIFICATE-----
1483 MIIBijCCATygAwIBAgIQegegnRQEFvwf2OX+0R0fjTAFBgMrZXAwHjEcMBoGA1UE
1484 AxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAgFw0xOTEwMzAwMTIwMjBaGA85OTk5MTIz
1485 MTIzNTk1OVowHjEcMBoGA1UEAxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAqMAUGAytl
1486 cAMhAJVzO7AGKjFatqembu9x36xvazkDhV5jS/imD2jGb3Uho4GNMIGKMA4GA1Ud
1487 DwEB/wQEAwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUF
1488 BwMJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLcX2hbqxe0fGElE09LjoDUK
1489 gZNgMB8GA1UdIwQYMBaAFLcX2hbqxe0fGElE09LjoDUKgZNgMAUGAytlcANBAPw+
1490 FOq7cMJvODRwvMin9HwNHijXKp8iikXoAnaEHi1kLR4JtSlxH5WKTnmHUWCa54ZA
1491 9mDH0e5odhcdkMySkwc=
1492 -----END CERTIFICATE-----`
1493
1494 const ed25519CRLKey = `-----BEGIN PRIVATE KEY-----
1495 MC4CAQAwBQYDK2VwBCIEINdKh2096vUBYu4EIFpjShsUSh3vimKya1sQ1YTT4RZG
1496 -----END PRIVATE KEY-----`
1497
1498 func TestCRLCreation(t *testing.T) {
1499 block, _ := pem.Decode([]byte(pemPrivateKey))
1500 privRSA, _ := ParsePKCS1PrivateKey(block.Bytes)
1501 block, _ = pem.Decode([]byte(pemCertificate))
1502 certRSA, _ := ParseCertificate(block.Bytes)
1503
1504 block, _ = pem.Decode([]byte(ed25519CRLKey))
1505 privEd25519, _ := ParsePKCS8PrivateKey(block.Bytes)
1506 block, _ = pem.Decode([]byte(ed25519CRLCertificate))
1507 certEd25519, _ := ParseCertificate(block.Bytes)
1508
1509 tests := []struct {
1510 name string
1511 priv interface{}
1512 cert *Certificate
1513 }{
1514 {"RSA CA", privRSA, certRSA},
1515 {"Ed25519 CA", privEd25519, certEd25519},
1516 }
1517
1518 loc := time.FixedZone("Oz/Atlantis", int((2 * time.Hour).Seconds()))
1519
1520 now := time.Unix(1000, 0).In(loc)
1521 nowUTC := now.UTC()
1522 expiry := time.Unix(10000, 0)
1523
1524 revokedCerts := []pkix.RevokedCertificate{
1525 {
1526 SerialNumber: big.NewInt(1),
1527 RevocationTime: nowUTC,
1528 },
1529 {
1530 SerialNumber: big.NewInt(42),
1531
1532 RevocationTime: now,
1533 },
1534 }
1535 expectedCerts := []pkix.RevokedCertificate{
1536 {
1537 SerialNumber: big.NewInt(1),
1538 RevocationTime: nowUTC,
1539 },
1540 {
1541 SerialNumber: big.NewInt(42),
1542 RevocationTime: nowUTC,
1543 },
1544 }
1545
1546 for _, test := range tests {
1547 crlBytes, err := test.cert.CreateCRL(rand.Reader, test.priv, revokedCerts, now, expiry)
1548 if err != nil {
1549 t.Errorf("%s: error creating CRL: %s", test.name, err)
1550 }
1551
1552 parsedCRL, err := ParseDERCRL(crlBytes)
1553 if err != nil {
1554 t.Errorf("%s: error reparsing CRL: %s", test.name, err)
1555 }
1556 if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) {
1557 t.Errorf("%s: RevokedCertificates mismatch: got %v; want %v.", test.name,
1558 parsedCRL.TBSCertList.RevokedCertificates, expectedCerts)
1559 }
1560 }
1561 }
1562
1563 func fromBase64(in string) []byte {
1564 out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
1565 n, err := base64.StdEncoding.Decode(out, []byte(in))
1566 if err != nil {
1567 panic("failed to base64 decode")
1568 }
1569 return out[:n]
1570 }
1571
1572 func TestParseDERCRL(t *testing.T) {
1573 derBytes := fromBase64(derCRLBase64)
1574 certList, err := ParseDERCRL(derBytes)
1575 if err != nil {
1576 t.Errorf("error parsing: %s", err)
1577 return
1578 }
1579 numCerts := len(certList.TBSCertList.RevokedCertificates)
1580 expected := 88
1581 if numCerts != expected {
1582 t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
1583 }
1584
1585 if certList.HasExpired(time.Unix(1302517272, 0)) {
1586 t.Errorf("CRL has expired (but shouldn't have)")
1587 }
1588
1589
1590 }
1591
1592 func TestCRLWithoutExpiry(t *testing.T) {
1593 derBytes := fromBase64("MIHYMIGZMAkGByqGSM44BAMwEjEQMA4GA1UEAxMHQ2FybERTUxcNOTkwODI3MDcwMDAwWjBpMBMCAgDIFw05OTA4MjIwNzAwMDBaMBMCAgDJFw05OTA4MjIwNzAwMDBaMBMCAgDTFw05OTA4MjIwNzAwMDBaMBMCAgDSFw05OTA4MjIwNzAwMDBaMBMCAgDUFw05OTA4MjQwNzAwMDBaMAkGByqGSM44BAMDLwAwLAIUfmVSdjP+NHMX0feW+aDU2G1cfT0CFAJ6W7fVWxjBz4fvftok8yqDnDWh")
1594 certList, err := ParseDERCRL(derBytes)
1595 if err != nil {
1596 t.Fatal(err)
1597 }
1598 if !certList.TBSCertList.NextUpdate.IsZero() {
1599 t.Errorf("NextUpdate is not the zero value")
1600 }
1601 }
1602
1603 func TestParsePEMCRL(t *testing.T) {
1604 pemBytes := fromBase64(pemCRLBase64)
1605 certList, err := ParseCRL(pemBytes)
1606 if err != nil {
1607 t.Errorf("error parsing: %s", err)
1608 return
1609 }
1610 numCerts := len(certList.TBSCertList.RevokedCertificates)
1611 expected := 2
1612 if numCerts != expected {
1613 t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
1614 }
1615
1616 if certList.HasExpired(time.Unix(1302517272, 0)) {
1617 t.Errorf("CRL has expired (but shouldn't have)")
1618 }
1619
1620
1621 }
1622
1623 func TestNonFatalErrors(t *testing.T) {
1624 nfe := NonFatalErrors{}
1625
1626 nfe.AddError(errors.New("one"))
1627 nfe.AddError(errors.New("two"))
1628 nfe.AddError(errors.New("three"))
1629
1630 if !nfe.HasError() {
1631 t.Fatal("NonFatalError claimed not to have an error")
1632 }
1633
1634 if !strings.Contains(nfe.Error(), "one; two; three") {
1635 t.Fatalf("Didn't see expected string from Error(), got '%s'", nfe.Error())
1636 }
1637 }
1638
1639 func TestIsFatal(t *testing.T) {
1640 tests := []struct {
1641 err error
1642 want bool
1643 }{
1644 {err: errors.New("normal error"), want: true},
1645 {err: NonFatalErrors{}, want: false},
1646 {err: nil, want: false},
1647 {err: &Errors{}, want: false},
1648 {err: &Errors{Errs: []Error{{ID: 1, Summary: "test", Fatal: true}}}, want: true},
1649 {err: &Errors{Errs: []Error{{ID: 1, Summary: "test", Fatal: false}}}, want: false},
1650 }
1651 for _, test := range tests {
1652 got := IsFatal(test.err)
1653 if got != test.want {
1654 t.Errorf("IsFatal(%T %v)=%v, want %v", test.err, test.err, got, test.want)
1655 }
1656 }
1657 }
1658
1659 const (
1660 tbsNoPoison = "30820245a003020102020842822a5b866fbfeb300d06092a864886f70d01010b" +
1661 "05003071310b3009060355040613024742310f300d060355040813064c6f6e64" +
1662 "6f6e310f300d060355040713064c6f6e646f6e310f300d060355040a1306476f" +
1663 "6f676c65310c300a060355040b1303456e673121301f0603550403131846616b" +
1664 "654365727469666963617465417574686f72697479301e170d31363037313731" +
1665 "31313534305a170d3139303331393131313534305a3066310b30090603550406" +
1666 "130255533113301106035504080c0a43616c69666f726e696131163014060355" +
1667 "04070c0d4d6f756e7461696e205669657731133011060355040a0c0a476f6f67" +
1668 "6c6520496e633115301306035504030c0c2a2e676f6f676c652e636f6d305930" +
1669 "1306072a8648ce3d020106082a8648ce3d03010703420004c4093984f5158d12" +
1670 "54b2029cf901e26d3547d40dd011616609351dcb121495b23fff35bd228e4dfc" +
1671 "38502d22d6981ecaa023afa4967e32d1825f3157fb28ff37a381ce3081cb301d" +
1672 "0603551d250416301406082b0601050507030106082b06010505070302306806" +
1673 "082b06010505070101045c305a302b06082b06010505073002861f687474703a" +
1674 "2f2f706b692e676f6f676c652e636f6d2f47494147322e637274302b06082b06" +
1675 "010505073001861f687474703a2f2f636c69656e7473312e676f6f676c652e63" +
1676 "6f6d2f6f637370301d0603551d0e04160414dbf46e63eee2dcbebf38604f9831" +
1677 "d06444f163d830210603551d20041a3018300c060a2b06010401d67902050130" +
1678 "08060667810c010202"
1679 tbsPoisonFirst = "3082025aa003020102020842822a5b866fbfeb300d06092a864886f70d01010b" +
1680 "05003071310b3009060355040613024742310f300d060355040813064c6f6e64" +
1681 "6f6e310f300d060355040713064c6f6e646f6e310f300d060355040a1306476f" +
1682 "6f676c65310c300a060355040b1303456e673121301f0603550403131846616b" +
1683 "654365727469666963617465417574686f72697479301e170d31363037313731" +
1684 "31313534305a170d3139303331393131313534305a3066310b30090603550406" +
1685 "130255533113301106035504080c0a43616c69666f726e696131163014060355" +
1686 "04070c0d4d6f756e7461696e205669657731133011060355040a0c0a476f6f67" +
1687 "6c6520496e633115301306035504030c0c2a2e676f6f676c652e636f6d305930" +
1688 "1306072a8648ce3d020106082a8648ce3d03010703420004c4093984f5158d12" +
1689 "54b2029cf901e26d3547d40dd011616609351dcb121495b23fff35bd228e4dfc" +
1690 "38502d22d6981ecaa023afa4967e32d1825f3157fb28ff37a381e33081e03013" +
1691 "060a2b06010401d6790204030101ff04020500301d0603551d25041630140608" +
1692 "2b0601050507030106082b06010505070302306806082b06010505070101045c" +
1693 "305a302b06082b06010505073002861f687474703a2f2f706b692e676f6f676c" +
1694 "652e636f6d2f47494147322e637274302b06082b06010505073001861f687474" +
1695 "703a2f2f636c69656e7473312e676f6f676c652e636f6d2f6f637370301d0603" +
1696 "551d0e04160414dbf46e63eee2dcbebf38604f9831d06444f163d83021060355" +
1697 "1d20041a3018300c060a2b06010401d6790205013008060667810c010202"
1698 tbsPoisonLast = "3082025aa003020102020842822a5b866fbfeb300d06092a864886f70d01010b" +
1699 "05003071310b3009060355040613024742310f300d060355040813064c6f6e64" +
1700 "6f6e310f300d060355040713064c6f6e646f6e310f300d060355040a1306476f" +
1701 "6f676c65310c300a060355040b1303456e673121301f0603550403131846616b" +
1702 "654365727469666963617465417574686f72697479301e170d31363037313731" +
1703 "31313534305a170d3139303331393131313534305a3066310b30090603550406" +
1704 "130255533113301106035504080c0a43616c69666f726e696131163014060355" +
1705 "04070c0d4d6f756e7461696e205669657731133011060355040a0c0a476f6f67" +
1706 "6c6520496e633115301306035504030c0c2a2e676f6f676c652e636f6d305930" +
1707 "1306072a8648ce3d020106082a8648ce3d03010703420004c4093984f5158d12" +
1708 "54b2029cf901e26d3547d40dd011616609351dcb121495b23fff35bd228e4dfc" +
1709 "38502d22d6981ecaa023afa4967e32d1825f3157fb28ff37a381e33081e0301d" +
1710 "0603551d250416301406082b0601050507030106082b06010505070302306806" +
1711 "082b06010505070101045c305a302b06082b06010505073002861f687474703a" +
1712 "2f2f706b692e676f6f676c652e636f6d2f47494147322e637274302b06082b06" +
1713 "010505073001861f687474703a2f2f636c69656e7473312e676f6f676c652e63" +
1714 "6f6d2f6f637370301d0603551d0e04160414dbf46e63eee2dcbebf38604f9831" +
1715 "d06444f163d830210603551d20041a3018300c060a2b06010401d67902050130" +
1716 "08060667810c0102023013060a2b06010401d6790204030101ff04020500"
1717 tbsPoisonMiddle = "3082025aa003020102020842822a5b866fbfeb300d06092a864886f70d01010b" +
1718 "05003071310b3009060355040613024742310f300d060355040813064c6f6e64" +
1719 "6f6e310f300d060355040713064c6f6e646f6e310f300d060355040a1306476f" +
1720 "6f676c65310c300a060355040b1303456e673121301f0603550403131846616b" +
1721 "654365727469666963617465417574686f72697479301e170d31363037313731" +
1722 "31313534305a170d3139303331393131313534305a3066310b30090603550406" +
1723 "130255533113301106035504080c0a43616c69666f726e696131163014060355" +
1724 "04070c0d4d6f756e7461696e205669657731133011060355040a0c0a476f6f67" +
1725 "6c6520496e633115301306035504030c0c2a2e676f6f676c652e636f6d305930" +
1726 "1306072a8648ce3d020106082a8648ce3d03010703420004c4093984f5158d12" +
1727 "54b2029cf901e26d3547d40dd011616609351dcb121495b23fff35bd228e4dfc" +
1728 "38502d22d6981ecaa023afa4967e32d1825f3157fb28ff37a381e33081e0301d" +
1729 "0603551d250416301406082b0601050507030106082b06010505070302306806" +
1730 "082b06010505070101045c305a302b06082b06010505073002861f687474703a" +
1731 "2f2f706b692e676f6f676c652e636f6d2f47494147322e637274302b06082b06" +
1732 "010505073001861f687474703a2f2f636c69656e7473312e676f6f676c652e63" +
1733 "6f6d2f6f6373703013060a2b06010401d6790204030101ff04020500301d0603" +
1734 "551d0e04160414dbf46e63eee2dcbebf38604f9831d06444f163d83021060355" +
1735 "1d20041a3018300c060a2b06010401d6790205013008060667810c010202"
1736 tbsPoisonTwice = "3082026fa003020102020842822a5b866fbfeb300d06092a864886f70d01010b" +
1737 "05003071310b3009060355040613024742310f300d060355040813064c6f6e64" +
1738 "6f6e310f300d060355040713064c6f6e646f6e310f300d060355040a1306476f" +
1739 "6f676c65310c300a060355040b1303456e673121301f0603550403131846616b" +
1740 "654365727469666963617465417574686f72697479301e170d31363037313731" +
1741 "31313534305a170d3139303331393131313534305a3066310b30090603550406" +
1742 "130255533113301106035504080c0a43616c69666f726e696131163014060355" +
1743 "04070c0d4d6f756e7461696e205669657731133011060355040a0c0a476f6f67" +
1744 "6c6520496e633115301306035504030c0c2a2e676f6f676c652e636f6d305930" +
1745 "1306072a8648ce3d020106082a8648ce3d03010703420004c4093984f5158d12" +
1746 "54b2029cf901e26d3547d40dd011616609351dcb121495b23fff35bd228e4dfc" +
1747 "38502d22d6981ecaa023afa4967e32d1825f3157fb28ff37a381f83081f5301d" +
1748 "0603551d250416301406082b0601050507030106082b06010505070302306806" +
1749 "082b06010505070101045c305a302b06082b06010505073002861f687474703a" +
1750 "2f2f706b692e676f6f676c652e636f6d2f47494147322e637274302b06082b06" +
1751 "010505073001861f687474703a2f2f636c69656e7473312e676f6f676c652e63" +
1752 "6f6d2f6f6373703013060a2b06010401d6790204030101ff04020500301d0603" +
1753 "551d0e04160414dbf46e63eee2dcbebf38604f9831d06444f163d83013060a2b" +
1754 "06010401d6790204030101ff0402050030210603551d20041a3018300c060a2b" +
1755 "06010401d6790205013008060667810c010202"
1756 )
1757
1758 func TestRemoveCTPoison(t *testing.T) {
1759 var tests = []struct {
1760 name string
1761 tbs string
1762 want string
1763 errstr string
1764 }{
1765 {name: "invalid-der", tbs: "01020304", errstr: "failed to parse"},
1766 {name: "trailing-data", tbs: tbsPoisonMiddle + "01020304", errstr: "trailing data"},
1767 {name: "no-poison-ext", tbs: tbsNoPoison, errstr: "no extension of specified type present"},
1768 {name: "two-poison-exts", tbs: tbsPoisonTwice, errstr: "multiple extensions of specified type present"},
1769 {name: "poison-first", tbs: tbsPoisonFirst, want: tbsNoPoison},
1770 {name: "poison-last", tbs: tbsPoisonLast, want: tbsNoPoison},
1771 {name: "poison-middle", tbs: tbsPoisonMiddle, want: tbsNoPoison},
1772 }
1773 for _, test := range tests {
1774 in, _ := hex.DecodeString(test.tbs)
1775 got, err := RemoveCTPoison(in)
1776 if test.errstr != "" {
1777 if err == nil {
1778 t.Errorf("RemoveCTPoison(%s)=%s,nil; want error %q", test.name, hex.EncodeToString(got), test.errstr)
1779 } else if !strings.Contains(err.Error(), test.errstr) {
1780 t.Errorf("RemoveCTPoison(%s)=nil,%q; want error %q", test.name, err, test.errstr)
1781 }
1782 continue
1783 }
1784 want, _ := hex.DecodeString(test.want)
1785 if err != nil {
1786 t.Errorf("RemoveCTPoison(%s)=nil,%q; want %s,nil", test.name, err, test.want)
1787 } else if !bytes.Equal(got, want) {
1788 t.Errorf("RemoveCTPoison(%s)=%s,nil; want %s,nil", test.name, hex.EncodeToString(got), test.want)
1789 }
1790 }
1791 }
1792
1793 func makeCert(t *testing.T, template, issuer *Certificate) *Certificate {
1794 t.Helper()
1795 certData, err := CreateCertificate(rand.Reader, template, issuer, &testPrivateKey.PublicKey, testPrivateKey)
1796 if err != nil {
1797 t.Fatalf("failed to create pre-cert: %v", err)
1798 }
1799 cert, err := ParseCertificate(certData)
1800 if err != nil {
1801 t.Fatalf("failed to re-parse pre-cert: %v", err)
1802 }
1803 return cert
1804 }
1805
1806 func TestBuildPrecertTBS(t *testing.T) {
1807 poisonExt := pkix.Extension{Id: OIDExtensionCTPoison, Critical: true, Value: asn1.NullBytes}
1808 preIssuerKeyID := []byte{0x19, 0x09, 0x19, 0x70}
1809 issuerKeyID := []byte{0x07, 0x07, 0x20, 0x07}
1810 preCertTemplate := Certificate{
1811 Version: 3,
1812 SerialNumber: big.NewInt(123),
1813 Issuer: pkix.Name{CommonName: "precert Issuer"},
1814 Subject: pkix.Name{CommonName: "precert subject"},
1815 NotBefore: time.Now(),
1816 NotAfter: time.Now().Add(3 * time.Hour),
1817 ExtraExtensions: []pkix.Extension{poisonExt},
1818 AuthorityKeyId: preIssuerKeyID,
1819 }
1820 preIssuerTemplate := Certificate{
1821 Version: 3,
1822 SerialNumber: big.NewInt(1234),
1823 Issuer: pkix.Name{CommonName: "real Issuer"},
1824 Subject: pkix.Name{CommonName: "precert Issuer"},
1825 NotBefore: time.Now(),
1826 NotAfter: time.Now().Add(3 * time.Hour),
1827 AuthorityKeyId: issuerKeyID,
1828 SubjectKeyId: preIssuerKeyID,
1829 ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageCertificateTransparency},
1830 }
1831 actualIssuerTemplate := Certificate{
1832 Version: 3,
1833 SerialNumber: big.NewInt(12345),
1834 Issuer: pkix.Name{CommonName: "real Issuer"},
1835 Subject: pkix.Name{CommonName: "real Issuer"},
1836 NotBefore: time.Now(),
1837 NotAfter: time.Now().Add(3 * time.Hour),
1838 SubjectKeyId: issuerKeyID,
1839 }
1840 preCertWithAKI := makeCert(t, &preCertTemplate, &preIssuerTemplate)
1841 preIssuerWithAKI := makeCert(t, &preIssuerTemplate, &actualIssuerTemplate)
1842
1843 preIssuerTemplate.AuthorityKeyId = nil
1844 actualIssuerTemplate.SubjectKeyId = nil
1845 preIssuerWithoutAKI := makeCert(t, &preIssuerTemplate, &actualIssuerTemplate)
1846
1847 preCertTemplate.AuthorityKeyId = nil
1848 preIssuerTemplate.SubjectKeyId = nil
1849 preCertWithoutAKI := makeCert(t, &preCertTemplate, &preIssuerTemplate)
1850
1851 preIssuerTemplate.ExtKeyUsage = nil
1852 invalidPreIssuer := makeCert(t, &preIssuerTemplate, &actualIssuerTemplate)
1853
1854 akiPrefix := []byte{0x30, 0x06, 0x80, 0x04}
1855 var tests = []struct {
1856 name string
1857 tbs *Certificate
1858 preIssuer *Certificate
1859 wantAKI []byte
1860 wantErr bool
1861 }{
1862 {
1863 name: "no-preIssuer-provided",
1864 tbs: preCertWithAKI,
1865 wantAKI: append(akiPrefix, preIssuerKeyID...),
1866 },
1867 {
1868 name: "both-with-AKI",
1869 tbs: preCertWithAKI,
1870 preIssuer: preIssuerWithAKI,
1871 wantAKI: append(akiPrefix, issuerKeyID...),
1872 },
1873 {
1874 name: "invalid-preIssuer",
1875 tbs: preCertWithAKI,
1876 preIssuer: invalidPreIssuer,
1877 wantErr: true,
1878 },
1879 {
1880 name: "both-without-AKI",
1881 tbs: preCertWithoutAKI,
1882 preIssuer: preIssuerWithoutAKI,
1883 },
1884 {
1885 name: "precert-with-preIssuer-without-AKI",
1886 tbs: preCertWithAKI,
1887 preIssuer: preIssuerWithoutAKI,
1888 },
1889 {
1890 name: "precert-without-preIssuer-with-AKI",
1891 tbs: preCertWithoutAKI,
1892 preIssuer: preIssuerWithAKI,
1893 wantAKI: append(akiPrefix, issuerKeyID...),
1894 },
1895 }
1896 for _, test := range tests {
1897 got, err := BuildPrecertTBS(test.tbs.RawTBSCertificate, test.preIssuer)
1898 if err != nil {
1899 if !test.wantErr {
1900 t.Errorf("BuildPrecertTBS(%s)=nil,%q; want _,nil", test.name, err)
1901 }
1902 continue
1903 }
1904 if test.wantErr {
1905 t.Errorf("BuildPrecertTBS(%s)=_,nil; want _,non-nil", test.name)
1906 }
1907
1908 var tbs tbsCertificate
1909 if rest, err := asn1.Unmarshal(got, &tbs); err != nil {
1910 t.Errorf("BuildPrecertTBS(%s) gave unparsable TBS: %v", test.name, err)
1911 continue
1912 } else if len(rest) > 0 {
1913 t.Errorf("BuildPrecertTBS(%s) gave extra data in DER", test.name)
1914 }
1915 if test.preIssuer != nil {
1916 if got, want := tbs.Issuer.FullBytes, test.preIssuer.RawIssuer; !bytes.Equal(got, want) {
1917 t.Errorf("BuildPrecertTBS(%s).Issuer=%x, want %x", test.name, got, want)
1918 }
1919 }
1920 var gotAKI []byte
1921 for _, ext := range tbs.Extensions {
1922 if ext.Id.Equal(OIDExtensionAuthorityKeyId) {
1923 gotAKI = ext.Value
1924 break
1925 }
1926 }
1927 if gotAKI != nil {
1928 if test.wantAKI != nil {
1929 if !reflect.DeepEqual(gotAKI, test.wantAKI) {
1930 t.Errorf("BuildPrecertTBS(%s).Extensions[AKI]=%+v, want %+v", test.name, gotAKI, test.wantAKI)
1931 }
1932 } else {
1933 t.Errorf("BuildPrecertTBS(%s).Extensions[AKI]=%+v, want nil", test.name, gotAKI)
1934 }
1935 } else if test.wantAKI != nil {
1936 t.Errorf("BuildPrecertTBS(%s).Extensions[AKI]=nil, want %+v", test.name, test.wantAKI)
1937 }
1938 }
1939 }
1940
1941 func TestImports(t *testing.T) {
1942 t.Skip("Import test skipped for forked codebase")
1943 if testing.Short() {
1944 t.Skip("skipping in -short mode")
1945 }
1946
1947
1948
1949 if out, err := exec.Command("go", "run", "x509_test_import.go").CombinedOutput(); err != nil {
1950 t.Errorf("failed to run x509_test_import.go: %s\n%s", err, out)
1951 }
1952 }
1953
1954 const derCRLBase64 = "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"
1955
1956 const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RFFZSktvWklodmNOQVFFRkJRQXdiREVhTUJnR0ExVUVDaE1SVWxOQklGTmxZM1Z5DQphWFI1SUVsdVl5NHhIakFjQmdOVkJBTVRGVkpUUVNCUWRXSnNhV01nVW05dmRDQkRRU0IyTVRFdU1Dd0dDU3FHDQpTSWIzRFFFSkFSWWZjbk5oYTJWdmJuSnZiM1J6YVdkdVFISnpZWE5sWTNWeWFYUjVMbU52YlJjTk1URXdNakl6DQpNVGt5T0RNd1doY05NVEV3T0RJeU1Ua3lPRE13V2pDQmpEQktBaEVBckRxb2g5RkhKSFhUN09QZ3V1bjQrQmNODQpNRGt4TVRBeU1UUXlOekE1V2pBbU1Bb0dBMVVkRlFRRENnRUpNQmdHQTFVZEdBUVJHQTh5TURBNU1URXdNakUwDQpNalExTlZvd1BnSVJBTEd6blowOTVQQjVhQU9MUGc1N2ZNTVhEVEF5TVRBeU16RTBOVEF4TkZvd0dqQVlCZ05WDQpIUmdFRVJnUE1qQXdNakV3TWpNeE5EVXdNVFJhb0RBd0xqQWZCZ05WSFNNRUdEQVdnQlQxVERGNlVRTS9MTmVMDQpsNWx2cUhHUXEzZzltekFMQmdOVkhSUUVCQUlDQUlRd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ1lFQUZVNUFzNk16DQpxNVBSc2lmYW9iUVBHaDFhSkx5QytNczVBZ2MwYld5QTNHQWR4dXI1U3BQWmVSV0NCamlQL01FSEJXSkNsQkhQDQpHUmNxNXlJZDNFakRrYUV5eFJhK2k2N0x6dmhJNmMyOUVlNks5cFNZd2ppLzdSVWhtbW5Qclh0VHhsTDBsckxyDQptUVFKNnhoRFJhNUczUUE0Q21VZHNITnZicnpnbUNZcHZWRT0NCi0tLS0tRU5EIFg1MDkgQ1JMLS0tLS0NCg0K"
1957
1958 func TestCreateCertificateRequest(t *testing.T) {
1959 random := rand.Reader
1960
1961 ecdsa256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
1962 if err != nil {
1963 t.Fatalf("Failed to generate ECDSA key: %s", err)
1964 }
1965
1966 ecdsa384Priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
1967 if err != nil {
1968 t.Fatalf("Failed to generate ECDSA key: %s", err)
1969 }
1970
1971 ecdsa521Priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
1972 if err != nil {
1973 t.Fatalf("Failed to generate ECDSA key: %s", err)
1974 }
1975
1976 _, ed25519Priv, err := ed25519.GenerateKey(random)
1977 if err != nil {
1978 t.Fatalf("Failed to generate Ed25519 key: %s", err)
1979 }
1980
1981 tests := []struct {
1982 name string
1983 priv interface{}
1984 sigAlgo SignatureAlgorithm
1985 }{
1986 {"RSA", testPrivateKey, SHA1WithRSA},
1987 {"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1},
1988 {"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1},
1989 {"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1},
1990 {"Ed25519", ed25519Priv, PureEd25519},
1991 }
1992
1993 for _, test := range tests {
1994 template := CertificateRequest{
1995 Subject: pkix.Name{
1996 CommonName: "test.example.com",
1997 Organization: []string{"Σ Acme Co"},
1998 },
1999 SignatureAlgorithm: test.sigAlgo,
2000 DNSNames: []string{"test.example.com"},
2001 EmailAddresses: []string{"gopher@golang.org"},
2002 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
2003 }
2004
2005 derBytes, err := CreateCertificateRequest(random, &template, test.priv)
2006 if err != nil {
2007 t.Errorf("%s: failed to create certificate request: %s", test.name, err)
2008 continue
2009 }
2010
2011 out, err := ParseCertificateRequest(derBytes)
2012 if err != nil {
2013 t.Errorf("%s: failed to create certificate request: %s", test.name, err)
2014 continue
2015 }
2016
2017 err = out.CheckSignature()
2018 if err != nil {
2019 t.Errorf("%s: failed to check certificate request signature: %s", test.name, err)
2020 continue
2021 }
2022
2023 if out.Subject.CommonName != template.Subject.CommonName {
2024 t.Errorf("%s: output subject common name and template subject common name don't match", test.name)
2025 } else if len(out.Subject.Organization) != len(template.Subject.Organization) {
2026 t.Errorf("%s: output subject organisation and template subject organisation don't match", test.name)
2027 } else if len(out.DNSNames) != len(template.DNSNames) {
2028 t.Errorf("%s: output DNS names and template DNS names don't match", test.name)
2029 } else if len(out.EmailAddresses) != len(template.EmailAddresses) {
2030 t.Errorf("%s: output email addresses and template email addresses don't match", test.name)
2031 } else if len(out.IPAddresses) != len(template.IPAddresses) {
2032 t.Errorf("%s: output IP addresses and template IP addresses names don't match", test.name)
2033 }
2034 }
2035 }
2036
2037 func marshalAndParseCSR(t *testing.T, template *CertificateRequest) *CertificateRequest {
2038 derBytes, err := CreateCertificateRequest(rand.Reader, template, testPrivateKey)
2039 if err != nil {
2040 t.Fatal(err)
2041 }
2042
2043 csr, err := ParseCertificateRequest(derBytes)
2044 if err != nil {
2045 t.Fatal(err)
2046 }
2047
2048 return csr
2049 }
2050
2051 func TestCertificateRequestOverrides(t *testing.T) {
2052 sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil, nil)
2053 if err != nil {
2054 t.Fatal(err)
2055 }
2056
2057 template := CertificateRequest{
2058 Subject: pkix.Name{
2059 CommonName: "test.example.com",
2060 Organization: []string{"Σ Acme Co"},
2061 },
2062 DNSNames: []string{"test.example.com"},
2063
2064
2065
2066 ExtraExtensions: []pkix.Extension{
2067 {
2068 Id: OIDExtensionSubjectAltName,
2069 Value: sanContents,
2070 Critical: true,
2071 },
2072 },
2073 }
2074
2075 csr := marshalAndParseCSR(t, &template)
2076
2077 if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo.example.com" {
2078 t.Errorf("Extension did not override template. Got %v\n", csr.DNSNames)
2079 }
2080
2081 if len(csr.Extensions) != 1 || !csr.Extensions[0].Id.Equal(OIDExtensionSubjectAltName) || !csr.Extensions[0].Critical {
2082 t.Errorf("SAN extension was not faithfully copied, got %#v", csr.Extensions)
2083 }
2084
2085
2086
2087
2088
2089 template.Attributes = []pkix.AttributeTypeAndValueSET{
2090 {
2091 Type: oidExtensionRequest,
2092 Value: [][]pkix.AttributeTypeAndValue{
2093 {
2094 {
2095 Type: OIDExtensionAuthorityInfoAccess,
2096 Value: []byte("foo"),
2097 },
2098 },
2099 },
2100 },
2101 }
2102
2103 csr = marshalAndParseCSR(t, &template)
2104 if l := len(csr.Attributes); l != 1 {
2105 t.Errorf("incorrect number of attributes: %d\n", l)
2106 }
2107
2108 if !csr.Attributes[0].Type.Equal(oidExtensionRequest) ||
2109 len(csr.Attributes[0].Value) != 1 ||
2110 len(csr.Attributes[0].Value[0]) != 2 {
2111 t.Errorf("bad attributes: %#v\n", csr.Attributes)
2112 }
2113
2114 sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil, nil)
2115 if err != nil {
2116 t.Fatal(err)
2117 }
2118
2119
2120 template.Attributes[0].Value[0] = append(template.Attributes[0].Value[0], pkix.AttributeTypeAndValue{
2121 Type: OIDExtensionSubjectAltName,
2122 Value: sanContents2,
2123 })
2124
2125 csr = marshalAndParseCSR(t, &template)
2126
2127 if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo2.example.com" {
2128 t.Errorf("Attributes did not override ExtraExtensions. Got %v\n", csr.DNSNames)
2129 }
2130 }
2131
2132 func TestParseCertificateRequest(t *testing.T) {
2133 for _, csrBase64 := range csrBase64Array {
2134 csrBytes := fromBase64(csrBase64)
2135 csr, err := ParseCertificateRequest(csrBytes)
2136 if err != nil {
2137 t.Fatalf("failed to parse CSR: %s", err)
2138 }
2139
2140 if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher@golang.org" {
2141 t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses)
2142 }
2143
2144 if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" {
2145 t.Errorf("incorrect DNS names found: %v", csr.DNSNames)
2146 }
2147
2148 if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" {
2149 t.Errorf("incorrect Subject name: %v", csr.Subject)
2150 }
2151
2152 found := false
2153 for _, e := range csr.Extensions {
2154 if e.Id.Equal(OIDExtensionBasicConstraints) {
2155 found = true
2156 break
2157 }
2158 }
2159 if !found {
2160 t.Errorf("basic constraints extension not found in CSR")
2161 }
2162 }
2163 }
2164
2165 func TestCriticalFlagInCSRRequestedExtensions(t *testing.T) {
2166
2167
2168 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="
2169
2170 csrBytes := fromBase64(csrBase64)
2171 csr, err := ParseCertificateRequest(csrBytes)
2172 if err != nil {
2173 t.Fatalf("failed to parse CSR: %s", err)
2174 }
2175
2176 expected := []struct {
2177 Id asn1.ObjectIdentifier
2178 Value []byte
2179 }{
2180 {OIDExtensionBasicConstraints, fromBase64("MAYBAf8CAQA=")},
2181 {OIDExtensionKeyUsage, fromBase64("AwIChA==")},
2182 }
2183
2184 if n := len(csr.Extensions); n != len(expected) {
2185 t.Fatalf("expected to find %d extensions but found %d", len(expected), n)
2186 }
2187
2188 for i, extension := range csr.Extensions {
2189 if !extension.Id.Equal(expected[i].Id) {
2190 t.Fatalf("extension #%d has unexpected type %v (expected %v)", i, extension.Id, expected[i].Id)
2191 }
2192
2193 if !bytes.Equal(extension.Value, expected[i].Value) {
2194 t.Fatalf("extension #%d has unexpected contents %x (expected %x)", i, extension.Value, expected[i].Value)
2195 }
2196 }
2197 }
2198
2199
2200
2201 func serialiseAndParse(t *testing.T, template *Certificate) *Certificate {
2202 derBytes, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey)
2203 if err != nil {
2204 t.Fatalf("failed to create certificate: %s", err)
2205 return nil
2206 }
2207
2208 cert, err := ParseCertificate(derBytes)
2209 if err != nil {
2210 t.Fatalf("failed to parse certificate: %s", err)
2211 return nil
2212 }
2213
2214 return cert
2215 }
2216
2217 func TestMaxPathLen(t *testing.T) {
2218 template := &Certificate{
2219 SerialNumber: big.NewInt(1),
2220 Subject: pkix.Name{
2221 CommonName: "Σ Acme Co",
2222 },
2223 NotBefore: time.Unix(1000, 0),
2224 NotAfter: time.Unix(100000, 0),
2225
2226 BasicConstraintsValid: true,
2227 IsCA: true,
2228 }
2229
2230 cert1 := serialiseAndParse(t, template)
2231 if m := cert1.MaxPathLen; m != -1 {
2232 t.Errorf("Omitting MaxPathLen didn't turn into -1, got %d", m)
2233 }
2234 if cert1.MaxPathLenZero {
2235 t.Errorf("Omitting MaxPathLen resulted in MaxPathLenZero")
2236 }
2237
2238 template.MaxPathLen = 1
2239 cert2 := serialiseAndParse(t, template)
2240 if m := cert2.MaxPathLen; m != 1 {
2241 t.Errorf("Setting MaxPathLen didn't work. Got %d but set 1", m)
2242 }
2243 if cert2.MaxPathLenZero {
2244 t.Errorf("Setting MaxPathLen resulted in MaxPathLenZero")
2245 }
2246
2247 template.MaxPathLen = 0
2248 template.MaxPathLenZero = true
2249 cert3 := serialiseAndParse(t, template)
2250 if m := cert3.MaxPathLen; m != 0 {
2251 t.Errorf("Setting MaxPathLenZero didn't work, got %d", m)
2252 }
2253 if !cert3.MaxPathLenZero {
2254 t.Errorf("Setting MaxPathLen to zero didn't result in MaxPathLenZero")
2255 }
2256 }
2257
2258 func TestNoAuthorityKeyIdInSelfSignedCert(t *testing.T) {
2259 template := &Certificate{
2260 SerialNumber: big.NewInt(1),
2261 Subject: pkix.Name{
2262 CommonName: "Σ Acme Co",
2263 },
2264 NotBefore: time.Unix(1000, 0),
2265 NotAfter: time.Unix(100000, 0),
2266
2267 BasicConstraintsValid: true,
2268 IsCA: true,
2269 SubjectKeyId: []byte{1, 2, 3, 4},
2270 }
2271
2272 if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) != 0 {
2273 t.Fatalf("self-signed certificate contained default authority key id")
2274 }
2275
2276 template.AuthorityKeyId = []byte{1, 2, 3, 4}
2277 if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) == 0 {
2278 t.Fatalf("self-signed certificate erased explicit authority key id")
2279 }
2280 }
2281
2282 func TestASN1BitLength(t *testing.T) {
2283 tests := []struct {
2284 bytes []byte
2285 bitLen int
2286 }{
2287 {nil, 0},
2288 {[]byte{0x00}, 0},
2289 {[]byte{0x00, 0x00}, 0},
2290 {[]byte{0xf0}, 4},
2291 {[]byte{0x88}, 5},
2292 {[]byte{0xff}, 8},
2293 {[]byte{0xff, 0x80}, 9},
2294 {[]byte{0xff, 0x81}, 16},
2295 }
2296
2297 for i, test := range tests {
2298 if got := asn1BitLength(test.bytes); got != test.bitLen {
2299 t.Errorf("#%d: calculated bit-length of %d for %x, wanted %d", i, got, test.bytes, test.bitLen)
2300 }
2301 }
2302 }
2303
2304 func TestVerifyEmptyCertificate(t *testing.T) {
2305 if _, err := new(Certificate).Verify(VerifyOptions{}); err != errNotParsed {
2306 t.Errorf("Verifying empty certificate resulted in unexpected error: %q (wanted %q)", err, errNotParsed)
2307 }
2308 }
2309
2310 func TestInsecureAlgorithmErrorString(t *testing.T) {
2311 tests := []struct {
2312 sa SignatureAlgorithm
2313 want string
2314 }{
2315 {MD2WithRSA, "x509: cannot verify signature: insecure algorithm MD2-RSA"},
2316 {-1, "x509: cannot verify signature: insecure algorithm -1"},
2317 {0, "x509: cannot verify signature: insecure algorithm 0"},
2318 {9999, "x509: cannot verify signature: insecure algorithm 9999"},
2319 }
2320 for i, tt := range tests {
2321 if got := fmt.Sprint(InsecureAlgorithmError(tt.sa)); got != tt.want {
2322 t.Errorf("%d. mismatch.\n got: %s\nwant: %s\n", i, got, tt.want)
2323 }
2324 }
2325 }
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340 var csrBase64Array = [...]string{
2341
2342 "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=",
2343
2344 "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==",
2345 }
2346
2347 var md5cert = `
2348 -----BEGIN CERTIFICATE-----
2349 MIIB4TCCAUoCCQCfmw3vMgPS5TANBgkqhkiG9w0BAQQFADA1MQswCQYDVQQGEwJB
2350 VTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wHhcNMTUx
2351 MjAzMTkyOTMyWhcNMjkwODEyMTkyOTMyWjA1MQswCQYDVQQGEwJBVTETMBEGA1UE
2352 CBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wgZ8wDQYJKoZIhvcNAQEB
2353 BQADgY0AMIGJAoGBANrq2nhLQj5mlXbpVX3QUPhfEm/vdEqPkoWtR/jRZIWm4WGf
2354 Wpq/LKHJx2Pqwn+t117syN8l4U5unyAi1BJSXjBwPZNd7dXjcuJ+bRLV7FZ/iuvs
2355 cfYyQQFTxan4TaJMd0x1HoNDbNbjHa02IyjjYE/r3mb/PIg+J2t5AZEh80lPAgMB
2356 AAEwDQYJKoZIhvcNAQEEBQADgYEAjGzp3K3ey/YfKHohf33yHHWd695HQxDAP+wY
2357 cs9/TAyLR+gJzJP7d18EcDDLJWVi7bhfa4EAD86di05azOh9kWSn4b3o9QYRGCSw
2358 GNnI3Zk0cwNKA49hZntKKiy22DhRk7JAHF01d6Bu3KkHkmENrtJ+zj/+159WAnUa
2359 qViorq4=
2360 -----END CERTIFICATE-----
2361 `
2362
2363 func TestMD5(t *testing.T) {
2364 pemBlock, _ := pem.Decode([]byte(md5cert))
2365 cert, err := ParseCertificate(pemBlock.Bytes)
2366 if err != nil {
2367 t.Fatalf("failed to parse certificate: %s", err)
2368 }
2369 if sa := cert.SignatureAlgorithm; sa != MD5WithRSA {
2370 t.Errorf("signature algorithm is %v, want %v", sa, MD5WithRSA)
2371 }
2372 if err = cert.CheckSignatureFrom(cert); err == nil {
2373 t.Fatalf("certificate verification succeeded incorrectly")
2374 }
2375 if _, ok := err.(InsecureAlgorithmError); !ok {
2376 t.Fatalf("certificate verification returned %v (%T), wanted InsecureAlgorithmError", err, err)
2377 }
2378 }
2379
2380
2381
2382 const certMissingRSANULL = `
2383 -----BEGIN CERTIFICATE-----
2384 MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD
2385 bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4
2386 MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc
2387 MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG
2388 hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE
2389 ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e
2390 E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw
2391 DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A
2392 p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4
2393 hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE
2394 GFGNEH5PlGffo05wc46QkYU=
2395 -----END CERTIFICATE-----`
2396
2397 func TestRSAMissingNULLParameters(t *testing.T) {
2398 block, _ := pem.Decode([]byte(certMissingRSANULL))
2399 if _, err := ParseCertificate(block.Bytes); err == nil {
2400 t.Error("unexpected success when parsing certificate with missing RSA NULL parameter")
2401 } else if !strings.Contains(err.Error(), "missing NULL") {
2402 t.Errorf("unrecognised error when parsing certificate with missing RSA NULL parameter: %s", err)
2403 }
2404 }
2405
2406 const certISOOID = `
2407 -----BEGIN CERTIFICATE-----
2408 MIIB5TCCAVKgAwIBAgIQtwyL3RPWV7dJQp34HwZG9DAJBgUrDgMCHQUAMBExDzAN
2409 BgNVBAMTBm15dGVzdDAeFw0xNjA4MDkyMjExMDVaFw0zOTEyMzEyMzU5NTlaMBEx
2410 DzANBgNVBAMTBm15dGVzdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArzIH
2411 GsyDB3ohIGkkvijF2PTRUX1bvOtY1eUUpjwHyu0twpAKSuaQv2Ha+/63+aHe8O86
2412 BT+98wjXFX6RFSagtAujo80rIF2dSm33BGt18pDN8v6zp93dnAm0jRaSQrHJ75xw
2413 5O+S1oEYR1LtUoFJy6qB104j6aINBAgOiLIKiMkCAwEAAaNGMEQwQgYDVR0BBDsw
2414 OYAQVuYVQ/WDjdGSkZRlTtJDNKETMBExDzANBgNVBAMTBm15dGVzdIIQtwyL3RPW
2415 V7dJQp34HwZG9DAJBgUrDgMCHQUAA4GBABngrSkH7vG5lY4sa4AZF59lAAXqBVJE
2416 J4TBiKC62hCdZv18rBleP6ETfhbPg7pTs8p4ebQbpmtNxRS9Lw3MzQ8Ya5Ybwzj2
2417 NwBSyCtCQl7mrEg4nJqJl4A2EUhnET/oVxU0oTV/SZ3ziGXcY1oG1s6vidV7TZTu
2418 MCRtdSdaM7g3
2419 -----END CERTIFICATE-----`
2420
2421 func TestISOOIDInCertificate(t *testing.T) {
2422 block, _ := pem.Decode([]byte(certISOOID))
2423 if cert, err := ParseCertificate(block.Bytes); err != nil {
2424 t.Errorf("certificate with ISO OID failed to parse: %s", err)
2425 } else if cert.SignatureAlgorithm == UnknownSignatureAlgorithm {
2426 t.Errorf("ISO OID not recognised in certificate")
2427 }
2428 }
2429
2430
2431
2432
2433 const certMultipleRDN = `
2434 -----BEGIN CERTIFICATE-----
2435 MIIFRzCCBC+gAwIBAgIEOl59NTANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJz
2436 aTEbMBkGA1UEChMSc3RhdGUtaW5zdGl0dXRpb25zMREwDwYDVQQLEwhzaWdvdi1j
2437 YTAeFw0xMjExMTYxMDUyNTdaFw0xNzExMTYxMjQ5MDVaMIGLMQswCQYDVQQGEwJz
2438 aTEbMBkGA1UEChMSc3RhdGUtaW5zdGl0dXRpb25zMRkwFwYDVQQLExB3ZWItY2Vy
2439 dGlmaWNhdGVzMRAwDgYDVQQLEwdTZXJ2ZXJzMTIwFAYDVQQFEw0xMjM2NDg0MDEw
2440 MDEwMBoGA1UEAxMTZXBvcnRhbC5tc3MuZWR1cy5zaTCCASIwDQYJKoZIhvcNAQEB
2441 BQADggEPADCCAQoCggEBAMrNkZH9MPuBTjMGNk3sJX8V+CkFx/4ru7RTlLS6dlYM
2442 098dtSfJ3s2w0p/1NB9UmR8j0yS0Kg6yoZ3ShsSO4DWBtcQD8820a6BYwqxxQTNf
2443 HSRZOc+N/4TQrvmK6t4k9Aw+YEYTMrWOU4UTeyhDeCcUsBdh7HjfWsVaqNky+2sv
2444 oic3zP5gF+2QfPkvOoHT3FLR8olNhViIE6Kk3eFIEs4dkq/ZzlYdLb8pHQoj/sGI
2445 zFmA5AFvm1HURqOmJriFjBwaCtn8AVEYOtQrnUCzJYu1ex8azyS2ZgYMX0u8A5Z/
2446 y2aMS/B2W+H79WcgLpK28vPwe7vam0oFrVytAd+u65ECAwEAAaOCAf4wggH6MA4G
2447 A1UdDwEB/wQEAwIFoDBABgNVHSAEOTA3MDUGCisGAQQBr1kBAwMwJzAlBggrBgEF
2448 BQcCARYZaHR0cDovL3d3dy5jYS5nb3Yuc2kvY3BzLzAfBgNVHREEGDAWgRRwb2Rw
2449 b3JhLm1pemtzQGdvdi5zaTCB8QYDVR0fBIHpMIHmMFWgU6BRpE8wTTELMAkGA1UE
2450 BhMCc2kxGzAZBgNVBAoTEnN0YXRlLWluc3RpdHV0aW9uczERMA8GA1UECxMIc2ln
2451 b3YtY2ExDjAMBgNVBAMTBUNSTDM5MIGMoIGJoIGGhldsZGFwOi8veDUwMC5nb3Yu
2452 c2kvb3U9c2lnb3YtY2Esbz1zdGF0ZS1pbnN0aXR1dGlvbnMsYz1zaT9jZXJ0aWZp
2453 Y2F0ZVJldm9jYXRpb25MaXN0P2Jhc2WGK2h0dHA6Ly93d3cuc2lnb3YtY2EuZ292
2454 LnNpL2NybC9zaWdvdi1jYS5jcmwwKwYDVR0QBCQwIoAPMjAxMjExMTYxMDUyNTda
2455 gQ8yMDE3MTExNjEyNDkwNVowHwYDVR0jBBgwFoAUHvjUU2uzgwbpBAZXAvmlv8ZY
2456 PHIwHQYDVR0OBBYEFGI1Duuu+wTGDZka/xHNbwcbM69ZMAkGA1UdEwQCMAAwGQYJ
2457 KoZIhvZ9B0EABAwwChsEVjcuMQMCA6gwDQYJKoZIhvcNAQEFBQADggEBAHny0K1y
2458 BQznrzDu3DDpBcGYguKU0dvU9rqsV1ua4nxkriSMWjgsX6XJFDdDW60I3P4VWab5
2459 ag5fZzbGqi8kva/CzGgZh+CES0aWCPy+4Gb8lwOTt+854/laaJvd6kgKTER7z7U9
2460 9C86Ch2y4sXNwwwPJ1A9dmrZJZOcJjS/WYZgwaafY2Hdxub5jqPE5nehwYUPVu9R
2461 uH6/skk4OEKcfOtN0hCnISOVuKYyS4ANARWRG5VGHIH06z3lGUVARFRJ61gtAprd
2462 La+fgSS+LVZ+kU2TkeoWAKvGq8MAgDq4D4Xqwekg7WKFeuyusi/NI5rm40XgjBMF
2463 DF72IUofoVt7wo0=
2464 -----END CERTIFICATE-----`
2465
2466 func TestMultipleRDN(t *testing.T) {
2467 block, _ := pem.Decode([]byte(certMultipleRDN))
2468 cert, err := ParseCertificate(block.Bytes)
2469 if err != nil {
2470 t.Fatalf("certificate with two elements in an RDN failed to parse: %v", err)
2471 }
2472
2473 if want := "eportal.mss.edus.si"; cert.Subject.CommonName != want {
2474 t.Errorf("got common name of %q, but want %q", cert.Subject.CommonName, want)
2475 }
2476
2477 if want := "1236484010010"; cert.Subject.SerialNumber != want {
2478 t.Errorf("got serial number of %q, but want %q", cert.Subject.SerialNumber, want)
2479 }
2480 }
2481
2482 func TestSystemCertPool(t *testing.T) {
2483 if runtime.GOOS == "windows" {
2484 t.Skip("not implemented on Windows; Issue 16736, 18609")
2485 }
2486 a, err := SystemCertPool()
2487 if err != nil {
2488 t.Fatal(err)
2489 }
2490 b, err := SystemCertPool()
2491 if err != nil {
2492 t.Fatal(err)
2493 }
2494 if !reflect.DeepEqual(a, b) {
2495 t.Fatal("two calls to SystemCertPool had different results")
2496 }
2497 if ok := b.AppendCertsFromPEM([]byte(`
2498 -----BEGIN CERTIFICATE-----
2499 MIIDBjCCAe6gAwIBAgIRANXM5I3gjuqDfTp/PYrs+u8wDQYJKoZIhvcNAQELBQAw
2500 EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xODAzMjcxOTU2MjFaFw0xOTAzMjcxOTU2
2501 MjFaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
2502 ggEKAoIBAQDK+9m3rjsO2Djes6bIYQZ3eV29JF09ZrjOrEHLtaKrD6/acsoSoTsf
2503 cQr+rzzztdB5ijWXCS64zo/0OiqBeZUNZ67jVdToa9qW5UYe2H0Y+ZNdfA5GYMFD
2504 yk/l3/uBu3suTZPfXiW2TjEi27Q8ruNUIZ54DpTcs6y2rBRFzadPWwn/VQMlvRXM
2505 jrzl8Y08dgnYmaAHprxVzwMXcQ/Brol+v9GvjaH1DooHqkn8O178wsPQNhdtvN01
2506 IXL46cYdcUwWrE/GX5u+9DaSi+0KWxAPQ+NVD5qUI0CKl4714yGGh7feXMjJdHgl
2507 VG4QJZlJvC4FsURgCHJT6uHGIelnSwhbAgMBAAGjVzBVMA4GA1UdDwEB/wQEAwIF
2508 oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCAGA1UdEQQZMBeC
2509 FVRlc3RTeXN0ZW1DZXJ0UG9vbC5nbzANBgkqhkiG9w0BAQsFAAOCAQEAwuSRx/VR
2510 BKh2ICxZjL6jBwk/7UlU1XKbhQD96RqkidDNGEc6eLZ90Z5XXTurEsXqdm5jQYPs
2511 1cdcSW+fOSMl7MfW9e5tM66FaIPZl9rKZ1r7GkOfgn93xdLAWe8XHd19xRfDreub
2512 YC8DVqgLASOEYFupVSl76ktPfxkU5KCvmUf3P2PrRybk1qLGFytGxfyice2gHSNI
2513 gify3K/+H/7wCkyFW4xYvzl7WW4mXxoqPRPjQt1J423DhnnQ4G1P8V/vhUpXNXOq
2514 N9IEPnWuihC09cyx/WMQIUlWnaQLHdfpPS04Iez3yy2PdfXJzwfPrja7rNE+skK6
2515 pa/O1nF0AfWOpw==
2516 -----END CERTIFICATE-----
2517 `)); !ok {
2518 t.Fatal("AppendCertsFromPEM failed")
2519 }
2520 if reflect.DeepEqual(a, b) {
2521 t.Fatal("changing one pool modified the other")
2522 }
2523 }
2524
2525 const emptyNameConstraintsPEM = `
2526 -----BEGIN CERTIFICATE-----
2527 MIIC1jCCAb6gAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w
2528 dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw
2529 NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB
2530 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD
2531 F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx
2532 f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq
2533 Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0
2534 LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD
2535 blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID
2536 AQABoxEwDzANBgNVHR4EBjAEoAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMH
2537 QhP8uNCtgSHyim/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb
2538 6L+iJa4ElREJOi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6H
2539 v5SsvpYW+1XleYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6M
2540 LYPmRhTioROA/drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOga
2541 nCOSyFYfGhqOANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8
2542 o+WoY6IsCKXV/g==
2543 -----END CERTIFICATE-----`
2544
2545 func TestEmptyNameConstraints(t *testing.T) {
2546 block, _ := pem.Decode([]byte(emptyNameConstraintsPEM))
2547 _, err := ParseCertificate(block.Bytes)
2548 if err == nil {
2549 t.Fatal("unexpected success")
2550 }
2551
2552 const expected = "empty name constraints"
2553 if str := err.Error(); !strings.Contains(str, expected) {
2554 t.Errorf("expected %q in error but got %q", expected, str)
2555 }
2556 }
2557
2558 func TestPKIXNameString(t *testing.T) {
2559 pem, err := hex.DecodeString(certBytes)
2560 if err != nil {
2561 t.Fatal(err)
2562 }
2563 certs, err := ParseCertificates(pem)
2564 if IsFatal(err) {
2565 t.Fatal(err)
2566 }
2567
2568 tests := []struct {
2569 dn pkix.Name
2570 want string
2571 }{
2572 {pkix.Name{
2573 CommonName: "Steve Kille",
2574 Organization: []string{"Isode Limited"},
2575 OrganizationalUnit: []string{"RFCs"},
2576 Locality: []string{"Richmond"},
2577 Province: []string{"Surrey"},
2578 StreetAddress: []string{"The Square"},
2579 PostalCode: []string{"TW9 1DT"},
2580 SerialNumber: "RFC 2253",
2581 Country: []string{"GB"},
2582 }, "SERIALNUMBER=RFC 2253,CN=Steve Kille,OU=RFCs,O=Isode Limited,POSTALCODE=TW9 1DT,STREET=The Square,L=Richmond,ST=Surrey,C=GB"},
2583 {certs[0].Subject,
2584 "CN=mail.google.com,O=Google Inc,L=Mountain View,ST=California,C=US"},
2585 {pkix.Name{
2586 Organization: []string{"#Google, Inc. \n-> 'Alphabet\" "},
2587 Country: []string{"US"},
2588 }, "O=\\#Google\\, Inc. \n-\\> 'Alphabet\\\"\\ ,C=US"},
2589 {pkix.Name{
2590 CommonName: "foo.com",
2591 Organization: []string{"Gopher Industries"},
2592 ExtraNames: []pkix.AttributeTypeAndValue{
2593 {Type: asn1.ObjectIdentifier([]int{2, 5, 4, 3}), Value: "bar.com"}},
2594 }, "CN=bar.com,O=Gopher Industries"},
2595 {pkix.Name{
2596 Locality: []string{"Gophertown"},
2597 ExtraNames: []pkix.AttributeTypeAndValue{
2598 {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
2599 }, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"},
2600 }
2601
2602 for i, test := range tests {
2603 if got := test.dn.String(); got != test.want {
2604 t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want)
2605 }
2606 }
2607 }
2608
2609 func TestRDNSequenceString(t *testing.T) {
2610
2611
2612
2613 var (
2614 oidCountry = []int{2, 5, 4, 6}
2615 oidOrganization = []int{2, 5, 4, 10}
2616 oidOrganizationalUnit = []int{2, 5, 4, 11}
2617 oidCommonName = []int{2, 5, 4, 3}
2618 )
2619
2620 tests := []struct {
2621 seq pkix.RDNSequence
2622 want string
2623 }{
2624 {
2625 seq: pkix.RDNSequence{
2626 pkix.RelativeDistinguishedNameSET{
2627 pkix.AttributeTypeAndValue{Type: oidCountry, Value: "US"},
2628 },
2629 pkix.RelativeDistinguishedNameSET{
2630 pkix.AttributeTypeAndValue{Type: oidOrganization, Value: "Widget Inc."},
2631 },
2632 pkix.RelativeDistinguishedNameSET{
2633 pkix.AttributeTypeAndValue{Type: oidOrganizationalUnit, Value: "Sales"},
2634 pkix.AttributeTypeAndValue{Type: oidCommonName, Value: "J. Smith"},
2635 },
2636 },
2637 want: "OU=Sales+CN=J. Smith,O=Widget Inc.,C=US",
2638 },
2639 }
2640
2641 for i, test := range tests {
2642 if got := test.seq.String(); got != test.want {
2643 t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want)
2644 }
2645 }
2646 }
2647
2648 const criticalNameConstraintWithUnknownTypePEM = `
2649 -----BEGIN CERTIFICATE-----
2650 MIIC/TCCAeWgAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w
2651 dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw
2652 NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB
2653 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD
2654 F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx
2655 f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq
2656 Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0
2657 LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD
2658 blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID
2659 AQABozgwNjA0BgNVHR4BAf8EKjAooCQwIokgIACrzQAAAAAAAAAAAAAAAP////8A
2660 AAAAAAAAAAAAAAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMHQhP8uNCtgSHy
2661 im/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb6L+iJa4ElREJ
2662 Oi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6Hv5SsvpYW+1Xl
2663 eYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6MLYPmRhTioROA
2664 /drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOganCOSyFYfGhqO
2665 ANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8o+WoY6IsCKXV
2666 /g==
2667 -----END CERTIFICATE-----`
2668
2669 func TestCriticalNameConstraintWithUnknownType(t *testing.T) {
2670 block, _ := pem.Decode([]byte(criticalNameConstraintWithUnknownTypePEM))
2671 cert, err := ParseCertificate(block.Bytes)
2672 if err != nil {
2673 t.Fatalf("unexpected parsing failure: %s", err)
2674 }
2675
2676 if l := len(cert.UnhandledCriticalExtensions); l != 1 {
2677 t.Fatalf("expected one unhandled critical extension, but found %d", l)
2678 }
2679 }
2680
2681 const badIPMaskPEM = `
2682 -----BEGIN CERTIFICATE-----
2683 MIICzzCCAbegAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UEAxMSQmFk
2684 IElQIG1hc2sgaXNzdWVyMB4XDTEzMDIwMTAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
2685 FjEUMBIGA1UEAxMLQmFkIElQIG1hc2swggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
2686 ggEKAoIBAQDCuISVQi3csKqYk5uz7IOhY8MXkiqBaTqagihtiM997G1mJhTojcR+
2687 8DCg3E8OQ3ZajByhxRkwlsR4Srl5sGSwWfF/XaAHGUhWIhjBkDO7toW+EMzI8pAj
2688 cLwIbRlIL0AFnUTe6Z0DcIS5406Y/9MKE2oKXbf4EbVBv88mSkA74Z+lZJWFNxXn
2689 cx/9wq8UdyMY2vHN1Kir1/JbtrqB9wYRBjQtWSbAVZR8nTBPyRp4uvQTS2jOQh+j
2690 TUo1Y3O/o1xg/zRA4FEOUCla704OYRUkc8NuXHiPNNDcktr7gO8E06NVQ6n6aBGa
2691 OJbSst2vHA7Eiog7A2PB4wKn+GDFf+FNAgMBAAGjIDAeMBwGA1UdHgEB/wQSMBCg
2692 DDAKhwgBAgME//8BAKEAMA0GCSqGSIb3DQEBCwUAA4IBAQBYb7/NQwdCE/y40K2B
2693 IfKKb++HvCaKfAC9aAwrGWQsEWezqdl5Cqw5XWUAFjtTRm6iprVnmdvov6IlrgSV
2694 EQk6L96stz24vAF0MIBHSFRMoPtrqLiihLf0NOV7ztxSePQxbUJRroe/lKy+lhb7
2695 VeV5gmT9rFA45NzLgSznd2+dmyNcfQQD9AeeftRX4maUTeu1XFxinowtg+ZGFOKh
2696 E4D92uCGJxGSK72HF0/LGRhLXozmDdmPfSN2b6T/oLo942031iY46BqcI5LIVh8a
2697 Go4A1jOma5X6gh50Cw+kht8jM3yeNhSzXOKj7Uigjijx10z2wJu09Tyj5ahjoiwI
2698 pdX+
2699 -----END CERTIFICATE-----`
2700
2701 func TestBadIPMask(t *testing.T) {
2702 block, _ := pem.Decode([]byte(badIPMaskPEM))
2703 _, err := ParseCertificate(block.Bytes)
2704 if err == nil {
2705 t.Fatalf("unexpected success")
2706 }
2707
2708 const expected = "contained invalid mask"
2709 if !strings.Contains(err.Error(), expected) {
2710 t.Fatalf("expected %q in error but got: %s", expected, err)
2711 }
2712 }
2713
2714 const additionalGeneralSubtreePEM = `
2715 -----BEGIN CERTIFICATE-----
2716 MIIG4TCCBMmgAwIBAgIRALss+4rLw2Ia7tFFhxE8g5cwDQYJKoZIhvcNAQELBQAw
2717 bjELMAkGA1UEBhMCTkwxIDAeBgNVBAoMF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll
2718 MT0wOwYDVQQDDDRNaW5pc3RlcmllIHZhbiBEZWZlbnNpZSBDZXJ0aWZpY2F0aWUg
2719 QXV0b3JpdGVpdCAtIEcyMB4XDTEzMDMwNjEyMDM0OVoXDTEzMTEzMDEyMDM1MFow
2720 bDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUNlcnRpUGF0aCBMTEMxIjAgBgNVBAsT
2721 GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxITAfBgNVBAMTGENlcnRpUGF0aCBC
2722 cmlkZ2UgQ0EgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANLW
2723 4kXiRqvwBhJfN9uz12FA+P2D34MPxOt7TGXljm2plJ2CLzvaH8/ymsMdSWdJBS1M
2724 8FmwvNL1w3A6ZuzksJjPikAu8kY3dcp3mrkk9eCPORDAwGtfsXwZysLiuEaDWpbD
2725 dHOaHnI6qWU0N6OI+hNX58EjDpIGC1WQdho1tHOTPc5Hf5/hOpM/29v/wr7kySjs
2726 Z+7nsvkm5rNhuJNzPsLsgzVaJ5/BVyOplZy24FKM8Y43MjR4osZm+a2e0zniqw6/
2727 rvcjcGYabYaznZfQG1GXoyf2Vea+CCgpgUhlVafgkwEs8izl8rIpvBzXiFAgFQuG
2728 Ituoy92PJbDs430fA/cCAwEAAaOCAnowggJ2MEUGCCsGAQUFBwEBBDkwNzA1Bggr
2729 BgEFBQcwAoYpaHR0cDovL2NlcnRzLmNhLm1pbmRlZi5ubC9taW5kZWYtY2EtMi5w
2730 N2MwHwYDVR0jBBgwFoAUzln9WSPz2M64Rl2HYf2/KD8StmQwDwYDVR0TAQH/BAUw
2731 AwEB/zCB6QYDVR0gBIHhMIHeMEgGCmCEEAGHawECBQEwOjA4BggrBgEFBQcCARYs
2732 aHR0cDovL2Nwcy5kcC5jYS5taW5kZWYubmwvbWluZGVmLWNhLWRwLWNwcy8wSAYK
2733 YIQQAYdrAQIFAjA6MDgGCCsGAQUFBwIBFixodHRwOi8vY3BzLmRwLmNhLm1pbmRl
2734 Zi5ubC9taW5kZWYtY2EtZHAtY3BzLzBIBgpghBABh2sBAgUDMDowOAYIKwYBBQUH
2735 AgEWLGh0dHA6Ly9jcHMuZHAuY2EubWluZGVmLm5sL21pbmRlZi1jYS1kcC1jcHMv
2736 MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmxzLmNhLm1pbmRlZi5ubC9taW5k
2737 ZWYtY2EtMi5jcmwwDgYDVR0PAQH/BAQDAgEGMEYGA1UdHgEB/wQ8MDqhODA2pDEw
2738 LzELMAkGA1UEBhMCTkwxIDAeBgNVBAoTF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll
2739 gQFjMF0GA1UdIQRWMFQwGgYKYIQQAYdrAQIFAQYMKwYBBAGBu1MBAQECMBoGCmCE
2740 EAGHawECBQIGDCsGAQQBgbtTAQEBAjAaBgpghBABh2sBAgUDBgwrBgEEAYG7UwEB
2741 AQIwHQYDVR0OBBYEFNDCjBM3M3ZKkag84ei3/aKc0d0UMA0GCSqGSIb3DQEBCwUA
2742 A4ICAQAQXFn9jF90/DNFf15JhoGtta/0dNInb14PMu3PAjcdrXYCDPpQZOArTUng
2743 5YT1WuzfmjnXiTsziT3my0r9Mxvz/btKK/lnVOMW4c2q/8sIsIPnnW5ZaRGrsANB
2744 dNDZkzMYmeG2Pfgvd0AQSOrpE/TVgWfu/+MMRWwX9y6VbooBR7BLv7zMuVH0WqLn
2745 6OMFth7fqsThlfMSzkE/RDSaU6n3wXAWT1SIqBITtccRjSUQUFm/q3xrb2cwcZA6
2746 8vdS4hzNd+ttS905ay31Ks4/1Wrm1bH5RhEfRSH0VSXnc0b+z+RyBbmiwtVZqzxE
2747 u3UQg/rAmtLDclLFEzjp8YDTIRYSLwstDbEXO/0ArdGrQm79HQ8i/3ZbP2357myW
2748 i15qd6gMJIgGHS4b8Hc7R1K8LQ9Gm1aLKBEWVNGZlPK/cpXThpVmoEyslN2DHCrc
2749 fbMbjNZpXlTMa+/b9z7Fa4X8dY8u/ELzZuJXJv5Rmqtg29eopFFYDCl0Nkh1XAjo
2750 QejEoHHUvYV8TThHZr6Z6Ib8CECgTehU4QvepkgDXNoNrKRZBG0JhLjkwxh2whZq
2751 nvWBfALC2VuNOM6C0rDY+HmhMlVt0XeqnybD9MuQALMit7Z00Cw2CIjNsBI9xBqD
2752 xKK9CjUb7gzRUWSpB9jGHsvpEMHOzIFhufvH2Bz1XJw+Cl7khw==
2753 -----END CERTIFICATE-----`
2754
2755 func TestAdditionFieldsInGeneralSubtree(t *testing.T) {
2756
2757
2758
2759 block, _ := pem.Decode([]byte(additionalGeneralSubtreePEM))
2760 if _, err := ParseCertificate(block.Bytes); IsFatal(err) {
2761 t.Fatalf("failed to parse certificate: %s", err)
2762 }
2763 }
2764
2765 func TestEmptySubject(t *testing.T) {
2766 template := Certificate{
2767 SerialNumber: big.NewInt(1),
2768 DNSNames: []string{"example.com"},
2769 }
2770
2771 derBytes, err := CreateCertificate(rand.Reader, &template, &template, &testPrivateKey.PublicKey, testPrivateKey)
2772 if err != nil {
2773 t.Fatalf("failed to create certificate: %s", err)
2774 }
2775
2776 cert, err := ParseCertificate(derBytes)
2777 if err != nil {
2778 t.Fatalf("failed to parse certificate: %s", err)
2779 }
2780
2781 for _, ext := range cert.Extensions {
2782 if ext.Id.Equal(OIDExtensionSubjectAltName) {
2783 if !ext.Critical {
2784 t.Fatal("SAN extension is not critical")
2785 }
2786 return
2787 }
2788 }
2789
2790 t.Fatal("SAN extension is missing")
2791 }
2792
2793
2794
2795 const multipleURLsInCRLDPPEM = `
2796 -----BEGIN CERTIFICATE-----
2797 MIIF4TCCBMmgAwIBAgIQc+6uFePfrahUGpXs8lhiTzANBgkqhkiG9w0BAQsFADCB
2798 8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy
2799 dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1
2800 YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3
2801 dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh
2802 IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD
2803 LUFDQzAeFw0xNDA5MTgwODIxMDBaFw0zMDA5MTgwODIxMDBaMIGGMQswCQYDVQQG
2804 EwJFUzEzMDEGA1UECgwqQ09OU09SQ0kgQURNSU5JU1RSQUNJTyBPQkVSVEEgREUg
2805 Q0FUQUxVTllBMSowKAYDVQQLDCFTZXJ2ZWlzIFDDumJsaWNzIGRlIENlcnRpZmlj
2806 YWNpw7MxFjAUBgNVBAMMDUVDLUNpdXRhZGFuaWEwggEiMA0GCSqGSIb3DQEBAQUA
2807 A4IBDwAwggEKAoIBAQDFkHPRZPZlXTWZ5psJhbS/Gx+bxcTpGrlVQHHtIkgGz77y
2808 TA7UZUFb2EQMncfbOhR0OkvQQn1aMvhObFJSR6nI+caf2D+h/m/InMl1MyH3S0Ak
2809 YGZZsthnyC6KxqK2A/NApncrOreh70ULkQs45aOKsi1kR1W0zE+iFN+/P19P7AkL
2810 Rl3bXBCVd8w+DLhcwRrkf1FCDw6cEqaFm3cGgf5cbBDMaVYAweWTxwBZAq2RbQAW
2811 jE7mledcYghcZa4U6bUmCBPuLOnO8KMFAvH+aRzaf3ws5/ZoOVmryyLLJVZ54peZ
2812 OwnP9EL4OuWzmXCjBifXR2IAblxs5JYj57tls45nAgMBAAGjggHaMIIB1jASBgNV
2813 HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUC2hZPofI
2814 oxUa4ECCIl+fHbLFNxUwHwYDVR0jBBgwFoAUoMOLRKo3pUW/l4Ba0fF4opvpXY0w
2815 gdYGA1UdIASBzjCByzCByAYEVR0gADCBvzAxBggrBgEFBQcCARYlaHR0cHM6Ly93
2816 d3cuYW9jLmNhdC9DQVRDZXJ0L1JlZ3VsYWNpbzCBiQYIKwYBBQUHAgIwfQx7QXF1
2817 ZXN0IGNlcnRpZmljYXQgw6lzIGVtw6hzIMO6bmljYSBpIGV4Y2x1c2l2YW1lbnQg
2818 YSBFbnRpdGF0cyBkZSBDZXJ0aWZpY2FjacOzLiBWZWdldSBodHRwczovL3d3dy5h
2819 b2MuY2F0L0NBVENlcnQvUmVndWxhY2lvMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEF
2820 BQcwAYYXaHR0cDovL29jc3AuY2F0Y2VydC5jYXQwYgYDVR0fBFswWTBXoFWgU4Yn
2821 aHR0cDovL2Vwc2NkLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JshihodHRwOi8v
2822 ZXBzY2QyLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JsMA0GCSqGSIb3DQEBCwUA
2823 A4IBAQChqFTjlAH5PyIhLjLgEs68CyNNC1+vDuZXRhy22TI83JcvGmQrZosPvVIL
2824 PsUXx+C06Pfqmh48Q9S89X9K8w1SdJxP/rZeGEoRiKpwvQzM4ArD9QxyC8jirxex
2825 3Umg9Ai/sXQ+1lBf6xw4HfUUr1WIp7pNHj0ZWLo106urqktcdeAFWme+/klis5fu
2826 labCSVPuT/QpwakPrtqOhRms8vgpKiXa/eLtL9ZiA28X/Mker0zlAeTA7Z7uAnp6
2827 oPJTlZu1Gg1ZDJueTWWsLlO+P+Wzm3MRRIbcgdRzm4mdO7ubu26SzX/aQXDhuih+
2828 eVxXDTCfs7GUlxnjOp5j559X/N0A
2829 -----END CERTIFICATE-----
2830 `
2831
2832 func TestMultipleURLsInCRLDP(t *testing.T) {
2833 block, _ := pem.Decode([]byte(multipleURLsInCRLDPPEM))
2834 cert, err := ParseCertificate(block.Bytes)
2835 if err != nil {
2836 t.Fatalf("failed to parse certificate: %s", err)
2837 }
2838
2839 want := []string{
2840 "http://epscd.catcert.net/crl/ec-acc.crl",
2841 "http://epscd2.catcert.net/crl/ec-acc.crl",
2842 }
2843 if got := cert.CRLDistributionPoints; !reflect.DeepEqual(got, want) {
2844 t.Errorf("CRL distribution points = %#v, want #%v", got, want)
2845 }
2846 }
2847
2848 func TestParseCertificateFail(t *testing.T) {
2849 var tests = []struct {
2850 desc string
2851 in string
2852 wantErr string
2853 wantFatal bool
2854 }{
2855 {desc: "SubjectInfoEmpty", in: "testdata/invalid/xf-ext-subject-info-empty.pem", wantErr: "empty SubjectInfoAccess"},
2856 {desc: "RSAParamsNonNULL", in: "testdata/invalid/xf-pubkey-rsa-param-nonnull.pem", wantErr: "RSA key missing NULL parameters"},
2857 {desc: "EmptyEKU", in: "testdata/invalid/xf-ext-extended-key-usage-empty.pem", wantErr: "empty ExtendedKeyUsage"},
2858 {desc: "EKUEmptyOID", in: "testdata/invalid/xf-ext-extended-key-usage-empty-oid.pem", wantErr: "zero length OBJECT IDENTIFIER"},
2859 {desc: "SECp192r1TooShort", in: "testdata/invalid/xf-pubkey-ecdsa-secp192r1.pem", wantErr: "insecure curve (secp192r1)"},
2860 {desc: "SerialNumIntegerNotMinimal", in: "testdata/invalid/xf-der-invalid-nonminimal-int.pem", wantErr: "integer not minimally-encoded"},
2861 {desc: "RSAIntegerNotMinimal", in: "testdata/invalid/xf-der-pubkey-rsa-nonminimal-int.pem", wantErr: "integer not minimally-encoded"},
2862 {desc: "SubjectNonPrintable", in: "testdata/invalid/xf-subject-nonprintable.pem", wantErr: "PrintableString contains invalid character"},
2863 {desc: "NegativeRSAModulus", in: "testdata/invalid/xf-pubkey-rsa-modulus-negative.pem", wantErr: "RSA modulus is not a positive number"},
2864 }
2865 for _, test := range tests {
2866 t.Run(test.desc, func(t *testing.T) {
2867 data, err := os.ReadFile(test.in)
2868 if err != nil {
2869 t.Fatalf("failed to read test data: %v", err)
2870 }
2871 block, _ := pem.Decode(data)
2872 got, err := ParseCertificate(block.Bytes)
2873 if err == nil {
2874 t.Fatalf("ParseCertificate()=%+v,nil; want nil, err containing %q", got, test.wantErr)
2875 }
2876 if !strings.Contains(err.Error(), test.wantErr) {
2877 t.Errorf("ParseCertificate()=_,%v; want nil, err containing %q", err, test.wantErr)
2878 }
2879 gotFatal := IsFatal(err)
2880 if gotFatal != test.wantFatal {
2881 t.Errorf("ParseCertificate()=_,%v with fatal=%t; want nil, err containing %q with fatal=%t", err, gotFatal, test.wantErr, test.wantFatal)
2882 }
2883 })
2884 }
2885 }
2886
View as plain text