1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package x509
6
7import (
8	"bytes"
9	"crypto/dsa"
10	"crypto/ecdsa"
11	"crypto/ed25519"
12	"crypto/elliptic"
13	"crypto/rand"
14	"crypto/rsa"
15	_ "crypto/sha256"
16	_ "crypto/sha512"
17	"crypto/x509/pkix"
18	"encoding/asn1"
19	"encoding/base64"
20	"encoding/hex"
21	"encoding/pem"
22	"fmt"
23	"internal/testenv"
24	"math/big"
25	"net"
26	"net/url"
27	"os/exec"
28	"reflect"
29	"runtime"
30	"strings"
31	"testing"
32	"time"
33)
34
35func TestParsePKCS1PrivateKey(t *testing.T) {
36	block, _ := pem.Decode([]byte(pemPrivateKey))
37	priv, err := ParsePKCS1PrivateKey(block.Bytes)
38	if err != nil {
39		t.Errorf("Failed to parse private key: %s", err)
40		return
41	}
42	if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 ||
43		priv.PublicKey.E != rsaPrivateKey.PublicKey.E ||
44		priv.D.Cmp(rsaPrivateKey.D) != 0 ||
45		priv.Primes[0].Cmp(rsaPrivateKey.Primes[0]) != 0 ||
46		priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 {
47		t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey)
48	}
49
50	// This private key includes an invalid prime that
51	// rsa.PrivateKey.Validate should reject.
52	data := []byte("0\x16\x02\x00\x02\x02\u007f\x00\x02\x0200\x02\x0200\x02\x02\x00\x01\x02\x02\u007f\x00")
53	if _, err := ParsePKCS1PrivateKey(data); err == nil {
54		t.Errorf("parsing invalid private key did not result in an error")
55	}
56}
57
58func TestPKCS1MismatchPublicKeyFormat(t *testing.T) {
59
60	const pkixPublicKey = "30820122300d06092a864886f70d01010105000382010f003082010a0282010100dd5a0f37d3ca5232852ccc0e81eebec270e2f2c6c44c6231d852971a0aad00aa7399e9b9de444611083c59ea919a9d76c20a7be131a99045ec19a7bb452d647a72429e66b87e28be9e8187ed1d2a2a01ef3eb2360706bd873b07f2d1f1a72337aab5ec94e983e39107f52c480d404915e84d75a3db2cfd601726a128cb1d7f11492d4bdb53272e652276667220795c709b8a9b4af6489cbf48bb8173b8fb607c834a71b6e8bf2d6aab82af3c8ad7ce16d8dcf58373a6edc427f7484d09744d4c08f4e19ed07adbf6cb31243bc5d0d1145e77a08a6fc5efd208eca67d6abf2d6f38f58b6fdd7c28774fb0cc03fc4935c6e074842d2e1479d3d8787249258719f90203010001"
61	const errorContains = "use ParsePKIXPublicKey instead"
62	derBytes, _ := hex.DecodeString(pkixPublicKey)
63	_, err := ParsePKCS1PublicKey(derBytes)
64	if !strings.Contains(err.Error(), errorContains) {
65		t.Errorf("expected error containing %q, got %s", errorContains, err)
66	}
67}
68
69func testParsePKIXPublicKey(t *testing.T, pemBytes string) (pub interface{}) {
70	block, _ := pem.Decode([]byte(pemBytes))
71	pub, err := ParsePKIXPublicKey(block.Bytes)
72	if err != nil {
73		t.Fatalf("Failed to parse public key: %s", err)
74	}
75
76	pubBytes2, err := MarshalPKIXPublicKey(pub)
77	if err != nil {
78		t.Errorf("Failed to marshal public key for the second time: %s", err)
79		return
80	}
81	if !bytes.Equal(pubBytes2, block.Bytes) {
82		t.Errorf("Reserialization of public key didn't match. got %x, want %x", pubBytes2, block.Bytes)
83	}
84	return
85}
86
87func TestParsePKIXPublicKey(t *testing.T) {
88	t.Run("RSA", func(t *testing.T) {
89		pub := testParsePKIXPublicKey(t, pemPublicKey)
90		_, ok := pub.(*rsa.PublicKey)
91		if !ok {
92			t.Errorf("Value returned from ParsePKIXPublicKey was not an RSA public key")
93		}
94	})
95	t.Run("Ed25519", func(t *testing.T) {
96		pub := testParsePKIXPublicKey(t, pemEd25519Key)
97		_, ok := pub.(ed25519.PublicKey)
98		if !ok {
99			t.Errorf("Value returned from ParsePKIXPublicKey was not an Ed25519 public key")
100		}
101	})
102}
103
104var pemPublicKey = `-----BEGIN PUBLIC KEY-----
105MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VoPN9PKUjKFLMwOge6+
106wnDi8sbETGIx2FKXGgqtAKpzmem53kRGEQg8WeqRmp12wgp74TGpkEXsGae7RS1k
107enJCnma4fii+noGH7R0qKgHvPrI2Bwa9hzsH8tHxpyM3qrXslOmD45EH9SxIDUBJ
108FehNdaPbLP1gFyahKMsdfxFJLUvbUycuZSJ2ZnIgeVxwm4qbSvZInL9Iu4FzuPtg
109fINKcbbovy1qq4KvPIrXzhbY3PWDc6btxCf3SE0JdE1MCPThntB62/bLMSQ7xdDR
110FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ
111+QIDAQAB
112-----END PUBLIC KEY-----
113`
114
115var pemPrivateKey = testingKey(`
116-----BEGIN RSA TESTING KEY-----
117MIICXAIBAAKBgQCxoeCUW5KJxNPxMp+KmCxKLc1Zv9Ny+4CFqcUXVUYH69L3mQ7v
118IWrJ9GBfcaA7BPQqUlWxWM+OCEQZH1EZNIuqRMNQVuIGCbz5UQ8w6tS0gcgdeGX7
119J7jgCQ4RK3F/PuCM38QBLaHx988qG8NMc6VKErBjctCXFHQt14lerd5KpQIDAQAB
120AoGAYrf6Hbk+mT5AI33k2Jt1kcweodBP7UkExkPxeuQzRVe0KVJw0EkcFhywKpr1
121V5eLMrILWcJnpyHE5slWwtFHBG6a5fLaNtsBBtcAIfqTQ0Vfj5c6SzVaJv0Z5rOd
1227gQF6isy3t3w9IF3We9wXQKzT6q5ypPGdm6fciKQ8RnzREkCQQDZwppKATqQ41/R
123vhSj90fFifrGE6aVKC1hgSpxGQa4oIdsYYHwMzyhBmWW9Xv/R+fPyr8ZwPxp2c12
12433QwOLPLAkEA0NNUb+z4ebVVHyvSwF5jhfJxigim+s49KuzJ1+A2RaSApGyBZiwS
125rWvWkB471POAKUYt5ykIWVZ83zcceQiNTwJBAMJUFQZX5GDqWFc/zwGoKkeR49Yi
126MTXIvf7Wmv6E++eFcnT461FlGAUHRV+bQQXGsItR/opIG7mGogIkVXa3E1MCQARX
127AAA7eoZ9AEHflUeuLn9QJI/r0hyQQLEtrpwv6rDT1GCWaLII5HJ6NUFVf4TTcqxo
1286vdM4QGKTJoO+SaCyP0CQFdpcxSAuzpFcKv0IlJ8XzS/cy+mweCMwyJ1PFEc4FX6
129wg/HcAJWY60xZTJDFN+Qfx8ZQvBEin6c2/h+zZi5IVY=
130-----END RSA TESTING KEY-----
131`)
132
133// pemEd25519Key is the example from RFC 8410, Secrion 4.
134var pemEd25519Key = `
135-----BEGIN PUBLIC KEY-----
136MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=
137-----END PUBLIC KEY-----
138`
139
140func TestPKIXMismatchPublicKeyFormat(t *testing.T) {
141
142	const pkcs1PublicKey = "308201080282010100817cfed98bcaa2e2a57087451c7674e0c675686dc33ff1268b0c2a6ee0202dec710858ee1c31bdf5e7783582e8ca800be45f3275c6576adc35d98e26e95bb88ca5beb186f853b8745d88bc9102c5f38753bcda519fb05948d5c77ac429255ff8aaf27d9f45d1586e95e2e9ba8a7cb771b8a09dd8c8fed3f933fd9b439bc9f30c475953418ef25f71a2b6496f53d94d39ce850aa0cc75d445b5f5b4f4ee4db78ab197a9a8d8a852f44529a007ac0ac23d895928d60ba538b16b0b087a7f903ed29770e215019b77eaecc360f35f7ab11b6d735978795b2c4a74e5bdea4dc6594cd67ed752a108e666729a753ab36d6c4f606f8760f507e1765be8cd744007e629020103"
143	const errorContains = "use ParsePKCS1PublicKey instead"
144	derBytes, _ := hex.DecodeString(pkcs1PublicKey)
145	_, err := ParsePKIXPublicKey(derBytes)
146	if !strings.Contains(err.Error(), errorContains) {
147		t.Errorf("expected error containing %q, got %s", errorContains, err)
148	}
149}
150
151var testPrivateKey *rsa.PrivateKey
152
153func init() {
154	block, _ := pem.Decode([]byte(pemPrivateKey))
155
156	var err error
157	if testPrivateKey, err = ParsePKCS1PrivateKey(block.Bytes); err != nil {
158		panic("Failed to parse private key: " + err.Error())
159	}
160}
161
162func bigFromString(s string) *big.Int {
163	ret := new(big.Int)
164	ret.SetString(s, 10)
165	return ret
166}
167
168func fromBase10(base10 string) *big.Int {
169	i := new(big.Int)
170	i.SetString(base10, 10)
171	return i
172}
173
174func bigFromHexString(s string) *big.Int {
175	ret := new(big.Int)
176	ret.SetString(s, 16)
177	return ret
178}
179
180var rsaPrivateKey = &rsa.PrivateKey{
181	PublicKey: rsa.PublicKey{
182		N: bigFromString("124737666279038955318614287965056875799409043964547386061640914307192830334599556034328900586693254156136128122194531292927142396093148164407300419162827624945636708870992355233833321488652786796134504707628792159725681555822420087112284637501705261187690946267527866880072856272532711620639179596808018872997"),
183		E: 65537,
184	},
185	D: bigFromString("69322600686866301945688231018559005300304807960033948687567105312977055197015197977971637657636780793670599180105424702854759606794705928621125408040473426339714144598640466128488132656829419518221592374964225347786430566310906679585739468938549035854760501049443920822523780156843263434219450229353270690889"),
186	Primes: []*big.Int{
187		bigFromString("11405025354575369741595561190164746858706645478381139288033759331174478411254205003127028642766986913445391069745480057674348716675323735886284176682955723"),
188		bigFromString("10937079261204603443118731009201819560867324167189758120988909645641782263430128449826989846631183550578761324239709121189827307416350485191350050332642639"),
189	},
190}
191
192func TestMarshalRSAPrivateKey(t *testing.T) {
193	priv := &rsa.PrivateKey{
194		PublicKey: rsa.PublicKey{
195			N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
196			E: 3,
197		},
198		D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"),
199		Primes: []*big.Int{
200			fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
201			fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
202			fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
203		},
204	}
205
206	derBytes := MarshalPKCS1PrivateKey(priv)
207
208	priv2, err := ParsePKCS1PrivateKey(derBytes)
209	if err != nil {
210		t.Errorf("error parsing serialized key: %s", err)
211		return
212	}
213	if priv.PublicKey.N.Cmp(priv2.PublicKey.N) != 0 ||
214		priv.PublicKey.E != priv2.PublicKey.E ||
215		priv.D.Cmp(priv2.D) != 0 ||
216		len(priv2.Primes) != 3 ||
217		priv.Primes[0].Cmp(priv2.Primes[0]) != 0 ||
218		priv.Primes[1].Cmp(priv2.Primes[1]) != 0 ||
219		priv.Primes[2].Cmp(priv2.Primes[2]) != 0 {
220		t.Errorf("got:%+v want:%+v", priv, priv2)
221	}
222}
223
224func TestMarshalRSAPublicKey(t *testing.T) {
225	pub := &rsa.PublicKey{
226		N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
227		E: 3,
228	}
229	derBytes := MarshalPKCS1PublicKey(pub)
230	pub2, err := ParsePKCS1PublicKey(derBytes)
231	if err != nil {
232		t.Errorf("ParsePKCS1PublicKey: %s", err)
233	}
234	if pub.N.Cmp(pub2.N) != 0 || pub.E != pub2.E {
235		t.Errorf("ParsePKCS1PublicKey = %+v, want %+v", pub, pub2)
236	}
237
238	// It's never been documented that asn1.Marshal/Unmarshal on rsa.PublicKey works,
239	// but it does, and we know of code that depends on it.
240	// Lock that in, even though we'd prefer that people use MarshalPKCS1PublicKey and ParsePKCS1PublicKey.
241	derBytes2, err := asn1.Marshal(*pub)
242	if err != nil {
243		t.Errorf("Marshal(rsa.PublicKey): %v", err)
244	} else if !bytes.Equal(derBytes, derBytes2) {
245		t.Errorf("Marshal(rsa.PublicKey) = %x, want %x", derBytes2, derBytes)
246	}
247	pub3 := new(rsa.PublicKey)
248	rest, err := asn1.Unmarshal(derBytes, pub3)
249	if err != nil {
250		t.Errorf("Unmarshal(rsa.PublicKey): %v", err)
251	}
252	if len(rest) != 0 || pub.N.Cmp(pub3.N) != 0 || pub.E != pub3.E {
253		t.Errorf("Unmarshal(rsa.PublicKey) = %+v, %q want %+v, %q", pub, rest, pub2, []byte(nil))
254	}
255
256	publicKeys := []struct {
257		derBytes          []byte
258		expectedErrSubstr string
259	}{
260		{
261			derBytes: []byte{
262				0x30, 6, // SEQUENCE, 6 bytes
263				0x02, 1, // INTEGER, 1 byte
264				17,
265				0x02, 1, // INTEGER, 1 byte
266				3, // 3
267			},
268		}, {
269			derBytes: []byte{
270				0x30, 6, // SEQUENCE
271				0x02, 1, // INTEGER, 1 byte
272				0xff,    // -1
273				0x02, 1, // INTEGER, 1 byte
274				3,
275			},
276			expectedErrSubstr: "zero or negative",
277		}, {
278			derBytes: []byte{
279				0x30, 6, // SEQUENCE
280				0x02, 1, // INTEGER, 1 byte
281				17,
282				0x02, 1, // INTEGER, 1 byte
283				0xff, // -1
284			},
285			expectedErrSubstr: "zero or negative",
286		}, {
287			derBytes: []byte{
288				0x30, 6, // SEQUENCE
289				0x02, 1, // INTEGER, 1 byte
290				17,
291				0x02, 1, // INTEGER, 1 byte
292				3,
293				1,
294			},
295			expectedErrSubstr: "trailing data",
296		}, {
297			derBytes: []byte{
298				0x30, 9, // SEQUENCE
299				0x02, 1, // INTEGER, 1 byte
300				17,
301				0x02, 4, // INTEGER, 4 bytes
302				0x7f, 0xff, 0xff, 0xff,
303			},
304		}, {
305			derBytes: []byte{
306				0x30, 10, // SEQUENCE
307				0x02, 1, // INTEGER, 1 byte
308				17,
309				0x02, 5, // INTEGER, 5 bytes
310				0x00, 0x80, 0x00, 0x00, 0x00,
311			},
312			// On 64-bit systems, encoding/asn1 will accept the
313			// public exponent, but ParsePKCS1PublicKey will return
314			// an error. On 32-bit systems, encoding/asn1 will
315			// return the error. The common substring of both error
316			// is the word “large”.
317			expectedErrSubstr: "large",
318		},
319	}
320
321	for i, test := range publicKeys {
322		shouldFail := len(test.expectedErrSubstr) > 0
323		pub, err := ParsePKCS1PublicKey(test.derBytes)
324		if shouldFail {
325			if err == nil {
326				t.Errorf("#%d: unexpected success, got %#v", i, pub)
327			} else if !strings.Contains(err.Error(), test.expectedErrSubstr) {
328				t.Errorf("#%d: expected error containing %q, got %s", i, test.expectedErrSubstr, err)
329			}
330		} else {
331			if err != nil {
332				t.Errorf("#%d: unexpected failure: %s", i, err)
333				continue
334			}
335			reserialized := MarshalPKCS1PublicKey(pub)
336			if !bytes.Equal(reserialized, test.derBytes) {
337				t.Errorf("#%d: failed to reserialize: got %x, expected %x", i, reserialized, test.derBytes)
338			}
339		}
340	}
341}
342
343type matchHostnamesTest struct {
344	pattern, host string
345	ok            bool
346}
347
348var matchHostnamesTests = []matchHostnamesTest{
349	{"a.b.c", "a.b.c", true},
350	{"a.b.c", "b.b.c", false},
351	{"", "b.b.c", false},
352	{"a.b.c", "", false},
353	{"example.com", "example.com", true},
354	{"example.com", "www.example.com", false},
355	{"*.example.com", "example.com", false},
356	{"*.example.com", "www.example.com", true},
357	{"*.example.com", "www.example.com.", true},
358	{"*.example.com", "xyz.www.example.com", false},
359	{"*.*.example.com", "xyz.www.example.com", false},
360	{"*.www.*.com", "xyz.www.example.com", false},
361	{"*bar.example.com", "foobar.example.com", false},
362	{"f*.example.com", "foobar.example.com", false},
363	{"", ".", false},
364	{".", "", false},
365	{".", ".", false},
366	{"example.com", "example.com.", true},
367	{"example.com.", "example.com", true},
368	{"example.com.", "example.com.", true},
369	{"*.com.", "example.com.", true},
370	{"*.com.", "example.com", true},
371	{"*.com", "example.com", true},
372	{"*.com", "example.com.", true},
373}
374
375func TestMatchHostnames(t *testing.T) {
376	for i, test := range matchHostnamesTests {
377		r := matchHostnames(test.pattern, test.host)
378		if r != test.ok {
379			t.Errorf("#%d mismatch got: %t want: %t when matching '%s' against '%s'", i, r, test.ok, test.host, test.pattern)
380		}
381	}
382}
383
384func TestMatchIP(t *testing.T) {
385	// Check that pattern matching is working.
386	c := &Certificate{
387		DNSNames: []string{"*.foo.bar.baz"},
388		Subject: pkix.Name{
389			CommonName: "*.foo.bar.baz",
390		},
391	}
392	err := c.VerifyHostname("quux.foo.bar.baz")
393	if err != nil {
394		t.Fatalf("VerifyHostname(quux.foo.bar.baz): %v", err)
395	}
396
397	// But check that if we change it to be matching against an IP address,
398	// it is rejected.
399	c = &Certificate{
400		DNSNames: []string{"*.2.3.4"},
401		Subject: pkix.Name{
402			CommonName: "*.2.3.4",
403		},
404	}
405	err = c.VerifyHostname("1.2.3.4")
406	if err == nil {
407		t.Fatalf("VerifyHostname(1.2.3.4) should have failed, did not")
408	}
409
410	c = &Certificate{
411		IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")},
412	}
413	err = c.VerifyHostname("127.0.0.1")
414	if err != nil {
415		t.Fatalf("VerifyHostname(127.0.0.1): %v", err)
416	}
417	err = c.VerifyHostname("::1")
418	if err != nil {
419		t.Fatalf("VerifyHostname(::1): %v", err)
420	}
421	err = c.VerifyHostname("[::1]")
422	if err != nil {
423		t.Fatalf("VerifyHostname([::1]): %v", err)
424	}
425}
426
427func TestCertificateParse(t *testing.T) {
428	s, _ := hex.DecodeString(certBytes)
429	certs, err := ParseCertificates(s)
430	if err != nil {
431		t.Error(err)
432	}
433	if len(certs) != 2 {
434		t.Errorf("Wrong number of certs: got %d want 2", len(certs))
435		return
436	}
437
438	err = certs[0].CheckSignatureFrom(certs[1])
439	if err != nil {
440		t.Error(err)
441	}
442
443	if err := certs[0].VerifyHostname("mail.google.com"); err != nil {
444		t.Error(err)
445	}
446
447	const expectedExtensions = 4
448	if n := len(certs[0].Extensions); n != expectedExtensions {
449		t.Errorf("want %d extensions, got %d", expectedExtensions, n)
450	}
451}
452
453func TestCertificateEqualOnNil(t *testing.T) {
454	cNonNil := new(Certificate)
455	var cNil1, cNil2 *Certificate
456	if !cNil1.Equal(cNil2) {
457		t.Error("Nil certificates: cNil1 is not equal to cNil2")
458	}
459	if !cNil2.Equal(cNil1) {
460		t.Error("Nil certificates: cNil2 is not equal to cNil1")
461	}
462	if cNil1.Equal(cNonNil) {
463		t.Error("Unexpectedly cNil1 is equal to cNonNil")
464	}
465	if cNonNil.Equal(cNil1) {
466		t.Error("Unexpectedly cNonNil is equal to cNil1")
467	}
468}
469
470func TestMismatchedSignatureAlgorithm(t *testing.T) {
471	der, _ := pem.Decode([]byte(rsaPSSSelfSignedPEM))
472	if der == nil {
473		t.Fatal("Failed to find PEM block")
474	}
475
476	cert, err := ParseCertificate(der.Bytes)
477	if err != nil {
478		t.Fatal(err)
479	}
480
481	if err = cert.CheckSignature(ECDSAWithSHA256, nil, nil); err == nil {
482		t.Fatal("CheckSignature unexpectedly return no error")
483	}
484
485	const expectedSubstring = " but have public key of type "
486	if !strings.Contains(err.Error(), expectedSubstring) {
487		t.Errorf("Expected error containing %q, but got %q", expectedSubstring, err)
488	}
489}
490
491var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" +
492	"f70d0101050500304c310b3009060355040613025a4131253023060355040a131c546861777465" +
493	"20436f6e73756c74696e67202850747929204c74642e311630140603550403130d546861777465" +
494	"20534743204341301e170d3039303332353136343932395a170d3130303332353136343932395a" +
495	"3069310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630" +
496	"140603550407130d4d6f756e7461696e205669657731133011060355040a130a476f6f676c6520" +
497	"496e63311830160603550403130f6d61696c2e676f6f676c652e636f6d30819f300d06092a8648" +
498	"86f70d010101050003818d0030818902818100c5d6f892fccaf5614b064149e80a2c9581a218ef" +
499	"41ec35bd7a58125ae76f9ea54ddc893abbeb029f6b73616bf0ffd868791fba7af9c4aebf3706ba" +
500	"3eeaeed27435b4ddcfb157c05f351d66aa87fee0de072d66d773affbd36ab78bef090e0cc861a9" +
501	"03ac90dd98b51c9c41566c017f0beec3bff391051ffba0f5cc6850ad2a590203010001a381e730" +
502	"81e430280603551d250421301f06082b0601050507030106082b06010505070302060960864801" +
503	"86f842040130360603551d1f042f302d302ba029a0278625687474703a2f2f63726c2e74686177" +
504	"74652e636f6d2f54686177746553474343412e63726c307206082b060105050701010466306430" +
505	"2206082b060105050730018616687474703a2f2f6f6373702e7468617774652e636f6d303e0608" +
506	"2b060105050730028632687474703a2f2f7777772e7468617774652e636f6d2f7265706f736974" +
507	"6f72792f5468617774655f5347435f43412e637274300c0603551d130101ff04023000300d0609" +
508	"2a864886f70d01010505000381810062f1f3050ebc105e497c7aedf87e24d2f4a986bb3b837bd1" +
509	"9b91ebcad98b065992f6bd2b49b7d6d3cb2e427a99d606c7b1d46352527fac39e6a8b6726de5bf" +
510	"70212a52cba07634a5e332011bd1868e78eb5e3c93cf03072276786f207494feaa0ed9d53b2110" +
511	"a76571f90209cdae884385c882587030ee15f33d761e2e45a6bc308203233082028ca003020102" +
512	"020430000002300d06092a864886f70d0101050500305f310b3009060355040613025553311730" +
513	"15060355040a130e566572695369676e2c20496e632e31373035060355040b132e436c61737320" +
514	"33205075626c6963205072696d6172792043657274696669636174696f6e20417574686f726974" +
515	"79301e170d3034303531333030303030305a170d3134303531323233353935395a304c310b3009" +
516	"060355040613025a4131253023060355040a131c54686177746520436f6e73756c74696e672028" +
517	"50747929204c74642e311630140603550403130d5468617774652053474320434130819f300d06" +
518	"092a864886f70d010101050003818d0030818902818100d4d367d08d157faecd31fe7d1d91a13f" +
519	"0b713cacccc864fb63fc324b0794bd6f80ba2fe10493c033fc093323e90b742b71c403c6d2cde2" +
520	"2ff50963cdff48a500bfe0e7f388b72d32de9836e60aad007bc4644a3b847503f270927d0e62f5" +
521	"21ab693684317590f8bfc76c881b06957cc9e5a8de75a12c7a68dfd5ca1c875860190203010001" +
522	"a381fe3081fb30120603551d130101ff040830060101ff020100300b0603551d0f040403020106" +
523	"301106096086480186f842010104040302010630280603551d110421301fa41d301b3119301706" +
524	"035504031310507269766174654c6162656c332d313530310603551d1f042a30283026a024a022" +
525	"8620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c303206082b" +
526	"0601050507010104263024302206082b060105050730018616687474703a2f2f6f6373702e7468" +
527	"617774652e636f6d30340603551d25042d302b06082b0601050507030106082b06010505070302" +
528	"06096086480186f8420401060a6086480186f845010801300d06092a864886f70d010105050003" +
529	"81810055ac63eadea1ddd2905f9f0bce76be13518f93d9052bc81b774bad6950a1eededcfddb07" +
530	"e9e83994dcab72792f06bfab8170c4a8edea5334edef1e53d906c7562bd15cf4d18a8eb42bb137" +
531	"9048084225c53e8acb7feb6f04d16dc574a2f7a27c7b603c77cd0ece48027f012fb69b37e02a2a" +
532	"36dcd585d6ace53f546f961e05af"
533
534func parseCIDR(s string) *net.IPNet {
535	_, net, err := net.ParseCIDR(s)
536	if err != nil {
537		panic(err)
538	}
539	return net
540}
541
542func parseURI(s string) *url.URL {
543	uri, err := url.Parse(s)
544	if err != nil {
545		panic(err)
546	}
547	return uri
548}
549
550func TestCreateSelfSignedCertificate(t *testing.T) {
551	random := rand.Reader
552
553	ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
554	if err != nil {
555		t.Fatalf("Failed to generate ECDSA key: %s", err)
556	}
557
558	ed25519Pub, ed25519Priv, err := ed25519.GenerateKey(random)
559	if err != nil {
560		t.Fatalf("Failed to generate Ed25519 key: %s", err)
561	}
562
563	tests := []struct {
564		name      string
565		pub, priv interface{}
566		checkSig  bool
567		sigAlgo   SignatureAlgorithm
568	}{
569		{"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, SHA1WithRSA},
570		{"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
571		{"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA},
572		{"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1},
573		{"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, SHA256WithRSAPSS},
574		{"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS},
575		{"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
576		{"Ed25519", ed25519Pub, ed25519Priv, true, PureEd25519},
577	}
578
579	testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth}
580	testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
581	extraExtensionData := []byte("extra extension")
582
583	for _, test := range tests {
584		commonName := "test.example.com"
585		template := Certificate{
586			// SerialNumber is negative to ensure that negative
587			// values are parsed. This is due to the prevalence of
588			// buggy code that produces certificates with negative
589			// serial numbers.
590			SerialNumber: big.NewInt(-1),
591			Subject: pkix.Name{
592				CommonName:   commonName,
593				Organization: []string{"Σ Acme Co"},
594				Country:      []string{"US"},
595				ExtraNames: []pkix.AttributeTypeAndValue{
596					{
597						Type:  []int{2, 5, 4, 42},
598						Value: "Gopher",
599					},
600					// This should override the Country, above.
601					{
602						Type:  []int{2, 5, 4, 6},
603						Value: "NL",
604					},
605				},
606			},
607			NotBefore: time.Unix(1000, 0),
608			NotAfter:  time.Unix(100000, 0),
609
610			SignatureAlgorithm: test.sigAlgo,
611
612			SubjectKeyId: []byte{1, 2, 3, 4},
613			KeyUsage:     KeyUsageCertSign,
614
615			ExtKeyUsage:        testExtKeyUsage,
616			UnknownExtKeyUsage: testUnknownExtKeyUsage,
617
618			BasicConstraintsValid: true,
619			IsCA:                  true,
620
621			OCSPServer:            []string{"http://ocsp.example.com"},
622			IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"},
623
624			DNSNames:       []string{"test.example.com"},
625			EmailAddresses: []string{"gopher@golang.org"},
626			IPAddresses:    []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
627			URIs:           []*url.URL{parseURI("https://foo.com/wibble#foo")},
628
629			PolicyIdentifiers:       []asn1.ObjectIdentifier{[]int{1, 2, 3}},
630			PermittedDNSDomains:     []string{".example.com", "example.com"},
631			ExcludedDNSDomains:      []string{"bar.example.com"},
632			PermittedIPRanges:       []*net.IPNet{parseCIDR("192.168.1.1/16"), parseCIDR("1.2.3.4/8")},
633			ExcludedIPRanges:        []*net.IPNet{parseCIDR("2001:db8::/48")},
634			PermittedEmailAddresses: []string{"foo@example.com"},
635			ExcludedEmailAddresses:  []string{".example.com", "example.com"},
636			PermittedURIDomains:     []string{".bar.com", "bar.com"},
637			ExcludedURIDomains:      []string{".bar2.com", "bar2.com"},
638
639			CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
640
641			ExtraExtensions: []pkix.Extension{
642				{
643					Id:    []int{1, 2, 3, 4},
644					Value: extraExtensionData,
645				},
646				// This extension should override the SubjectKeyId, above.
647				{
648					Id:       oidExtensionSubjectKeyId,
649					Critical: false,
650					Value:    []byte{0x04, 0x04, 4, 3, 2, 1},
651				},
652			},
653		}
654
655		derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv)
656		if err != nil {
657			t.Errorf("%s: failed to create certificate: %s", test.name, err)
658			continue
659		}
660
661		cert, err := ParseCertificate(derBytes)
662		if err != nil {
663			t.Errorf("%s: failed to parse certificate: %s", test.name, err)
664			continue
665		}
666
667		if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) {
668			t.Errorf("%s: failed to parse policy identifiers: got:%#v want:%#v", test.name, cert.PolicyIdentifiers, template.PolicyIdentifiers)
669		}
670
671		if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" {
672			t.Errorf("%s: failed to parse name constraints: %#v", test.name, cert.PermittedDNSDomains)
673		}
674
675		if len(cert.ExcludedDNSDomains) != 1 || cert.ExcludedDNSDomains[0] != "bar.example.com" {
676			t.Errorf("%s: failed to parse name constraint exclusions: %#v", test.name, cert.ExcludedDNSDomains)
677		}
678
679		if len(cert.PermittedIPRanges) != 2 || cert.PermittedIPRanges[0].String() != "192.168.0.0/16" || cert.PermittedIPRanges[1].String() != "1.0.0.0/8" {
680			t.Errorf("%s: failed to parse IP constraints: %#v", test.name, cert.PermittedIPRanges)
681		}
682
683		if len(cert.ExcludedIPRanges) != 1 || cert.ExcludedIPRanges[0].String() != "2001:db8::/48" {
684			t.Errorf("%s: failed to parse IP constraint exclusions: %#v", test.name, cert.ExcludedIPRanges)
685		}
686
687		if len(cert.PermittedEmailAddresses) != 1 || cert.PermittedEmailAddresses[0] != "foo@example.com" {
688			t.Errorf("%s: failed to parse permitted email addreses: %#v", test.name, cert.PermittedEmailAddresses)
689		}
690
691		if len(cert.ExcludedEmailAddresses) != 2 || cert.ExcludedEmailAddresses[0] != ".example.com" || cert.ExcludedEmailAddresses[1] != "example.com" {
692			t.Errorf("%s: failed to parse excluded email addreses: %#v", test.name, cert.ExcludedEmailAddresses)
693		}
694
695		if len(cert.PermittedURIDomains) != 2 || cert.PermittedURIDomains[0] != ".bar.com" || cert.PermittedURIDomains[1] != "bar.com" {
696			t.Errorf("%s: failed to parse permitted URIs: %#v", test.name, cert.PermittedURIDomains)
697		}
698
699		if len(cert.ExcludedURIDomains) != 2 || cert.ExcludedURIDomains[0] != ".bar2.com" || cert.ExcludedURIDomains[1] != "bar2.com" {
700			t.Errorf("%s: failed to parse excluded URIs: %#v", test.name, cert.ExcludedURIDomains)
701		}
702
703		if cert.Subject.CommonName != commonName {
704			t.Errorf("%s: subject wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Subject.CommonName, commonName)
705		}
706
707		if len(cert.Subject.Country) != 1 || cert.Subject.Country[0] != "NL" {
708			t.Errorf("%s: ExtraNames didn't override Country", test.name)
709		}
710
711		for _, ext := range cert.Extensions {
712			if ext.Id.Equal(oidExtensionSubjectAltName) {
713				if ext.Critical {
714					t.Fatal("SAN extension is marked critical")
715				}
716			}
717		}
718
719		found := false
720		for _, atv := range cert.Subject.Names {
721			if atv.Type.Equal([]int{2, 5, 4, 42}) {
722				found = true
723				break
724			}
725		}
726		if !found {
727			t.Errorf("%s: Names didn't contain oid 2.5.4.42 from ExtraNames", test.name)
728		}
729
730		if cert.Issuer.CommonName != commonName {
731			t.Errorf("%s: issuer wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Issuer.CommonName, commonName)
732		}
733
734		if cert.SignatureAlgorithm != test.sigAlgo {
735			t.Errorf("%s: SignatureAlgorithm wasn't copied from template. Got %v, want %v", test.name, cert.SignatureAlgorithm, test.sigAlgo)
736		}
737
738		if !reflect.DeepEqual(cert.ExtKeyUsage, testExtKeyUsage) {
739			t.Errorf("%s: extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.ExtKeyUsage, testExtKeyUsage)
740		}
741
742		if !reflect.DeepEqual(cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) {
743			t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage)
744		}
745
746		if !reflect.DeepEqual(cert.OCSPServer, template.OCSPServer) {
747			t.Errorf("%s: OCSP servers differ from template. Got %v, want %v", test.name, cert.OCSPServer, template.OCSPServer)
748		}
749
750		if !reflect.DeepEqual(cert.IssuingCertificateURL, template.IssuingCertificateURL) {
751			t.Errorf("%s: Issuing certificate URLs differ from template. Got %v, want %v", test.name, cert.IssuingCertificateURL, template.IssuingCertificateURL)
752		}
753
754		if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) {
755			t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames)
756		}
757
758		if !reflect.DeepEqual(cert.EmailAddresses, template.EmailAddresses) {
759			t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses)
760		}
761
762		if len(cert.URIs) != 1 || cert.URIs[0].String() != "https://foo.com/wibble#foo" {
763			t.Errorf("%s: URIs differ from template. Got %v, want %v", test.name, cert.URIs, template.URIs)
764		}
765
766		if !reflect.DeepEqual(cert.IPAddresses, template.IPAddresses) {
767			t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses)
768		}
769
770		if !reflect.DeepEqual(cert.CRLDistributionPoints, template.CRLDistributionPoints) {
771			t.Errorf("%s: CRL distribution points differ from template. Got %v, want %v", test.name, cert.CRLDistributionPoints, template.CRLDistributionPoints)
772		}
773
774		if !bytes.Equal(cert.SubjectKeyId, []byte{4, 3, 2, 1}) {
775			t.Errorf("%s: ExtraExtensions didn't override SubjectKeyId", test.name)
776		}
777
778		if !bytes.Contains(derBytes, extraExtensionData) {
779			t.Errorf("%s: didn't find extra extension in DER output", test.name)
780		}
781
782		if test.checkSig {
783			err = cert.CheckSignatureFrom(cert)
784			if err != nil {
785				t.Errorf("%s: signature verification failed: %s", test.name, err)
786			}
787		}
788	}
789}
790
791// Self-signed certificate using ECDSA with SHA1 & secp256r1
792var ecdsaSHA1CertPem = `
793-----BEGIN CERTIFICATE-----
794MIICDjCCAbUCCQDF6SfN0nsnrjAJBgcqhkjOPQQBMIGPMQswCQYDVQQGEwJVUzET
795MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEVMBMG
796A1UECgwMR29vZ2xlLCBJbmMuMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
797CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIwMjAyMDUw
798WhcNMjIwNTE4MjAyMDUwWjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
799b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTATBgNVBAoMDEdvb2dsZSwg
800SW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAhBgkqhkiG9w0BCQEWFGdv
801bGFuZy1kZXZAZ21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/Wgn
802WQDo5+bz71T0327ERgd5SDDXFbXLpzIZDXTkjpe8QTEbsF+ezsQfrekrpDPC4Cd3
803P9LY0tG+aI8IyVKdUjAJBgcqhkjOPQQBA0gAMEUCIGlsqMcRqWVIWTD6wXwe6Jk2
804DKxL46r/FLgJYnzBEH99AiEA3fBouObsvV1R3oVkb4BQYnD4/4LeId6lAT43YvyV
805a/A=
806-----END CERTIFICATE-----
807`
808
809// Self-signed certificate using ECDSA with SHA256 & secp256r1
810var ecdsaSHA256p256CertPem = `
811-----BEGIN CERTIFICATE-----
812MIICDzCCAbYCCQDlsuMWvgQzhTAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCVVMx
813EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT
814BgNVBAoMDEdvb2dsZSwgSW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAh
815BgkqhkiG9w0BCQEWFGdvbGFuZy1kZXZAZ21haWwuY29tMB4XDTEyMDUyMTAwMTkx
816NloXDTIyMDUxOTAwMTkxNlowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
817Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYDVQQKDAxHb29nbGUs
818IEluYy4xFzAVBgNVBAMMDnd3dy5nb29nbGUuY29tMSMwIQYJKoZIhvcNAQkBFhRn
819b2xhbmctZGV2QGdtYWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPMt
8202ErhxAty5EJRu9yM+MTy+hUXm3pdW1ensAv382KoGExSXAFWP7pjJnNtHO+XSwVm
821YNtqjcAGFKpweoN//kQwCgYIKoZIzj0EAwIDRwAwRAIgIYSaUA/IB81gjbIw/hUV
82270twxJr5EcgOo0hLp3Jm+EYCIFDO3NNcgmURbJ1kfoS3N/0O+irUtoPw38YoNkqJ
823h5wi
824-----END CERTIFICATE-----
825`
826
827// Self-signed certificate using ECDSA with SHA256 & secp384r1
828var ecdsaSHA256p384CertPem = `
829-----BEGIN CERTIFICATE-----
830MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx
831EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
832BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
833CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0
834WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
835b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
836SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
837YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK
838jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze
839qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI
840zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr
841PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh
8423yILeYQzllt/g0rKVRk=
843-----END CERTIFICATE-----
844`
845
846// Self-signed certificate using ECDSA with SHA384 & secp521r1
847var ecdsaSHA384p521CertPem = `
848-----BEGIN CERTIFICATE-----
849MIICljCCAfcCCQDhp1AFD/ahKjAKBggqhkjOPQQDAzCBjjELMAkGA1UEBhMCVVMx
850EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
851BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
852CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMTUwNDI5
853WhcNMjIwNTE5MTUwNDI5WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
854b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
855SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
856YW5nLWRldkBnbWFpbC5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACqx9Rv
857IssRs1LWYcNN+WffwlHw4Tv3y8/LIAA9MF1ZScIonU9nRMxt4a2uGJVCPDw6JHpz
858PaYc0E9puLoE9AfKpwFr59Jkot7dBg55SKPEFkddoip/rvmN7NPAWjMBirOwjOkm
8598FPthvPhGPqsu9AvgVuHu3PosWiHGNrhh379pva8MzAKBggqhkjOPQQDAwOBjAAw
860gYgCQgEHNmswkUdPpHqrVxp9PvLVl+xxPuHBkT+75z9JizyxtqykHQo9Uh6SWCYH
861BF9KLolo01wMt8DjoYP5Fb3j5MH7xwJCAbWZzTOp4l4DPkIvAh4LeC4VWbwPPyqh
862kBg71w/iEcSY3wUKgHGcJJrObZw7wys91I5kENljqw/Samdr3ka+jBJa
863-----END CERTIFICATE-----
864`
865
866var ecdsaTests = []struct {
867	sigAlgo SignatureAlgorithm
868	pemCert string
869}{
870	{ECDSAWithSHA1, ecdsaSHA1CertPem},
871	{ECDSAWithSHA256, ecdsaSHA256p256CertPem},
872	{ECDSAWithSHA256, ecdsaSHA256p384CertPem},
873	{ECDSAWithSHA384, ecdsaSHA384p521CertPem},
874}
875
876func TestECDSA(t *testing.T) {
877	for i, test := range ecdsaTests {
878		pemBlock, _ := pem.Decode([]byte(test.pemCert))
879		cert, err := ParseCertificate(pemBlock.Bytes)
880		if err != nil {
881			t.Errorf("%d: failed to parse certificate: %s", i, err)
882			continue
883		}
884		if sa := cert.SignatureAlgorithm; sa != test.sigAlgo {
885			t.Errorf("%d: signature algorithm is %v, want %v", i, sa, test.sigAlgo)
886		}
887		if parsedKey, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok {
888			t.Errorf("%d: wanted an ECDSA public key but found: %#v", i, parsedKey)
889		}
890		if pka := cert.PublicKeyAlgorithm; pka != ECDSA {
891			t.Errorf("%d: public key algorithm is %v, want ECDSA", i, pka)
892		}
893		if err = cert.CheckSignatureFrom(cert); err != nil {
894			t.Errorf("%d: certificate verification failed: %s", i, err)
895		}
896	}
897}
898
899// Self-signed certificate using DSA with SHA1
900var dsaCertPem = `-----BEGIN CERTIFICATE-----
901MIIEDTCCA82gAwIBAgIJALHPghaoxeDhMAkGByqGSM44BAMweTELMAkGA1UEBhMC
902VVMxCzAJBgNVBAgTAk5DMQ8wDQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2ds
903ZSwgSW5jMRIwEAYDVQQDEwlKb24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFs
904bGllQGdvb2dsZS5jb20wHhcNMTEwNTE0MDMwMTQ1WhcNMTEwNjEzMDMwMTQ1WjB5
905MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTkMxDzANBgNVBAcTBk5ld3RvbjEUMBIG
906A1UEChMLR29vZ2xlLCBJbmMxEjAQBgNVBAMTCUpvbiBBbGxpZTEiMCAGCSqGSIb3
907DQEJARYTam9uYWxsaWVAZ29vZ2xlLmNvbTCCAbcwggEsBgcqhkjOOAQBMIIBHwKB
908gQC8hLUnQ7FpFYu4WXTj6DKvXvz8QrJkNJCVMTpKAT7uBpobk32S5RrPKXocd4gN
9098lyGB9ggS03EVlEwXvSmO0DH2MQtke2jl9j1HLydClMf4sbx5V6TV9IFw505U1iW
910jL7awRMgxge+FsudtJK254FjMFo03ZnOQ8ZJJ9E6AEDrlwIVAJpnBn9moyP11Ox5
911Asc/5dnjb6dPAoGBAJFHd4KVv1iTVCvEG6gGiYop5DJh28hUQcN9kul+2A0yPUSC
912X93oN00P8Vh3eYgSaCWZsha7zDG53MrVJ0Zf6v/X/CoZNhLldeNOepivTRAzn+Rz
913kKUYy5l1sxYLHQKF0UGNCXfFKZT0PCmgU+PWhYNBBMn6/cIh44vp85ideo5CA4GE
914AAKBgFmifCafzeRaohYKXJgMGSEaggCVCRq5xdyDCat+wbOkjC4mfG01/um3G8u5
915LxasjlWRKTR/tcAL7t0QuokVyQaYdVypZXNaMtx1db7YBuHjj3aP+8JOQRI9xz8c
916bp5NDJ5pISiFOv4p3GZfqZPcqckDt78AtkQrmnal2txhhjF6o4HeMIHbMB0GA1Ud
917DgQWBBQVyyr7hO11ZFFpWX50298Sa3V+rzCBqwYDVR0jBIGjMIGggBQVyyr7hO11
918ZFFpWX50298Sa3V+r6F9pHsweTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5DMQ8w
919DQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2dsZSwgSW5jMRIwEAYDVQQDEwlK
920b24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFsbGllQGdvb2dsZS5jb22CCQCx
921z4IWqMXg4TAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUPtn/5j8Q1jJI
9227ggOIsgrhgUdjGQCFCsmDq1H11q9+9Wp9IMeGrTSKHIM
923-----END CERTIFICATE-----
924`
925
926func TestParseCertificateWithDsaPublicKey(t *testing.T) {
927	expectedKey := &dsa.PublicKey{
928		Parameters: dsa.Parameters{
929			P: bigFromHexString("00BC84B52743B169158BB85974E3E832AF5EFCFC42B264349095313A4A013EEE069A1B937D92E51ACF297A1C77880DF25C8607D8204B4DC45651305EF4A63B40C7D8C42D91EDA397D8F51CBC9D0A531FE2C6F1E55E9357D205C39D395358968CBEDAC11320C607BE16CB9DB492B6E78163305A34DD99CE43C64927D13A0040EB97"),
930			Q: bigFromHexString("009A67067F66A323F5D4EC7902C73FE5D9E36FA74F"),
931			G: bigFromHexString("009147778295BF5893542BC41BA806898A29E43261DBC85441C37D92E97ED80D323D44825FDDE8374D0FF15877798812682599B216BBCC31B9DCCAD527465FEAFFD7FC2A193612E575E34E7A98AF4D10339FE47390A518CB9975B3160B1D0285D1418D0977C52994F43C29A053E3D685834104C9FAFDC221E38BE9F3989D7A8E42"),
932		},
933		Y: bigFromHexString("59A27C269FCDE45AA2160A5C980C19211A820095091AB9C5DC8309AB7EC1B3A48C2E267C6D35FEE9B71BCBB92F16AC8E559129347FB5C00BEEDD10BA8915C90698755CA965735A32DC7575BED806E1E38F768FFBC24E41123DC73F1C6E9E4D0C9E692128853AFE29DC665FA993DCA9C903B7BF00B6442B9A76A5DADC6186317A"),
934	}
935	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
936	cert, err := ParseCertificate(pemBlock.Bytes)
937	if err != nil {
938		t.Fatalf("Failed to parse certificate: %s", err)
939	}
940	if cert.PublicKeyAlgorithm != DSA {
941		t.Errorf("Parsed key algorithm was not DSA")
942	}
943	parsedKey, ok := cert.PublicKey.(*dsa.PublicKey)
944	if !ok {
945		t.Fatalf("Parsed key was not a DSA key: %s", err)
946	}
947	if expectedKey.Y.Cmp(parsedKey.Y) != 0 ||
948		expectedKey.P.Cmp(parsedKey.P) != 0 ||
949		expectedKey.Q.Cmp(parsedKey.Q) != 0 ||
950		expectedKey.G.Cmp(parsedKey.G) != 0 {
951		t.Fatal("Parsed key differs from expected key")
952	}
953}
954
955func TestParseCertificateWithDSASignatureAlgorithm(t *testing.T) {
956	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
957	cert, err := ParseCertificate(pemBlock.Bytes)
958	if err != nil {
959		t.Fatalf("Failed to parse certificate: %s", err)
960	}
961	if cert.SignatureAlgorithm != DSAWithSHA1 {
962		t.Errorf("Parsed signature algorithm was not DSAWithSHA1")
963	}
964}
965
966func TestVerifyCertificateWithDSASignature(t *testing.T) {
967	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
968	cert, err := ParseCertificate(pemBlock.Bytes)
969	if err != nil {
970		t.Fatalf("Failed to parse certificate: %s", err)
971	}
972	// test cert is self-signed
973	if err = cert.CheckSignatureFrom(cert); err != nil {
974		t.Fatalf("DSA Certificate verification failed: %s", err)
975	}
976}
977
978const dsaCert1024WithSha256 = `-----BEGIN CERTIFICATE-----
979MIIDKzCCAumgAwIBAgIUOXWPK4gTRZVVY7OSXTU00QEWQU8wCwYJYIZIAWUDBAMC
980MEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJ
981bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMTkxMDAxMDYxODUyWhgPMzAxOTAy
982MDEwNjE4NTJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
983HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggG4MIIBLAYHKoZIzjgE
984ATCCAR8CgYEAr79m/1ypU1aUbbLX1jikTyX7w2QYP+EkxNtXUiiTuxkC1KBqqxT3
9850Aht2vxFR47ODEK4B79rHO+UevhaqDaAHSH7Z/9umS0h0aS32KLDLb+LI5AneCrn
986eW5YbVhfD03N7uR4kKUCKOnWj5hAk9xiE3y7oFR0bBXzqrrHJF9LMd0CFQCB6lSj
987HSW0rGmNxIZsBl72u7JFLQKBgQCOFd1PGEQmddn0cdFgby5QQfjrqmoD1zNlFZEt
988L0x1EbndFwelLlF1ChNh3NPNUkjwRbla07FDlONs1GMJq6w4vW11ns+pUvAZ2+RM
989EVFjugip8az2ncn3UujGTVdFxnSTLBsRlMP/tFDK3ky//8zn/5ha9SKKw4v1uv6M
990JuoIbwOBhQACgYEAoeKeR90nwrnoPi5MOUPBLQvuzB87slfr+3kL8vFCmgjA6MtB
9917TxQKoBTOo5aVgWDp0lMIMxLd6btzBrm6r3VdRlh/cL8/PtbxkFwBa+Upe4o5NAh
992ISCe2/f2leT1PxtF8xxYjz/fszeUeHsJbVMilE2cuB2SYrR5tMExiqy+QpqjUzBR
993MB0GA1UdDgQWBBQDMIEL8Z3jc1d9wCxWtksUWc8RkjAfBgNVHSMEGDAWgBQDMIEL
9948Z3jc1d9wCxWtksUWc8RkjAPBgNVHRMBAf8EBTADAQH/MAsGCWCGSAFlAwQDAgMv
995ADAsAhQFehZgI4OyKBGpfnXvyJ0Z/0a6nAIUTO265Ane87LfJuQr3FrqvuCI354=
996-----END CERTIFICATE-----
997`
998
999func TestVerifyCertificateWithDSATooLongHash(t *testing.T) {
1000	pemBlock, _ := pem.Decode([]byte(dsaCert1024WithSha256))
1001	cert, err := ParseCertificate(pemBlock.Bytes)
1002	if err != nil {
1003		t.Fatalf("Failed to parse certificate: %s", err)
1004	}
1005
1006	// test cert is self-signed
1007	if err = cert.CheckSignatureFrom(cert); err != nil {
1008		t.Fatalf("DSA Certificate self-signature verification failed: %s", err)
1009	}
1010
1011	signed := []byte("A wild Gopher appears!\n")
1012	signature, _ := hex.DecodeString("302c0214417aca7ff458f5b566e43e7b82f994953da84be50214625901e249e33f4e4838f8b5966020c286dd610e")
1013
1014	// This signature is using SHA256, but only has 1024 DSA key. The hash has to be truncated
1015	// in CheckSignature, otherwise it won't pass.
1016	if err = cert.CheckSignature(DSAWithSHA256, signed, signature); err != nil {
1017		t.Fatalf("DSA signature verification failed: %s", err)
1018	}
1019}
1020
1021var rsaPSSSelfSignedPEM = `-----BEGIN CERTIFICATE-----
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
1055-----END CERTIFICATE-----`
1056
1057// openssl req -newkey rsa:2048 -keyout test.key -sha256 -sigopt \
1058// rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 -sigopt rsa_mgf1_md:sha256 \
1059// -x509 -days 3650 -nodes -subj '/C=US/ST=CA/L=SF/O=Test/CN=Test' -out \
1060// test.pem
1061var rsaPSSSelfSignedOpenSSL110PEM = `-----BEGIN CERTIFICATE-----
1062MIIDwDCCAnigAwIBAgIJAM9LAMHTE5xpMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZI
1063AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgMEUxCzAJBgNV
1064BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDTALBgNVBAoMBFRlc3Qx
1065DTALBgNVBAMMBFRlc3QwHhcNMTgwMjIyMjIxMzE4WhcNMjgwMjIwMjIxMzE4WjBF
1066MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMQ0wCwYDVQQK
1067DARUZXN0MQ0wCwYDVQQDDARUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
1068CgKCAQEA4Zrsydod+GoTAJLLutWNF87qhhVPBsK1zB1Gj+NAAe4+VbrZ1E41H1wp
1069qITx7DA8DRtJEf+NqrTAnAdZWBG/tAOA5LfXVax0ZSQtLnYLSeylLoMtDyY3eFAj
1070TmuTOoyVy6raktowCnHCh01NsstqqTfrx6SbmzOmDmKTkq/I+7K0MCVsn41xRDVM
1071+ShD0WGFGioEGoiWnFSWupxJDA3Q6jIDEygVwNKHwnhv/2NgG2kqZzrZSQA67en0
1072iKAXtoDNPpmyD5oS9YbEJ+2Nbm7oLeON30i6kZvXKIzJXx+UWViazHZqnsi5rQ8G
1073RHF+iVFXsqd0MzDKmkKOT5FDhrsbKQIDAQABo1MwUTAdBgNVHQ4EFgQU9uFY/nlg
1074gLH00NBnr/o7QvpN9ugwHwYDVR0jBBgwFoAU9uFY/nlggLH00NBnr/o7QvpN9ugw
1075DwYDVR0TAQH/BAUwAwEB/zA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEa
1076MBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIAOCAQEAhJzpwxBNGKvzKWDe
1077WLqv6RMrl/q4GcH3b7M9wjxe0yOm4F+Tb2zJ7re4h+D39YkJf8cX1NV9UQVu6z4s
1078Fvo2kmlR0qZOXAg5augmCQ1xS0WHFoF6B52anNzHkZQbAIYJ3kGoFsUHzs7Sz7F/
1079656FsRpHA9UzJQ3avPPMrA4Y4aoJ7ANJ6XIwTrdWrhULOVuvYRLCl4CdTVztVFX6
1080wxX8nS1ISYd8jXPUMgsBKVbWufvLoIymMJW8CZbpprVZel5zFn0bmPrON8IHS30w
1081Gs+ITJjKEnZgXmAQ25SLKVzkZkBcGANs2GsdHNJ370Puisy0FIPD2NXR5uASAf7J
1082+w9fjQ==
1083-----END CERTIFICATE-----`
1084
1085func TestRSAPSSSelfSigned(t *testing.T) {
1086	for i, pemBlock := range []string{rsaPSSSelfSignedPEM, rsaPSSSelfSignedOpenSSL110PEM} {
1087		der, _ := pem.Decode([]byte(pemBlock))
1088		if der == nil {
1089			t.Errorf("#%d: failed to find PEM block", i)
1090			continue
1091		}
1092
1093		cert, err := ParseCertificate(der.Bytes)
1094		if err != nil {
1095			t.Errorf("#%d: failed to parse: %s", i, err)
1096			continue
1097		}
1098
1099		if err = cert.CheckSignatureFrom(cert); err != nil {
1100			t.Errorf("#%d: signature check failed: %s", i, err)
1101			continue
1102		}
1103	}
1104}
1105
1106const ed25519Certificate = `
1107Certificate:
1108    Data:
1109        Version: 3 (0x2)
1110        Serial Number:
1111            0c:83:d8:21:2b:82:cb:23:98:23:63:e2:f7:97:8a:43:5b:f3:bd:92
1112        Signature Algorithm: ED25519
1113        Issuer: CN = Ed25519 test certificate
1114        Validity
1115            Not Before: May  6 17:27:16 2019 GMT
1116            Not After : Jun  5 17:27:16 2019 GMT
1117        Subject: CN = Ed25519 test certificate
1118        Subject Public Key Info:
1119            Public Key Algorithm: ED25519
1120                ED25519 Public-Key:
1121                pub:
1122                    36:29:c5:6c:0d:4f:14:6c:81:d0:ff:75:d3:6a:70:
1123                    5f:69:cd:0f:4d:66:d5:da:98:7e:82:49:89:a3:8a:
1124                    3c:fa
1125        X509v3 extensions:
1126            X509v3 Subject Key Identifier:
1127                09:3B:3A:9D:4A:29:D8:95:FF:68:BE:7B:43:54:72:E0:AD:A2:E3:AE
1128            X509v3 Authority Key Identifier:
1129                keyid:09:3B:3A:9D:4A:29:D8:95:FF:68:BE:7B:43:54:72:E0:AD:A2:E3:AE
1130
1131            X509v3 Basic Constraints: critical
1132                CA:TRUE
1133    Signature Algorithm: ED25519
1134         53:a5:58:1c:2c:3b:2a:9e:ac:9d:4e:a5:1d:5f:5d:6d:a6:b5:
1135         08:de:12:82:f3:97:20:ae:fa:d8:98:f4:1a:83:32:6b:91:f5:
1136         24:1d:c4:20:7f:2c:e2:4d:da:13:3b:6d:54:1a:d2:a8:28:dc:
1137         60:b9:d4:f4:78:4b:3c:1c:91:00
1138-----BEGIN CERTIFICATE-----
1139MIIBWzCCAQ2gAwIBAgIUDIPYISuCyyOYI2Pi95eKQ1vzvZIwBQYDK2VwMCMxITAf
1140BgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZpY2F0ZTAeFw0xOTA1MDYxNzI3MTZa
1141Fw0xOTA2MDUxNzI3MTZaMCMxITAfBgNVBAMMGEVkMjU1MTkgdGVzdCBjZXJ0aWZp
1142Y2F0ZTAqMAUGAytlcAMhADYpxWwNTxRsgdD/ddNqcF9pzQ9NZtXamH6CSYmjijz6
1143o1MwUTAdBgNVHQ4EFgQUCTs6nUop2JX/aL57Q1Ry4K2i464wHwYDVR0jBBgwFoAU
1144CTs6nUop2JX/aL57Q1Ry4K2i464wDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXADQQBT
1145pVgcLDsqnqydTqUdX11tprUI3hKC85cgrvrYmPQagzJrkfUkHcQgfyziTdoTO21U
1146GtKoKNxgudT0eEs8HJEA
1147-----END CERTIFICATE-----`
1148
1149func TestEd25519SelfSigned(t *testing.T) {
1150	der, _ := pem.Decode([]byte(ed25519Certificate))
1151	if der == nil {
1152		t.Fatalf("Failed to find PEM block")
1153	}
1154
1155	cert, err := ParseCertificate(der.Bytes)
1156	if err != nil {
1157		t.Fatalf("Failed to parse: %s", err)
1158	}
1159
1160	if cert.PublicKeyAlgorithm != Ed25519 {
1161		t.Fatalf("Parsed key algorithm was not Ed25519")
1162	}
1163	parsedKey, ok := cert.PublicKey.(ed25519.PublicKey)
1164	if !ok {
1165		t.Fatalf("Parsed key was not an Ed25519 key: %s", err)
1166	}
1167	if len(parsedKey) != ed25519.PublicKeySize {
1168		t.Fatalf("Invalid Ed25519 key")
1169	}
1170
1171	if err = cert.CheckSignatureFrom(cert); err != nil {
1172		t.Fatalf("Signature check failed: %s", err)
1173	}
1174}
1175
1176const pemCertificate = `-----BEGIN CERTIFICATE-----
1177MIIDATCCAemgAwIBAgIRAKQkkrFx1T/dgB/Go/xBM5swDQYJKoZIhvcNAQELBQAw
1178EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjA4MTcyMDM2MDdaFw0xNzA4MTcyMDM2
1179MDdaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
1180ggEKAoIBAQDAoJtjG7M6InsWwIo+l3qq9u+g2rKFXNu9/mZ24XQ8XhV6PUR+5HQ4
1181jUFWC58ExYhottqK5zQtKGkw5NuhjowFUgWB/VlNGAUBHtJcWR/062wYrHBYRxJH
1182qVXOpYKbIWwFKoXu3hcpg/CkdOlDWGKoZKBCwQwUBhWE7MDhpVdQ+ZljUJWL+FlK
1183yQK5iRsJd5TGJ6VUzLzdT4fmN2DzeK6GLeyMpVpU3sWV90JJbxWQ4YrzkKzYhMmB
1184EcpXTG2wm+ujiHU/k2p8zlf8Sm7VBM/scmnMFt0ynNXop4FWvJzEm1G0xD2t+e2I
11855Utr04dOZPCgkm++QJgYhtZvgW7ZZiGTAgMBAAGjUjBQMA4GA1UdDwEB/wQEAwIF
1186oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBsGA1UdEQQUMBKC
1187EHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBADpqKQxrthH5InC7
1188X96UP0OJCu/lLEMkrjoEWYIQaFl7uLPxKH5AmQPH4lYwF7u7gksR7owVG9QU9fs6
11891fK7II9CVgCd/4tZ0zm98FmU4D0lHGtPARrrzoZaqVZcAvRnFTlPX5pFkPhVjjai
1190/mkxX9LpD8oK1445DFHxK5UjLMmPIIWd8EOi+v5a+hgGwnJpoW7hntSl8kHMtTmy
1191fnnktsblSUV4lRCit0ymC7Ojhe+gzCCwkgs5kDzVVag+tnl/0e2DloIjASwOhpbH
1192KVcg7fBd484ht/sS+l0dsB4KDOSpd8JzVDMF8OZqlaydizoJO0yWr9GbCN1+OKq5
1193EhLrEqU=
1194-----END CERTIFICATE-----`
1195
1196const ed25519CRLCertificate = `
1197Certificate:
1198Data:
1199	Version: 3 (0x2)
1200	Serial Number:
1201		7a:07:a0:9d:14:04:16:fc:1f:d8:e5:fe:d1:1d:1f:8d
1202	Signature Algorithm: ED25519
1203	Issuer: CN = Ed25519 CRL Test CA
1204	Validity
1205		Not Before: Oct 30 01:20:20 2019 GMT
1206		Not After : Dec 31 23:59:59 9999 GMT
1207	Subject: CN = Ed25519 CRL Test CA
1208	Subject Public Key Info:
1209		Public Key Algorithm: ED25519
1210			ED25519 Public-Key:
1211			pub:
1212				95:73:3b:b0:06:2a:31:5a:b6:a7:a6:6e:ef:71:df:
1213				ac:6f:6b:39:03:85:5e:63:4b:f8:a6:0f:68:c6:6f:
1214				75:21
1215	X509v3 extensions:
1216		X509v3 Key Usage: critical
1217			Digital Signature, Certificate Sign, CRL Sign
1218		X509v3 Extended Key Usage:
1219			TLS Web Client Authentication, TLS Web Server Authentication, OCSP Signing
1220		X509v3 Basic Constraints: critical
1221			CA:TRUE
1222		X509v3 Subject Key Identifier:
1223			B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
1224		X509v3 Authority Key Identifier:
1225			keyid:B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
1226
1227Signature Algorithm: ED25519
1228	 fc:3e:14:ea:bb:70:c2:6f:38:34:70:bc:c8:a7:f4:7c:0d:1e:
1229	 28:d7:2a:9f:22:8a:45:e8:02:76:84:1e:2d:64:2d:1e:09:b5:
1230	 29:71:1f:95:8a:4e:79:87:51:60:9a:e7:86:40:f6:60:c7:d1:
1231	 ee:68:76:17:1d:90:cc:92:93:07
1232-----BEGIN CERTIFICATE-----
1233MIIBijCCATygAwIBAgIQegegnRQEFvwf2OX+0R0fjTAFBgMrZXAwHjEcMBoGA1UE
1234AxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAgFw0xOTEwMzAwMTIwMjBaGA85OTk5MTIz
1235MTIzNTk1OVowHjEcMBoGA1UEAxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAqMAUGAytl
1236cAMhAJVzO7AGKjFatqembu9x36xvazkDhV5jS/imD2jGb3Uho4GNMIGKMA4GA1Ud
1237DwEB/wQEAwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUF
1238BwMJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLcX2hbqxe0fGElE09LjoDUK
1239gZNgMB8GA1UdIwQYMBaAFLcX2hbqxe0fGElE09LjoDUKgZNgMAUGAytlcANBAPw+
1240FOq7cMJvODRwvMin9HwNHijXKp8iikXoAnaEHi1kLR4JtSlxH5WKTnmHUWCa54ZA
12419mDH0e5odhcdkMySkwc=
1242-----END CERTIFICATE-----`
1243
1244const ed25519CRLKey = `-----BEGIN PRIVATE KEY-----
1245MC4CAQAwBQYDK2VwBCIEINdKh2096vUBYu4EIFpjShsUSh3vimKya1sQ1YTT4RZG
1246-----END PRIVATE KEY-----`
1247
1248func TestCRLCreation(t *testing.T) {
1249	block, _ := pem.Decode([]byte(pemPrivateKey))
1250	privRSA, _ := ParsePKCS1PrivateKey(block.Bytes)
1251	block, _ = pem.Decode([]byte(pemCertificate))
1252	certRSA, _ := ParseCertificate(block.Bytes)
1253
1254	block, _ = pem.Decode([]byte(ed25519CRLKey))
1255	privEd25519, _ := ParsePKCS8PrivateKey(block.Bytes)
1256	block, _ = pem.Decode([]byte(ed25519CRLCertificate))
1257	certEd25519, _ := ParseCertificate(block.Bytes)
1258
1259	tests := []struct {
1260		name string
1261		priv interface{}
1262		cert *Certificate
1263	}{
1264		{"RSA CA", privRSA, certRSA},
1265		{"Ed25519 CA", privEd25519, certEd25519},
1266	}
1267
1268	loc := time.FixedZone("Oz/Atlantis", int((2 * time.Hour).Seconds()))
1269
1270	now := time.Unix(1000, 0).In(loc)
1271	nowUTC := now.UTC()
1272	expiry := time.Unix(10000, 0)
1273
1274	revokedCerts := []pkix.RevokedCertificate{
1275		{
1276			SerialNumber:   big.NewInt(1),
1277			RevocationTime: nowUTC,
1278		},
1279		{
1280			SerialNumber: big.NewInt(42),
1281			// RevocationTime should be converted to UTC before marshaling.
1282			RevocationTime: now,
1283		},
1284	}
1285	expectedCerts := []pkix.RevokedCertificate{
1286		{
1287			SerialNumber:   big.NewInt(1),
1288			RevocationTime: nowUTC,
1289		},
1290		{
1291			SerialNumber:   big.NewInt(42),
1292			RevocationTime: nowUTC,
1293		},
1294	}
1295
1296	for _, test := range tests {
1297		crlBytes, err := test.cert.CreateCRL(rand.Reader, test.priv, revokedCerts, now, expiry)
1298		if err != nil {
1299			t.Errorf("%s: error creating CRL: %s", test.name, err)
1300		}
1301
1302		parsedCRL, err := ParseDERCRL(crlBytes)
1303		if err != nil {
1304			t.Errorf("%s: error reparsing CRL: %s", test.name, err)
1305		}
1306		if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) {
1307			t.Errorf("%s: RevokedCertificates mismatch: got %v; want %v.", test.name,
1308				parsedCRL.TBSCertList.RevokedCertificates, expectedCerts)
1309		}
1310	}
1311}
1312
1313func fromBase64(in string) []byte {
1314	out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
1315	n, err := base64.StdEncoding.Decode(out, []byte(in))
1316	if err != nil {
1317		panic("failed to base64 decode")
1318	}
1319	return out[:n]
1320}
1321
1322func TestParseDERCRL(t *testing.T) {
1323	derBytes := fromBase64(derCRLBase64)
1324	certList, err := ParseDERCRL(derBytes)
1325	if err != nil {
1326		t.Errorf("error parsing: %s", err)
1327		return
1328	}
1329	numCerts := len(certList.TBSCertList.RevokedCertificates)
1330	expected := 88
1331	if numCerts != expected {
1332		t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
1333	}
1334
1335	if certList.HasExpired(time.Unix(1302517272, 0)) {
1336		t.Errorf("CRL has expired (but shouldn't have)")
1337	}
1338
1339	// Can't check the signature here without a package cycle.
1340}
1341
1342func TestCRLWithoutExpiry(t *testing.T) {
1343	derBytes := fromBase64("MIHYMIGZMAkGByqGSM44BAMwEjEQMA4GA1UEAxMHQ2FybERTUxcNOTkwODI3MDcwMDAwWjBpMBMCAgDIFw05OTA4MjIwNzAwMDBaMBMCAgDJFw05OTA4MjIwNzAwMDBaMBMCAgDTFw05OTA4MjIwNzAwMDBaMBMCAgDSFw05OTA4MjIwNzAwMDBaMBMCAgDUFw05OTA4MjQwNzAwMDBaMAkGByqGSM44BAMDLwAwLAIUfmVSdjP+NHMX0feW+aDU2G1cfT0CFAJ6W7fVWxjBz4fvftok8yqDnDWh")
1344	certList, err := ParseDERCRL(derBytes)
1345	if err != nil {
1346		t.Fatal(err)
1347	}
1348	if !certList.TBSCertList.NextUpdate.IsZero() {
1349		t.Errorf("NextUpdate is not the zero value")
1350	}
1351}
1352
1353func TestParsePEMCRL(t *testing.T) {
1354	pemBytes := fromBase64(pemCRLBase64)
1355	certList, err := ParseCRL(pemBytes)
1356	if err != nil {
1357		t.Errorf("error parsing: %s", err)
1358		return
1359	}
1360	numCerts := len(certList.TBSCertList.RevokedCertificates)
1361	expected := 2
1362	if numCerts != expected {
1363		t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
1364	}
1365
1366	if certList.HasExpired(time.Unix(1302517272, 0)) {
1367		t.Errorf("CRL has expired (but shouldn't have)")
1368	}
1369
1370	// Can't check the signature here without a package cycle.
1371}
1372
1373func TestImports(t *testing.T) {
1374	if testing.Short() {
1375		t.Skip("skipping in -short mode")
1376	}
1377	testenv.MustHaveGoRun(t)
1378
1379	if out, err := exec.Command(testenv.GoToolPath(t), "run", "x509_test_import.go").CombinedOutput(); err != nil {
1380		t.Errorf("failed to run x509_test_import.go: %s\n%s", err, out)
1381	}
1382}
1383
1384const derCRLBase64 = "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"
1385
1386const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RFFZSktvWklodmNOQVFFRkJRQXdiREVhTUJnR0ExVUVDaE1SVWxOQklGTmxZM1Z5DQphWFI1SUVsdVl5NHhIakFjQmdOVkJBTVRGVkpUUVNCUWRXSnNhV01nVW05dmRDQkRRU0IyTVRFdU1Dd0dDU3FHDQpTSWIzRFFFSkFSWWZjbk5oYTJWdmJuSnZiM1J6YVdkdVFISnpZWE5sWTNWeWFYUjVMbU52YlJjTk1URXdNakl6DQpNVGt5T0RNd1doY05NVEV3T0RJeU1Ua3lPRE13V2pDQmpEQktBaEVBckRxb2g5RkhKSFhUN09QZ3V1bjQrQmNODQpNRGt4TVRBeU1UUXlOekE1V2pBbU1Bb0dBMVVkRlFRRENnRUpNQmdHQTFVZEdBUVJHQTh5TURBNU1URXdNakUwDQpNalExTlZvd1BnSVJBTEd6blowOTVQQjVhQU9MUGc1N2ZNTVhEVEF5TVRBeU16RTBOVEF4TkZvd0dqQVlCZ05WDQpIUmdFRVJnUE1qQXdNakV3TWpNeE5EVXdNVFJhb0RBd0xqQWZCZ05WSFNNRUdEQVdnQlQxVERGNlVRTS9MTmVMDQpsNWx2cUhHUXEzZzltekFMQmdOVkhSUUVCQUlDQUlRd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ1lFQUZVNUFzNk16DQpxNVBSc2lmYW9iUVBHaDFhSkx5QytNczVBZ2MwYld5QTNHQWR4dXI1U3BQWmVSV0NCamlQL01FSEJXSkNsQkhQDQpHUmNxNXlJZDNFakRrYUV5eFJhK2k2N0x6dmhJNmMyOUVlNks5cFNZd2ppLzdSVWhtbW5Qclh0VHhsTDBsckxyDQptUVFKNnhoRFJhNUczUUE0Q21VZHNITnZicnpnbUNZcHZWRT0NCi0tLS0tRU5EIFg1MDkgQ1JMLS0tLS0NCg0K"
1387
1388func TestCreateCertificateRequest(t *testing.T) {
1389	random := rand.Reader
1390
1391	ecdsa256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
1392	if err != nil {
1393		t.Fatalf("Failed to generate ECDSA key: %s", err)
1394	}
1395
1396	ecdsa384Priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
1397	if err != nil {
1398		t.Fatalf("Failed to generate ECDSA key: %s", err)
1399	}
1400
1401	ecdsa521Priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
1402	if err != nil {
1403		t.Fatalf("Failed to generate ECDSA key: %s", err)
1404	}
1405
1406	_, ed25519Priv, err := ed25519.GenerateKey(random)
1407	if err != nil {
1408		t.Fatalf("Failed to generate Ed25519 key: %s", err)
1409	}
1410
1411	tests := []struct {
1412		name    string
1413		priv    interface{}
1414		sigAlgo SignatureAlgorithm
1415	}{
1416		{"RSA", testPrivateKey, SHA1WithRSA},
1417		{"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1},
1418		{"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1},
1419		{"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1},
1420		{"Ed25519", ed25519Priv, PureEd25519},
1421	}
1422
1423	for _, test := range tests {
1424		template := CertificateRequest{
1425			Subject: pkix.Name{
1426				CommonName:   "test.example.com",
1427				Organization: []string{"Σ Acme Co"},
1428			},
1429			SignatureAlgorithm: test.sigAlgo,
1430			DNSNames:           []string{"test.example.com"},
1431			EmailAddresses:     []string{"gopher@golang.org"},
1432			IPAddresses:        []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
1433		}
1434
1435		derBytes, err := CreateCertificateRequest(random, &template, test.priv)
1436		if err != nil {
1437			t.Errorf("%s: failed to create certificate request: %s", test.name, err)
1438			continue
1439		}
1440
1441		out, err := ParseCertificateRequest(derBytes)
1442		if err != nil {
1443			t.Errorf("%s: failed to create certificate request: %s", test.name, err)
1444			continue
1445		}
1446
1447		err = out.CheckSignature()
1448		if err != nil {
1449			t.Errorf("%s: failed to check certificate request signature: %s", test.name, err)
1450			continue
1451		}
1452
1453		if out.Subject.CommonName != template.Subject.CommonName {
1454			t.Errorf("%s: output subject common name and template subject common name don't match", test.name)
1455		} else if len(out.Subject.Organization) != len(template.Subject.Organization) {
1456			t.Errorf("%s: output subject organisation and template subject organisation don't match", test.name)
1457		} else if len(out.DNSNames) != len(template.DNSNames) {
1458			t.Errorf("%s: output DNS names and template DNS names don't match", test.name)
1459		} else if len(out.EmailAddresses) != len(template.EmailAddresses) {
1460			t.Errorf("%s: output email addresses and template email addresses don't match", test.name)
1461		} else if len(out.IPAddresses) != len(template.IPAddresses) {
1462			t.Errorf("%s: output IP addresses and template IP addresses names don't match", test.name)
1463		}
1464	}
1465}
1466
1467func marshalAndParseCSR(t *testing.T, template *CertificateRequest) *CertificateRequest {
1468	derBytes, err := CreateCertificateRequest(rand.Reader, template, testPrivateKey)
1469	if err != nil {
1470		t.Fatal(err)
1471	}
1472
1473	csr, err := ParseCertificateRequest(derBytes)
1474	if err != nil {
1475		t.Fatal(err)
1476	}
1477
1478	return csr
1479}
1480
1481func TestCertificateRequestOverrides(t *testing.T) {
1482	sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil, nil)
1483	if err != nil {
1484		t.Fatal(err)
1485	}
1486
1487	template := CertificateRequest{
1488		Subject: pkix.Name{
1489			CommonName:   "test.example.com",
1490			Organization: []string{"Σ Acme Co"},
1491		},
1492		DNSNames: []string{"test.example.com"},
1493
1494		// An explicit extension should override the DNSNames from the
1495		// template.
1496		ExtraExtensions: []pkix.Extension{
1497			{
1498				Id:       oidExtensionSubjectAltName,
1499				Value:    sanContents,
1500				Critical: true,
1501			},
1502		},
1503	}
1504
1505	csr := marshalAndParseCSR(t, &template)
1506
1507	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo.example.com" {
1508		t.Errorf("Extension did not override template. Got %v\n", csr.DNSNames)
1509	}
1510
1511	if len(csr.Extensions) != 1 || !csr.Extensions[0].Id.Equal(oidExtensionSubjectAltName) || !csr.Extensions[0].Critical {
1512		t.Errorf("SAN extension was not faithfully copied, got %#v", csr.Extensions)
1513	}
1514
1515	// If there is already an attribute with X.509 extensions then the
1516	// extra extensions should be added to it rather than creating a CSR
1517	// with two extension attributes.
1518
1519	template.Attributes = []pkix.AttributeTypeAndValueSET{
1520		{
1521			Type: oidExtensionRequest,
1522			Value: [][]pkix.AttributeTypeAndValue{
1523				{
1524					{
1525						Type:  oidExtensionAuthorityInfoAccess,
1526						Value: []byte("foo"),
1527					},
1528				},
1529			},
1530		},
1531	}
1532
1533	csr = marshalAndParseCSR(t, &template)
1534	if l := len(csr.Attributes); l != 1 {
1535		t.Errorf("incorrect number of attributes: %d\n", l)
1536	}
1537
1538	if !csr.Attributes[0].Type.Equal(oidExtensionRequest) ||
1539		len(csr.Attributes[0].Value) != 1 ||
1540		len(csr.Attributes[0].Value[0]) != 2 {
1541		t.Errorf("bad attributes: %#v\n", csr.Attributes)
1542	}
1543
1544	sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil, nil)
1545	if err != nil {
1546		t.Fatal(err)
1547	}
1548
1549	// Extensions in Attributes should override those in ExtraExtensions.
1550	template.Attributes[0].Value[0] = append(template.Attributes[0].Value[0], pkix.AttributeTypeAndValue{
1551		Type:  oidExtensionSubjectAltName,
1552		Value: sanContents2,
1553	})
1554
1555	csr = marshalAndParseCSR(t, &template)
1556
1557	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo2.example.com" {
1558		t.Errorf("Attributes did not override ExtraExtensions. Got %v\n", csr.DNSNames)
1559	}
1560}
1561
1562func TestParseCertificateRequest(t *testing.T) {
1563	for _, csrBase64 := range csrBase64Array {
1564		csrBytes := fromBase64(csrBase64)
1565		csr, err := ParseCertificateRequest(csrBytes)
1566		if err != nil {
1567			t.Fatalf("failed to parse CSR: %s", err)
1568		}
1569
1570		if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher@golang.org" {
1571			t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses)
1572		}
1573
1574		if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" {
1575			t.Errorf("incorrect DNS names found: %v", csr.DNSNames)
1576		}
1577
1578		if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" {
1579			t.Errorf("incorrect Subject name: %v", csr.Subject)
1580		}
1581
1582		found := false
1583		for _, e := range csr.Extensions {
1584			if e.Id.Equal(oidExtensionBasicConstraints) {
1585				found = true
1586				break
1587			}
1588		}
1589		if !found {
1590			t.Errorf("basic constraints extension not found in CSR")
1591		}
1592	}
1593}
1594
1595func TestCriticalFlagInCSRRequestedExtensions(t *testing.T) {
1596	// This CSR contains an extension request where the extensions have a
1597	// critical flag in them. In the past we failed to handle this.
1598	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="
1599
1600	csrBytes := fromBase64(csrBase64)
1601	csr, err := ParseCertificateRequest(csrBytes)
1602	if err != nil {
1603		t.Fatalf("failed to parse CSR: %s", err)
1604	}
1605
1606	expected := []struct {
1607		Id    asn1.ObjectIdentifier
1608		Value []byte
1609	}{
1610		{oidExtensionBasicConstraints, fromBase64("MAYBAf8CAQA=")},
1611		{oidExtensionKeyUsage, fromBase64("AwIChA==")},
1612	}
1613
1614	if n := len(csr.Extensions); n != len(expected) {
1615		t.Fatalf("expected to find %d extensions but found %d", len(expected), n)
1616	}
1617
1618	for i, extension := range csr.Extensions {
1619		if !extension.Id.Equal(expected[i].Id) {
1620			t.Fatalf("extension #%d has unexpected type %v (expected %v)", i, extension.Id, expected[i].Id)
1621		}
1622
1623		if !bytes.Equal(extension.Value, expected[i].Value) {
1624			t.Fatalf("extension #%d has unexpected contents %x (expected %x)", i, extension.Value, expected[i].Value)
1625		}
1626	}
1627}
1628
1629// serialiseAndParse generates a self-signed certificate from template and
1630// returns a parsed version of it.
1631func serialiseAndParse(t *testing.T, template *Certificate) *Certificate {
1632	derBytes, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey)
1633	if err != nil {
1634		t.Fatalf("failed to create certificate: %s", err)
1635		return nil
1636	}
1637
1638	cert, err := ParseCertificate(derBytes)
1639	if err != nil {
1640		t.Fatalf("failed to parse certificate: %s", err)
1641		return nil
1642	}
1643
1644	return cert
1645}
1646
1647func TestMaxPathLen(t *testing.T) {
1648	template := &Certificate{
1649		SerialNumber: big.NewInt(1),
1650		Subject: pkix.Name{
1651			CommonName: "Σ Acme Co",
1652		},
1653		NotBefore: time.Unix(1000, 0),
1654		NotAfter:  time.Unix(100000, 0),
1655
1656		BasicConstraintsValid: true,
1657		IsCA:                  true,
1658	}
1659
1660	cert1 := serialiseAndParse(t, template)
1661	if m := cert1.MaxPathLen; m != -1 {
1662		t.Errorf("Omitting MaxPathLen didn't turn into -1, got %d", m)
1663	}
1664	if cert1.MaxPathLenZero {
1665		t.Errorf("Omitting MaxPathLen resulted in MaxPathLenZero")
1666	}
1667
1668	template.MaxPathLen = 1
1669	cert2 := serialiseAndParse(t, template)
1670	if m := cert2.MaxPathLen; m != 1 {
1671		t.Errorf("Setting MaxPathLen didn't work. Got %d but set 1", m)
1672	}
1673	if cert2.MaxPathLenZero {
1674		t.Errorf("Setting MaxPathLen resulted in MaxPathLenZero")
1675	}
1676
1677	template.MaxPathLen = 0
1678	template.MaxPathLenZero = true
1679	cert3 := serialiseAndParse(t, template)
1680	if m := cert3.MaxPathLen; m != 0 {
1681		t.Errorf("Setting MaxPathLenZero didn't work, got %d", m)
1682	}
1683	if !cert3.MaxPathLenZero {
1684		t.Errorf("Setting MaxPathLen to zero didn't result in MaxPathLenZero")
1685	}
1686}
1687
1688func TestNoAuthorityKeyIdInSelfSignedCert(t *testing.T) {
1689	template := &Certificate{
1690		SerialNumber: big.NewInt(1),
1691		Subject: pkix.Name{
1692			CommonName: "Σ Acme Co",
1693		},
1694		NotBefore: time.Unix(1000, 0),
1695		NotAfter:  time.Unix(100000, 0),
1696
1697		BasicConstraintsValid: true,
1698		IsCA:                  true,
1699		SubjectKeyId:          []byte{1, 2, 3, 4},
1700	}
1701
1702	if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) != 0 {
1703		t.Fatalf("self-signed certificate contained default authority key id")
1704	}
1705
1706	template.AuthorityKeyId = []byte{1, 2, 3, 4}
1707	if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) == 0 {
1708		t.Fatalf("self-signed certificate erased explicit authority key id")
1709	}
1710}
1711
1712func TestASN1BitLength(t *testing.T) {
1713	tests := []struct {
1714		bytes  []byte
1715		bitLen int
1716	}{
1717		{nil, 0},
1718		{[]byte{0x00}, 0},
1719		{[]byte{0x00, 0x00}, 0},
1720		{[]byte{0xf0}, 4},
1721		{[]byte{0x88}, 5},
1722		{[]byte{0xff}, 8},
1723		{[]byte{0xff, 0x80}, 9},
1724		{[]byte{0xff, 0x81}, 16},
1725	}
1726
1727	for i, test := range tests {
1728		if got := asn1BitLength(test.bytes); got != test.bitLen {
1729			t.Errorf("#%d: calculated bit-length of %d for %x, wanted %d", i, got, test.bytes, test.bitLen)
1730		}
1731	}
1732}
1733
1734func TestVerifyEmptyCertificate(t *testing.T) {
1735	if _, err := new(Certificate).Verify(VerifyOptions{}); err != errNotParsed {
1736		t.Errorf("Verifying empty certificate resulted in unexpected error: %q (wanted %q)", err, errNotParsed)
1737	}
1738}
1739
1740func TestInsecureAlgorithmErrorString(t *testing.T) {
1741	tests := []struct {
1742		sa   SignatureAlgorithm
1743		want string
1744	}{
1745		{MD2WithRSA, "x509: cannot verify signature: insecure algorithm MD2-RSA"},
1746		{-1, "x509: cannot verify signature: insecure algorithm -1"},
1747		{0, "x509: cannot verify signature: insecure algorithm 0"},
1748		{9999, "x509: cannot verify signature: insecure algorithm 9999"},
1749	}
1750	for i, tt := range tests {
1751		if got := fmt.Sprint(InsecureAlgorithmError(tt.sa)); got != tt.want {
1752			t.Errorf("%d. mismatch.\n got: %s\nwant: %s\n", i, got, tt.want)
1753		}
1754	}
1755}
1756
1757// These CSR was generated with OpenSSL:
1758//  openssl req -out CSR.csr -new -sha256 -nodes -keyout privateKey.key -config openssl.cnf
1759//
1760// With openssl.cnf containing the following sections:
1761//   [ v3_req ]
1762//   basicConstraints = CA:FALSE
1763//   keyUsage = nonRepudiation, digitalSignature, keyEncipherment
1764//   subjectAltName = email:gopher@golang.org,DNS:test.example.com
1765//   [ req_attributes ]
1766//   challengePassword = ignored challenge
1767//   unstructuredName  = ignored unstructured name
1768var csrBase64Array = [...]string{
1769	// Just [ v3_req ]
1770	"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=",
1771	// Both [ v3_req ] and [ req_attributes ]
1772	"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==",
1773}
1774
1775var md5cert = `
1776-----BEGIN CERTIFICATE-----
1777MIIB4TCCAUoCCQCfmw3vMgPS5TANBgkqhkiG9w0BAQQFADA1MQswCQYDVQQGEwJB
1778VTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wHhcNMTUx
1779MjAzMTkyOTMyWhcNMjkwODEyMTkyOTMyWjA1MQswCQYDVQQGEwJBVTETMBEGA1UE
1780CBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wgZ8wDQYJKoZIhvcNAQEB
1781BQADgY0AMIGJAoGBANrq2nhLQj5mlXbpVX3QUPhfEm/vdEqPkoWtR/jRZIWm4WGf
1782Wpq/LKHJx2Pqwn+t117syN8l4U5unyAi1BJSXjBwPZNd7dXjcuJ+bRLV7FZ/iuvs
1783cfYyQQFTxan4TaJMd0x1HoNDbNbjHa02IyjjYE/r3mb/PIg+J2t5AZEh80lPAgMB
1784AAEwDQYJKoZIhvcNAQEEBQADgYEAjGzp3K3ey/YfKHohf33yHHWd695HQxDAP+wY
1785cs9/TAyLR+gJzJP7d18EcDDLJWVi7bhfa4EAD86di05azOh9kWSn4b3o9QYRGCSw
1786GNnI3Zk0cwNKA49hZntKKiy22DhRk7JAHF01d6Bu3KkHkmENrtJ+zj/+159WAnUa
1787qViorq4=
1788-----END CERTIFICATE-----
1789`
1790
1791func TestMD5(t *testing.T) {
1792	pemBlock, _ := pem.Decode([]byte(md5cert))
1793	cert, err := ParseCertificate(pemBlock.Bytes)
1794	if err != nil {
1795		t.Fatalf("failed to parse certificate: %s", err)
1796	}
1797	if sa := cert.SignatureAlgorithm; sa != MD5WithRSA {
1798		t.Errorf("signature algorithm is %v, want %v", sa, MD5WithRSA)
1799	}
1800	if err = cert.CheckSignatureFrom(cert); err == nil {
1801		t.Fatalf("certificate verification succeeded incorrectly")
1802	}
1803	if _, ok := err.(InsecureAlgorithmError); !ok {
1804		t.Fatalf("certificate verification returned %v (%T), wanted InsecureAlgorithmError", err, err)
1805	}
1806}
1807
1808// certMissingRSANULL contains an RSA public key where the AlgorithmIdentifer
1809// parameters are omitted rather than being an ASN.1 NULL.
1810const certMissingRSANULL = `
1811-----BEGIN CERTIFICATE-----
1812MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD
1813bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4
1814MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc
1815MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG
1816hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE
1817ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e
1818E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw
1819DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A
1820p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4
1821hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE
1822GFGNEH5PlGffo05wc46QkYU=
1823-----END CERTIFICATE-----`
1824
1825func TestRSAMissingNULLParameters(t *testing.T) {
1826	block, _ := pem.Decode([]byte(certMissingRSANULL))
1827	if _, err := ParseCertificate(block.Bytes); err == nil {
1828		t.Error("unexpected success when parsing certificate with missing RSA NULL parameter")
1829	} else if !strings.Contains(err.Error(), "missing NULL") {
1830		t.Errorf("unrecognised error when parsing certificate with missing RSA NULL parameter: %s", err)
1831	}
1832}
1833
1834const certISOOID = `
1835-----BEGIN CERTIFICATE-----
1836MIIB5TCCAVKgAwIBAgIQtwyL3RPWV7dJQp34HwZG9DAJBgUrDgMCHQUAMBExDzAN
1837BgNVBAMTBm15dGVzdDAeFw0xNjA4MDkyMjExMDVaFw0zOTEyMzEyMzU5NTlaMBEx
1838DzANBgNVBAMTBm15dGVzdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArzIH
1839GsyDB3ohIGkkvijF2PTRUX1bvOtY1eUUpjwHyu0twpAKSuaQv2Ha+/63+aHe8O86
1840BT+98wjXFX6RFSagtAujo80rIF2dSm33BGt18pDN8v6zp93dnAm0jRaSQrHJ75xw
18415O+S1oEYR1LtUoFJy6qB104j6aINBAgOiLIKiMkCAwEAAaNGMEQwQgYDVR0BBDsw
1842OYAQVuYVQ/WDjdGSkZRlTtJDNKETMBExDzANBgNVBAMTBm15dGVzdIIQtwyL3RPW
1843V7dJQp34HwZG9DAJBgUrDgMCHQUAA4GBABngrSkH7vG5lY4sa4AZF59lAAXqBVJE
1844J4TBiKC62hCdZv18rBleP6ETfhbPg7pTs8p4ebQbpmtNxRS9Lw3MzQ8Ya5Ybwzj2
1845NwBSyCtCQl7mrEg4nJqJl4A2EUhnET/oVxU0oTV/SZ3ziGXcY1oG1s6vidV7TZTu
1846MCRtdSdaM7g3
1847-----END CERTIFICATE-----`
1848
1849func TestISOOIDInCertificate(t *testing.T) {
1850	block, _ := pem.Decode([]byte(certISOOID))
1851	if cert, err := ParseCertificate(block.Bytes); err != nil {
1852		t.Errorf("certificate with ISO OID failed to parse: %s", err)
1853	} else if cert.SignatureAlgorithm == UnknownSignatureAlgorithm {
1854		t.Errorf("ISO OID not recognised in certificate")
1855	}
1856}
1857
1858// certMultipleRDN contains a RelativeDistinguishedName with two elements (the
1859// common name and serial number). This particular certificate was the first
1860// such certificate in the “Pilot” Certificate Transparency log.
1861const certMultipleRDN = `
1862-----BEGIN CERTIFICATE-----
1863MIIFRzCCBC+gAwIBAgIEOl59NTANBgkqhkiG9w0BAQUFADA9MQswCQYDVQQGEwJz
1864aTEbMBkGA1UEChMSc3RhdGUtaW5zdGl0dXRpb25zMREwDwYDVQQLEwhzaWdvdi1j
1865YTAeFw0xMjExMTYxMDUyNTdaFw0xNzExMTYxMjQ5MDVaMIGLMQswCQYDVQQGEwJz
1866aTEbMBkGA1UEChMSc3RhdGUtaW5zdGl0dXRpb25zMRkwFwYDVQQLExB3ZWItY2Vy
1867dGlmaWNhdGVzMRAwDgYDVQQLEwdTZXJ2ZXJzMTIwFAYDVQQFEw0xMjM2NDg0MDEw
1868MDEwMBoGA1UEAxMTZXBvcnRhbC5tc3MuZWR1cy5zaTCCASIwDQYJKoZIhvcNAQEB
1869BQADggEPADCCAQoCggEBAMrNkZH9MPuBTjMGNk3sJX8V+CkFx/4ru7RTlLS6dlYM
1870098dtSfJ3s2w0p/1NB9UmR8j0yS0Kg6yoZ3ShsSO4DWBtcQD8820a6BYwqxxQTNf
1871HSRZOc+N/4TQrvmK6t4k9Aw+YEYTMrWOU4UTeyhDeCcUsBdh7HjfWsVaqNky+2sv
1872oic3zP5gF+2QfPkvOoHT3FLR8olNhViIE6Kk3eFIEs4dkq/ZzlYdLb8pHQoj/sGI
1873zFmA5AFvm1HURqOmJriFjBwaCtn8AVEYOtQrnUCzJYu1ex8azyS2ZgYMX0u8A5Z/
1874y2aMS/B2W+H79WcgLpK28vPwe7vam0oFrVytAd+u65ECAwEAAaOCAf4wggH6MA4G
1875A1UdDwEB/wQEAwIFoDBABgNVHSAEOTA3MDUGCisGAQQBr1kBAwMwJzAlBggrBgEF
1876BQcCARYZaHR0cDovL3d3dy5jYS5nb3Yuc2kvY3BzLzAfBgNVHREEGDAWgRRwb2Rw
1877b3JhLm1pemtzQGdvdi5zaTCB8QYDVR0fBIHpMIHmMFWgU6BRpE8wTTELMAkGA1UE
1878BhMCc2kxGzAZBgNVBAoTEnN0YXRlLWluc3RpdHV0aW9uczERMA8GA1UECxMIc2ln
1879b3YtY2ExDjAMBgNVBAMTBUNSTDM5MIGMoIGJoIGGhldsZGFwOi8veDUwMC5nb3Yu
1880c2kvb3U9c2lnb3YtY2Esbz1zdGF0ZS1pbnN0aXR1dGlvbnMsYz1zaT9jZXJ0aWZp
1881Y2F0ZVJldm9jYXRpb25MaXN0P2Jhc2WGK2h0dHA6Ly93d3cuc2lnb3YtY2EuZ292
1882LnNpL2NybC9zaWdvdi1jYS5jcmwwKwYDVR0QBCQwIoAPMjAxMjExMTYxMDUyNTda
1883gQ8yMDE3MTExNjEyNDkwNVowHwYDVR0jBBgwFoAUHvjUU2uzgwbpBAZXAvmlv8ZY
1884PHIwHQYDVR0OBBYEFGI1Duuu+wTGDZka/xHNbwcbM69ZMAkGA1UdEwQCMAAwGQYJ
1885KoZIhvZ9B0EABAwwChsEVjcuMQMCA6gwDQYJKoZIhvcNAQEFBQADggEBAHny0K1y
1886BQznrzDu3DDpBcGYguKU0dvU9rqsV1ua4nxkriSMWjgsX6XJFDdDW60I3P4VWab5
1887ag5fZzbGqi8kva/CzGgZh+CES0aWCPy+4Gb8lwOTt+854/laaJvd6kgKTER7z7U9
18889C86Ch2y4sXNwwwPJ1A9dmrZJZOcJjS/WYZgwaafY2Hdxub5jqPE5nehwYUPVu9R
1889uH6/skk4OEKcfOtN0hCnISOVuKYyS4ANARWRG5VGHIH06z3lGUVARFRJ61gtAprd
1890La+fgSS+LVZ+kU2TkeoWAKvGq8MAgDq4D4Xqwekg7WKFeuyusi/NI5rm40XgjBMF
1891DF72IUofoVt7wo0=
1892-----END CERTIFICATE-----`
1893
1894func TestMultipleRDN(t *testing.T) {
1895	block, _ := pem.Decode([]byte(certMultipleRDN))
1896	cert, err := ParseCertificate(block.Bytes)
1897	if err != nil {
1898		t.Fatalf("certificate with two elements in an RDN failed to parse: %v", err)
1899	}
1900
1901	if want := "eportal.mss.edus.si"; cert.Subject.CommonName != want {
1902		t.Errorf("got common name of %q, but want %q", cert.Subject.CommonName, want)
1903	}
1904
1905	if want := "1236484010010"; cert.Subject.SerialNumber != want {
1906		t.Errorf("got serial number of %q, but want %q", cert.Subject.SerialNumber, want)
1907	}
1908}
1909
1910func TestSystemCertPool(t *testing.T) {
1911	if runtime.GOOS == "windows" {
1912		t.Skip("not implemented on Windows; Issue 16736, 18609")
1913	}
1914	a, err := SystemCertPool()
1915	if err != nil {
1916		t.Fatal(err)
1917	}
1918	b, err := SystemCertPool()
1919	if err != nil {
1920		t.Fatal(err)
1921	}
1922	if !reflect.DeepEqual(a, b) {
1923		t.Fatal("two calls to SystemCertPool had different results")
1924	}
1925	if ok := b.AppendCertsFromPEM([]byte(`
1926-----BEGIN CERTIFICATE-----
1927MIIDBjCCAe6gAwIBAgIRANXM5I3gjuqDfTp/PYrs+u8wDQYJKoZIhvcNAQELBQAw
1928EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xODAzMjcxOTU2MjFaFw0xOTAzMjcxOTU2
1929MjFaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
1930ggEKAoIBAQDK+9m3rjsO2Djes6bIYQZ3eV29JF09ZrjOrEHLtaKrD6/acsoSoTsf
1931cQr+rzzztdB5ijWXCS64zo/0OiqBeZUNZ67jVdToa9qW5UYe2H0Y+ZNdfA5GYMFD
1932yk/l3/uBu3suTZPfXiW2TjEi27Q8ruNUIZ54DpTcs6y2rBRFzadPWwn/VQMlvRXM
1933jrzl8Y08dgnYmaAHprxVzwMXcQ/Brol+v9GvjaH1DooHqkn8O178wsPQNhdtvN01
1934IXL46cYdcUwWrE/GX5u+9DaSi+0KWxAPQ+NVD5qUI0CKl4714yGGh7feXMjJdHgl
1935VG4QJZlJvC4FsURgCHJT6uHGIelnSwhbAgMBAAGjVzBVMA4GA1UdDwEB/wQEAwIF
1936oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCAGA1UdEQQZMBeC
1937FVRlc3RTeXN0ZW1DZXJ0UG9vbC5nbzANBgkqhkiG9w0BAQsFAAOCAQEAwuSRx/VR
1938BKh2ICxZjL6jBwk/7UlU1XKbhQD96RqkidDNGEc6eLZ90Z5XXTurEsXqdm5jQYPs
19391cdcSW+fOSMl7MfW9e5tM66FaIPZl9rKZ1r7GkOfgn93xdLAWe8XHd19xRfDreub
1940YC8DVqgLASOEYFupVSl76ktPfxkU5KCvmUf3P2PrRybk1qLGFytGxfyice2gHSNI
1941gify3K/+H/7wCkyFW4xYvzl7WW4mXxoqPRPjQt1J423DhnnQ4G1P8V/vhUpXNXOq
1942N9IEPnWuihC09cyx/WMQIUlWnaQLHdfpPS04Iez3yy2PdfXJzwfPrja7rNE+skK6
1943pa/O1nF0AfWOpw==
1944-----END CERTIFICATE-----
1945	`)); !ok {
1946		t.Fatal("AppendCertsFromPEM failed")
1947	}
1948	if reflect.DeepEqual(a, b) {
1949		t.Fatal("changing one pool modified the other")
1950	}
1951}
1952
1953const emptyNameConstraintsPEM = `
1954-----BEGIN CERTIFICATE-----
1955MIIC1jCCAb6gAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w
1956dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw
1957NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB
1958IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD
1959F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx
1960f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq
1961Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0
1962LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD
1963blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID
1964AQABoxEwDzANBgNVHR4EBjAEoAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMH
1965QhP8uNCtgSHyim/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb
19666L+iJa4ElREJOi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6H
1967v5SsvpYW+1XleYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6M
1968LYPmRhTioROA/drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOga
1969nCOSyFYfGhqOANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8
1970o+WoY6IsCKXV/g==
1971-----END CERTIFICATE-----`
1972
1973func TestEmptyNameConstraints(t *testing.T) {
1974	block, _ := pem.Decode([]byte(emptyNameConstraintsPEM))
1975	_, err := ParseCertificate(block.Bytes)
1976	if err == nil {
1977		t.Fatal("unexpected success")
1978	}
1979
1980	const expected = "empty name constraints"
1981	if str := err.Error(); !strings.Contains(str, expected) {
1982		t.Errorf("expected %q in error but got %q", expected, str)
1983	}
1984}
1985
1986func TestPKIXNameString(t *testing.T) {
1987	pem, err := hex.DecodeString(certBytes)
1988	if err != nil {
1989		t.Fatal(err)
1990	}
1991	certs, err := ParseCertificates(pem)
1992	if err != nil {
1993		t.Fatal(err)
1994	}
1995
1996	tests := []struct {
1997		dn   pkix.Name
1998		want string
1999	}{
2000		{pkix.Name{
2001			CommonName:         "Steve Kille",
2002			Organization:       []string{"Isode Limited"},
2003			OrganizationalUnit: []string{"RFCs"},
2004			Locality:           []string{"Richmond"},
2005			Province:           []string{"Surrey"},
2006			StreetAddress:      []string{"The Square"},
2007			PostalCode:         []string{"TW9 1DT"},
2008			SerialNumber:       "RFC 2253",
2009			Country:            []string{"GB"},
2010		}, "SERIALNUMBER=RFC 2253,CN=Steve Kille,OU=RFCs,O=Isode Limited,POSTALCODE=TW9 1DT,STREET=The Square,L=Richmond,ST=Surrey,C=GB"},
2011		{certs[0].Subject,
2012			"CN=mail.google.com,O=Google Inc,L=Mountain View,ST=California,C=US"},
2013		{pkix.Name{
2014			Organization: []string{"#Google, Inc. \n-> 'Alphabet\" "},
2015			Country:      []string{"US"},
2016		}, "O=\\#Google\\, Inc. \n-\\> 'Alphabet\\\"\\ ,C=US"},
2017		{pkix.Name{
2018			CommonName:   "foo.com",
2019			Organization: []string{"Gopher Industries"},
2020			ExtraNames: []pkix.AttributeTypeAndValue{
2021				{Type: asn1.ObjectIdentifier([]int{2, 5, 4, 3}), Value: "bar.com"}},
2022		}, "CN=bar.com,O=Gopher Industries"},
2023		{pkix.Name{
2024			Locality: []string{"Gophertown"},
2025			ExtraNames: []pkix.AttributeTypeAndValue{
2026				{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
2027		}, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"},
2028	}
2029
2030	for i, test := range tests {
2031		if got := test.dn.String(); got != test.want {
2032			t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want)
2033		}
2034	}
2035}
2036
2037func TestRDNSequenceString(t *testing.T) {
2038	// Test some extra cases that get lost in pkix.Name conversions such as
2039	// multi-valued attributes.
2040
2041	var (
2042		oidCountry            = []int{2, 5, 4, 6}
2043		oidOrganization       = []int{2, 5, 4, 10}
2044		oidOrganizationalUnit = []int{2, 5, 4, 11}
2045		oidCommonName         = []int{2, 5, 4, 3}
2046	)
2047
2048	tests := []struct {
2049		seq  pkix.RDNSequence
2050		want string
2051	}{
2052		{
2053			seq: pkix.RDNSequence{
2054				pkix.RelativeDistinguishedNameSET{
2055					pkix.AttributeTypeAndValue{Type: oidCountry, Value: "US"},
2056				},
2057				pkix.RelativeDistinguishedNameSET{
2058					pkix.AttributeTypeAndValue{Type: oidOrganization, Value: "Widget Inc."},
2059				},
2060				pkix.RelativeDistinguishedNameSET{
2061					pkix.AttributeTypeAndValue{Type: oidOrganizationalUnit, Value: "Sales"},
2062					pkix.AttributeTypeAndValue{Type: oidCommonName, Value: "J. Smith"},
2063				},
2064			},
2065			want: "OU=Sales+CN=J. Smith,O=Widget Inc.,C=US",
2066		},
2067	}
2068
2069	for i, test := range tests {
2070		if got := test.seq.String(); got != test.want {
2071			t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want)
2072		}
2073	}
2074}
2075
2076const criticalNameConstraintWithUnknownTypePEM = `
2077-----BEGIN CERTIFICATE-----
2078MIIC/TCCAeWgAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UEAxMdRW1w
2079dHkgbmFtZSBjb25zdHJhaW50cyBpc3N1ZXIwHhcNMTMwMjAxMDAwMDAwWhcNMjAw
2080NTMwMTA0ODM4WjAhMR8wHQYDVQQDExZFbXB0eSBuYW1lIGNvbnN0cmFpbnRzMIIB
2081IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwriElUIt3LCqmJObs+yDoWPD
2082F5IqgWk6moIobYjPfextZiYU6I3EfvAwoNxPDkN2WowcocUZMJbEeEq5ebBksFnx
2083f12gBxlIViIYwZAzu7aFvhDMyPKQI3C8CG0ZSC9ABZ1E3umdA3CEueNOmP/TChNq
2084Cl23+BG1Qb/PJkpAO+GfpWSVhTcV53Mf/cKvFHcjGNrxzdSoq9fyW7a6gfcGEQY0
2085LVkmwFWUfJ0wT8kaeLr0E0tozkIfo01KNWNzv6NcYP80QOBRDlApWu9ODmEVJHPD
2086blx4jzTQ3JLa+4DvBNOjVUOp+mgRmjiW0rLdrxwOxIqIOwNjweMCp/hgxX/hTQID
2087AQABozgwNjA0BgNVHR4BAf8EKjAooCQwIokgIACrzQAAAAAAAAAAAAAAAP////8A
2088AAAAAAAAAAAAAAChADANBgkqhkiG9w0BAQsFAAOCAQEAWG+/zUMHQhP8uNCtgSHy
2089im/vh7wminwAvWgMKxlkLBFns6nZeQqsOV1lABY7U0Zuoqa1Z5nb6L+iJa4ElREJ
2090Oi/erLc9uLwBdDCAR0hUTKD7a6i4ooS39DTle87cUnj0MW1CUa6Hv5SsvpYW+1Xl
2091eYJk/axQOOTcy4Es53dvnZsjXH0EA/QHnn7UV+JmlE3rtVxcYp6MLYPmRhTioROA
2092/drghicRkiu9hxdPyxkYS16M5g3Zj30jdm+k/6C6PeNtN9YmOOganCOSyFYfGhqO
2093ANYzpmuV+oIedAsPpIbfIzN8njYUs1zio+1IoI4o8ddM9sCbtPU8o+WoY6IsCKXV
2094/g==
2095-----END CERTIFICATE-----`
2096
2097func TestCriticalNameConstraintWithUnknownType(t *testing.T) {
2098	block, _ := pem.Decode([]byte(criticalNameConstraintWithUnknownTypePEM))
2099	cert, err := ParseCertificate(block.Bytes)
2100	if err != nil {
2101		t.Fatalf("unexpected parsing failure: %s", err)
2102	}
2103
2104	if l := len(cert.UnhandledCriticalExtensions); l != 1 {
2105		t.Fatalf("expected one unhandled critical extension, but found %d", l)
2106	}
2107}
2108
2109const badIPMaskPEM = `
2110-----BEGIN CERTIFICATE-----
2111MIICzzCCAbegAwIBAgICEjQwDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UEAxMSQmFk
2112IElQIG1hc2sgaXNzdWVyMB4XDTEzMDIwMTAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
2113FjEUMBIGA1UEAxMLQmFkIElQIG1hc2swggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
2114ggEKAoIBAQDCuISVQi3csKqYk5uz7IOhY8MXkiqBaTqagihtiM997G1mJhTojcR+
21158DCg3E8OQ3ZajByhxRkwlsR4Srl5sGSwWfF/XaAHGUhWIhjBkDO7toW+EMzI8pAj
2116cLwIbRlIL0AFnUTe6Z0DcIS5406Y/9MKE2oKXbf4EbVBv88mSkA74Z+lZJWFNxXn
2117cx/9wq8UdyMY2vHN1Kir1/JbtrqB9wYRBjQtWSbAVZR8nTBPyRp4uvQTS2jOQh+j
2118TUo1Y3O/o1xg/zRA4FEOUCla704OYRUkc8NuXHiPNNDcktr7gO8E06NVQ6n6aBGa
2119OJbSst2vHA7Eiog7A2PB4wKn+GDFf+FNAgMBAAGjIDAeMBwGA1UdHgEB/wQSMBCg
2120DDAKhwgBAgME//8BAKEAMA0GCSqGSIb3DQEBCwUAA4IBAQBYb7/NQwdCE/y40K2B
2121IfKKb++HvCaKfAC9aAwrGWQsEWezqdl5Cqw5XWUAFjtTRm6iprVnmdvov6IlrgSV
2122EQk6L96stz24vAF0MIBHSFRMoPtrqLiihLf0NOV7ztxSePQxbUJRroe/lKy+lhb7
2123VeV5gmT9rFA45NzLgSznd2+dmyNcfQQD9AeeftRX4maUTeu1XFxinowtg+ZGFOKh
2124E4D92uCGJxGSK72HF0/LGRhLXozmDdmPfSN2b6T/oLo942031iY46BqcI5LIVh8a
2125Go4A1jOma5X6gh50Cw+kht8jM3yeNhSzXOKj7Uigjijx10z2wJu09Tyj5ahjoiwI
2126pdX+
2127-----END CERTIFICATE-----`
2128
2129func TestBadIPMask(t *testing.T) {
2130	block, _ := pem.Decode([]byte(badIPMaskPEM))
2131	_, err := ParseCertificate(block.Bytes)
2132	if err == nil {
2133		t.Fatalf("unexpected success")
2134	}
2135
2136	const expected = "contained invalid mask"
2137	if !strings.Contains(err.Error(), expected) {
2138		t.Fatalf("expected %q in error but got: %s", expected, err)
2139	}
2140}
2141
2142const additionalGeneralSubtreePEM = `
2143-----BEGIN CERTIFICATE-----
2144MIIG4TCCBMmgAwIBAgIRALss+4rLw2Ia7tFFhxE8g5cwDQYJKoZIhvcNAQELBQAw
2145bjELMAkGA1UEBhMCTkwxIDAeBgNVBAoMF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll
2146MT0wOwYDVQQDDDRNaW5pc3RlcmllIHZhbiBEZWZlbnNpZSBDZXJ0aWZpY2F0aWUg
2147QXV0b3JpdGVpdCAtIEcyMB4XDTEzMDMwNjEyMDM0OVoXDTEzMTEzMDEyMDM1MFow
2148bDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUNlcnRpUGF0aCBMTEMxIjAgBgNVBAsT
2149GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxITAfBgNVBAMTGENlcnRpUGF0aCBC
2150cmlkZ2UgQ0EgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANLW
21514kXiRqvwBhJfN9uz12FA+P2D34MPxOt7TGXljm2plJ2CLzvaH8/ymsMdSWdJBS1M
21528FmwvNL1w3A6ZuzksJjPikAu8kY3dcp3mrkk9eCPORDAwGtfsXwZysLiuEaDWpbD
2153dHOaHnI6qWU0N6OI+hNX58EjDpIGC1WQdho1tHOTPc5Hf5/hOpM/29v/wr7kySjs
2154Z+7nsvkm5rNhuJNzPsLsgzVaJ5/BVyOplZy24FKM8Y43MjR4osZm+a2e0zniqw6/
2155rvcjcGYabYaznZfQG1GXoyf2Vea+CCgpgUhlVafgkwEs8izl8rIpvBzXiFAgFQuG
2156Ituoy92PJbDs430fA/cCAwEAAaOCAnowggJ2MEUGCCsGAQUFBwEBBDkwNzA1Bggr
2157BgEFBQcwAoYpaHR0cDovL2NlcnRzLmNhLm1pbmRlZi5ubC9taW5kZWYtY2EtMi5w
2158N2MwHwYDVR0jBBgwFoAUzln9WSPz2M64Rl2HYf2/KD8StmQwDwYDVR0TAQH/BAUw
2159AwEB/zCB6QYDVR0gBIHhMIHeMEgGCmCEEAGHawECBQEwOjA4BggrBgEFBQcCARYs
2160aHR0cDovL2Nwcy5kcC5jYS5taW5kZWYubmwvbWluZGVmLWNhLWRwLWNwcy8wSAYK
2161YIQQAYdrAQIFAjA6MDgGCCsGAQUFBwIBFixodHRwOi8vY3BzLmRwLmNhLm1pbmRl
2162Zi5ubC9taW5kZWYtY2EtZHAtY3BzLzBIBgpghBABh2sBAgUDMDowOAYIKwYBBQUH
2163AgEWLGh0dHA6Ly9jcHMuZHAuY2EubWluZGVmLm5sL21pbmRlZi1jYS1kcC1jcHMv
2164MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmxzLmNhLm1pbmRlZi5ubC9taW5k
2165ZWYtY2EtMi5jcmwwDgYDVR0PAQH/BAQDAgEGMEYGA1UdHgEB/wQ8MDqhODA2pDEw
2166LzELMAkGA1UEBhMCTkwxIDAeBgNVBAoTF01pbmlzdGVyaWUgdmFuIERlZmVuc2ll
2167gQFjMF0GA1UdIQRWMFQwGgYKYIQQAYdrAQIFAQYMKwYBBAGBu1MBAQECMBoGCmCE
2168EAGHawECBQIGDCsGAQQBgbtTAQEBAjAaBgpghBABh2sBAgUDBgwrBgEEAYG7UwEB
2169AQIwHQYDVR0OBBYEFNDCjBM3M3ZKkag84ei3/aKc0d0UMA0GCSqGSIb3DQEBCwUA
2170A4ICAQAQXFn9jF90/DNFf15JhoGtta/0dNInb14PMu3PAjcdrXYCDPpQZOArTUng
21715YT1WuzfmjnXiTsziT3my0r9Mxvz/btKK/lnVOMW4c2q/8sIsIPnnW5ZaRGrsANB
2172dNDZkzMYmeG2Pfgvd0AQSOrpE/TVgWfu/+MMRWwX9y6VbooBR7BLv7zMuVH0WqLn
21736OMFth7fqsThlfMSzkE/RDSaU6n3wXAWT1SIqBITtccRjSUQUFm/q3xrb2cwcZA6
21748vdS4hzNd+ttS905ay31Ks4/1Wrm1bH5RhEfRSH0VSXnc0b+z+RyBbmiwtVZqzxE
2175u3UQg/rAmtLDclLFEzjp8YDTIRYSLwstDbEXO/0ArdGrQm79HQ8i/3ZbP2357myW
2176i15qd6gMJIgGHS4b8Hc7R1K8LQ9Gm1aLKBEWVNGZlPK/cpXThpVmoEyslN2DHCrc
2177fbMbjNZpXlTMa+/b9z7Fa4X8dY8u/ELzZuJXJv5Rmqtg29eopFFYDCl0Nkh1XAjo
2178QejEoHHUvYV8TThHZr6Z6Ib8CECgTehU4QvepkgDXNoNrKRZBG0JhLjkwxh2whZq
2179nvWBfALC2VuNOM6C0rDY+HmhMlVt0XeqnybD9MuQALMit7Z00Cw2CIjNsBI9xBqD
2180xKK9CjUb7gzRUWSpB9jGHsvpEMHOzIFhufvH2Bz1XJw+Cl7khw==
2181-----END CERTIFICATE-----`
2182
2183func TestAdditionFieldsInGeneralSubtree(t *testing.T) {
2184	// Very rarely, certificates can include additional fields in the
2185	// GeneralSubtree structure. This tests that such certificates can be
2186	// parsed.
2187	block, _ := pem.Decode([]byte(additionalGeneralSubtreePEM))
2188	if _, err := ParseCertificate(block.Bytes); err != nil {
2189		t.Fatalf("failed to parse certificate: %s", err)
2190	}
2191}
2192
2193func TestEmptySubject(t *testing.T) {
2194	template := Certificate{
2195		SerialNumber: big.NewInt(1),
2196		DNSNames:     []string{"example.com"},
2197	}
2198
2199	derBytes, err := CreateCertificate(rand.Reader, &template, &template, &testPrivateKey.PublicKey, testPrivateKey)
2200	if err != nil {
2201		t.Fatalf("failed to create certificate: %s", err)
2202	}
2203
2204	cert, err := ParseCertificate(derBytes)
2205	if err != nil {
2206		t.Fatalf("failed to parse certificate: %s", err)
2207	}
2208
2209	for _, ext := range cert.Extensions {
2210		if ext.Id.Equal(oidExtensionSubjectAltName) {
2211			if !ext.Critical {
2212				t.Fatal("SAN extension is not critical")
2213			}
2214			return
2215		}
2216	}
2217
2218	t.Fatal("SAN extension is missing")
2219}
2220
2221// multipleURLsInCRLDPPEM contains two URLs in a single CRL DistributionPoint
2222// structure. It is taken from https://crt.sh/?id=12721534.
2223const multipleURLsInCRLDPPEM = `
2224-----BEGIN CERTIFICATE-----
2225MIIF4TCCBMmgAwIBAgIQc+6uFePfrahUGpXs8lhiTzANBgkqhkiG9w0BAQsFADCB
22268zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy
2227dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1
2228YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3
2229dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh
2230IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD
2231LUFDQzAeFw0xNDA5MTgwODIxMDBaFw0zMDA5MTgwODIxMDBaMIGGMQswCQYDVQQG
2232EwJFUzEzMDEGA1UECgwqQ09OU09SQ0kgQURNSU5JU1RSQUNJTyBPQkVSVEEgREUg
2233Q0FUQUxVTllBMSowKAYDVQQLDCFTZXJ2ZWlzIFDDumJsaWNzIGRlIENlcnRpZmlj
2234YWNpw7MxFjAUBgNVBAMMDUVDLUNpdXRhZGFuaWEwggEiMA0GCSqGSIb3DQEBAQUA
2235A4IBDwAwggEKAoIBAQDFkHPRZPZlXTWZ5psJhbS/Gx+bxcTpGrlVQHHtIkgGz77y
2236TA7UZUFb2EQMncfbOhR0OkvQQn1aMvhObFJSR6nI+caf2D+h/m/InMl1MyH3S0Ak
2237YGZZsthnyC6KxqK2A/NApncrOreh70ULkQs45aOKsi1kR1W0zE+iFN+/P19P7AkL
2238Rl3bXBCVd8w+DLhcwRrkf1FCDw6cEqaFm3cGgf5cbBDMaVYAweWTxwBZAq2RbQAW
2239jE7mledcYghcZa4U6bUmCBPuLOnO8KMFAvH+aRzaf3ws5/ZoOVmryyLLJVZ54peZ
2240OwnP9EL4OuWzmXCjBifXR2IAblxs5JYj57tls45nAgMBAAGjggHaMIIB1jASBgNV
2241HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUC2hZPofI
2242oxUa4ECCIl+fHbLFNxUwHwYDVR0jBBgwFoAUoMOLRKo3pUW/l4Ba0fF4opvpXY0w
2243gdYGA1UdIASBzjCByzCByAYEVR0gADCBvzAxBggrBgEFBQcCARYlaHR0cHM6Ly93
2244d3cuYW9jLmNhdC9DQVRDZXJ0L1JlZ3VsYWNpbzCBiQYIKwYBBQUHAgIwfQx7QXF1
2245ZXN0IGNlcnRpZmljYXQgw6lzIGVtw6hzIMO6bmljYSBpIGV4Y2x1c2l2YW1lbnQg
2246YSBFbnRpdGF0cyBkZSBDZXJ0aWZpY2FjacOzLiBWZWdldSBodHRwczovL3d3dy5h
2247b2MuY2F0L0NBVENlcnQvUmVndWxhY2lvMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEF
2248BQcwAYYXaHR0cDovL29jc3AuY2F0Y2VydC5jYXQwYgYDVR0fBFswWTBXoFWgU4Yn
2249aHR0cDovL2Vwc2NkLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JshihodHRwOi8v
2250ZXBzY2QyLmNhdGNlcnQubmV0L2NybC9lYy1hY2MuY3JsMA0GCSqGSIb3DQEBCwUA
2251A4IBAQChqFTjlAH5PyIhLjLgEs68CyNNC1+vDuZXRhy22TI83JcvGmQrZosPvVIL
2252PsUXx+C06Pfqmh48Q9S89X9K8w1SdJxP/rZeGEoRiKpwvQzM4ArD9QxyC8jirxex
22533Umg9Ai/sXQ+1lBf6xw4HfUUr1WIp7pNHj0ZWLo106urqktcdeAFWme+/klis5fu
2254labCSVPuT/QpwakPrtqOhRms8vgpKiXa/eLtL9ZiA28X/Mker0zlAeTA7Z7uAnp6
2255oPJTlZu1Gg1ZDJueTWWsLlO+P+Wzm3MRRIbcgdRzm4mdO7ubu26SzX/aQXDhuih+
2256eVxXDTCfs7GUlxnjOp5j559X/N0A
2257-----END CERTIFICATE-----
2258`
2259
2260func TestMultipleURLsInCRLDP(t *testing.T) {
2261	block, _ := pem.Decode([]byte(multipleURLsInCRLDPPEM))
2262	cert, err := ParseCertificate(block.Bytes)
2263	if err != nil {
2264		t.Fatalf("failed to parse certificate: %s", err)
2265	}
2266
2267	want := []string{
2268		"http://epscd.catcert.net/crl/ec-acc.crl",
2269		"http://epscd2.catcert.net/crl/ec-acc.crl",
2270	}
2271	if got := cert.CRLDistributionPoints; !reflect.DeepEqual(got, want) {
2272		t.Errorf("CRL distribution points = %#v, want #%v", got, want)
2273	}
2274}
2275
2276const hexPKCS1TestPKCS8Key = "30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031"
2277const hexPKCS1TestECKey = "3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50"
2278
2279var pkcs1MismatchKeyTests = []struct {
2280	hexKey        string
2281	errorContains string
2282}{
2283	{hexKey: hexPKCS1TestPKCS8Key, errorContains: "use ParsePKCS8PrivateKey instead"},
2284	{hexKey: hexPKCS1TestECKey, errorContains: "use ParseECPrivateKey instead"},
2285}
2286
2287func TestPKCS1MismatchKeyFormat(t *testing.T) {
2288	for i, test := range pkcs1MismatchKeyTests {
2289		derBytes, _ := hex.DecodeString(test.hexKey)
2290		_, err := ParsePKCS1PrivateKey(derBytes)
2291		if !strings.Contains(err.Error(), test.errorContains) {
2292			t.Errorf("#%d: expected error containing %q, got %s", i, test.errorContains, err)
2293		}
2294	}
2295}
2296