1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build boringcrypto
6
7package tls
8
9import (
10	"crypto/ecdsa"
11	"crypto/elliptic"
12	"crypto/internal/boring/fipstls"
13	"crypto/rand"
14	"crypto/rsa"
15	"crypto/x509"
16	"crypto/x509/pkix"
17	"encoding/pem"
18	"fmt"
19	"internal/obscuretestdata"
20	"math/big"
21	"net"
22	"runtime"
23	"strings"
24	"testing"
25	"time"
26)
27
28func TestBoringServerProtocolVersion(t *testing.T) {
29	test := func(t *testing.T, name string, v uint16, msg string) {
30		t.Run(name, func(t *testing.T) {
31			serverConfig := testConfig.Clone()
32			serverConfig.MinVersion = VersionSSL30
33			clientConfig := testConfig.Clone()
34			clientConfig.MinVersion = v
35			clientConfig.MaxVersion = v
36			_, _, err := testHandshake(t, clientConfig, serverConfig)
37			if msg == "" {
38				if err != nil {
39					t.Fatalf("got error: %v, expected success", err)
40				}
41			} else {
42				if err == nil {
43					t.Fatalf("got success, expected error")
44				}
45				if !strings.Contains(err.Error(), msg) {
46					t.Fatalf("got error %v, expected %q", err, msg)
47				}
48			}
49		})
50	}
51
52	test(t, "VersionTLS10", VersionTLS10, "")
53	test(t, "VersionTLS11", VersionTLS11, "")
54	test(t, "VersionTLS12", VersionTLS12, "")
55	test(t, "VersionTLS13", VersionTLS13, "")
56
57	t.Run("fipstls", func(t *testing.T) {
58		fipstls.Force()
59		defer fipstls.Abandon()
60		test(t, "VersionTLS10", VersionTLS10, "supported versions")
61		test(t, "VersionTLS11", VersionTLS11, "supported versions")
62		test(t, "VersionTLS12", VersionTLS12, "")
63		test(t, "VersionTLS13", VersionTLS13, "supported versions")
64	})
65}
66
67func isBoringVersion(v uint16) bool {
68	return v == VersionTLS12
69}
70
71func isBoringCipherSuite(id uint16) bool {
72	switch id {
73	case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
74		TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
75		TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
76		TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
77		TLS_RSA_WITH_AES_128_GCM_SHA256,
78		TLS_RSA_WITH_AES_256_GCM_SHA384:
79		return true
80	}
81	return false
82}
83
84func isBoringCurve(id CurveID) bool {
85	switch id {
86	case CurveP256, CurveP384, CurveP521:
87		return true
88	}
89	return false
90}
91
92func isECDSA(id uint16) bool {
93	for _, suite := range cipherSuites {
94		if suite.id == id {
95			return suite.flags&suiteECSign == suiteECSign
96		}
97	}
98	panic(fmt.Sprintf("unknown cipher suite %#x", id))
99}
100
101func isBoringSignatureScheme(alg SignatureScheme) bool {
102	switch alg {
103	default:
104		return false
105	case PKCS1WithSHA256,
106		ECDSAWithP256AndSHA256,
107		PKCS1WithSHA384,
108		ECDSAWithP384AndSHA384,
109		PKCS1WithSHA512,
110		ECDSAWithP521AndSHA512,
111		PSSWithSHA256,
112		PSSWithSHA384,
113		PSSWithSHA512:
114		// ok
115	}
116	return true
117}
118
119func TestBoringServerCipherSuites(t *testing.T) {
120	serverConfig := testConfig.Clone()
121	serverConfig.CipherSuites = allCipherSuites()
122	serverConfig.Certificates = make([]Certificate, 1)
123
124	for _, id := range allCipherSuites() {
125		if isECDSA(id) {
126			serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
127			serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
128		} else {
129			serverConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
130			serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
131		}
132		serverConfig.BuildNameToCertificate()
133		t.Run(fmt.Sprintf("suite=%#x", id), func(t *testing.T) {
134			clientHello := &clientHelloMsg{
135				vers:               VersionTLS12,
136				random:             make([]byte, 32),
137				cipherSuites:       []uint16{id},
138				compressionMethods: []uint8{compressionNone},
139				supportedCurves:    defaultCurvePreferences(),
140				supportedPoints:    []uint8{pointFormatUncompressed},
141			}
142
143			testClientHello(t, serverConfig, clientHello)
144			t.Run("fipstls", func(t *testing.T) {
145				fipstls.Force()
146				defer fipstls.Abandon()
147				msg := ""
148				if !isBoringCipherSuite(id) {
149					msg = "no cipher suite supported by both client and server"
150				}
151				testClientHelloFailure(t, serverConfig, clientHello, msg)
152			})
153		})
154	}
155}
156
157func TestBoringServerCurves(t *testing.T) {
158	serverConfig := testConfig.Clone()
159	serverConfig.Certificates = make([]Certificate, 1)
160	serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
161	serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
162	serverConfig.BuildNameToCertificate()
163
164	for _, curveid := range defaultCurvePreferences() {
165		t.Run(fmt.Sprintf("curve=%d", curveid), func(t *testing.T) {
166			clientConfig := testConfig.Clone()
167			clientConfig.CurvePreferences = []CurveID{curveid}
168			if curveid == x25519Kyber768Draft00 {
169				// x25519Kyber768Draft00 is not supported standalone.
170				clientConfig.CurvePreferences = append(clientConfig.CurvePreferences, X25519)
171			}
172			if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
173				t.Fatalf("got error: %v, expected success", err)
174			}
175
176			// With fipstls forced, bad curves should be rejected.
177			t.Run("fipstls", func(t *testing.T) {
178				fipstls.Force()
179				defer fipstls.Abandon()
180				_, _, err := testHandshake(t, clientConfig, serverConfig)
181				if err != nil && isBoringCurve(curveid) {
182					t.Fatalf("got error: %v, expected success", err)
183				} else if err == nil && !isBoringCurve(curveid) {
184					t.Fatalf("got success, expected error")
185				}
186			})
187		})
188	}
189}
190
191func boringHandshake(t *testing.T, clientConfig, serverConfig *Config) (clientErr, serverErr error) {
192	c, s := localPipe(t)
193	client := Client(c, clientConfig)
194	server := Server(s, serverConfig)
195	done := make(chan error, 1)
196	go func() {
197		done <- client.Handshake()
198		c.Close()
199	}()
200	serverErr = server.Handshake()
201	s.Close()
202	clientErr = <-done
203	return
204}
205
206func TestBoringServerSignatureAndHash(t *testing.T) {
207	defer func() {
208		testingOnlyForceClientHelloSignatureAlgorithms = nil
209	}()
210
211	for _, sigHash := range defaultSupportedSignatureAlgorithms {
212		t.Run(fmt.Sprintf("%v", sigHash), func(t *testing.T) {
213			serverConfig := testConfig.Clone()
214			serverConfig.Certificates = make([]Certificate, 1)
215
216			testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash}
217
218			sigType, _, _ := typeAndHashFromSignatureScheme(sigHash)
219			switch sigType {
220			case signaturePKCS1v15, signatureRSAPSS:
221				serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
222				serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
223				serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey
224			case signatureEd25519:
225				serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
226				serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
227				serverConfig.Certificates[0].PrivateKey = testEd25519PrivateKey
228			case signatureECDSA:
229				serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
230				serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
231				serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
232			}
233			serverConfig.BuildNameToCertificate()
234			// PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
235			// 1.3, and the ECDSA ones bind to the curve used.
236			serverConfig.MaxVersion = VersionTLS12
237
238			clientErr, serverErr := boringHandshake(t, testConfig, serverConfig)
239			if clientErr != nil {
240				t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
241			}
242
243			// With fipstls forced, bad curves should be rejected.
244			t.Run("fipstls", func(t *testing.T) {
245				fipstls.Force()
246				defer fipstls.Abandon()
247				clientErr, _ := boringHandshake(t, testConfig, serverConfig)
248				if isBoringSignatureScheme(sigHash) {
249					if clientErr != nil {
250						t.Fatalf("expected handshake with %#x to succeed; err=%v", sigHash, clientErr)
251					}
252				} else {
253					if clientErr == nil {
254						t.Fatalf("expected handshake with %#x to fail, but it succeeded", sigHash)
255					}
256				}
257			})
258		})
259	}
260}
261
262func TestBoringClientHello(t *testing.T) {
263	// Test that no matter what we put in the client config,
264	// the client does not offer non-FIPS configurations.
265	fipstls.Force()
266	defer fipstls.Abandon()
267
268	c, s := net.Pipe()
269	defer c.Close()
270	defer s.Close()
271
272	clientConfig := testConfig.Clone()
273	// All sorts of traps for the client to avoid.
274	clientConfig.MinVersion = VersionSSL30
275	clientConfig.MaxVersion = VersionTLS13
276	clientConfig.CipherSuites = allCipherSuites()
277	clientConfig.CurvePreferences = defaultCurvePreferences()
278
279	go Client(c, clientConfig).Handshake()
280	srv := Server(s, testConfig)
281	msg, err := srv.readHandshake(nil)
282	if err != nil {
283		t.Fatal(err)
284	}
285	hello, ok := msg.(*clientHelloMsg)
286	if !ok {
287		t.Fatalf("unexpected message type %T", msg)
288	}
289
290	if !isBoringVersion(hello.vers) {
291		t.Errorf("client vers=%#x, want %#x (TLS 1.2)", hello.vers, VersionTLS12)
292	}
293	for _, v := range hello.supportedVersions {
294		if !isBoringVersion(v) {
295			t.Errorf("client offered disallowed version %#x", v)
296		}
297	}
298	for _, id := range hello.cipherSuites {
299		if !isBoringCipherSuite(id) {
300			t.Errorf("client offered disallowed suite %#x", id)
301		}
302	}
303	for _, id := range hello.supportedCurves {
304		if !isBoringCurve(id) {
305			t.Errorf("client offered disallowed curve %d", id)
306		}
307	}
308	for _, sigHash := range hello.supportedSignatureAlgorithms {
309		if !isBoringSignatureScheme(sigHash) {
310			t.Errorf("client offered disallowed signature-and-hash %v", sigHash)
311		}
312	}
313}
314
315func TestBoringCertAlgs(t *testing.T) {
316	// NaCl, arm and wasm time out generating keys. Nothing in this test is architecture-specific, so just don't bother on those.
317	if runtime.GOOS == "nacl" || runtime.GOARCH == "arm" || runtime.GOOS == "js" {
318		t.Skipf("skipping on %s/%s because key generation takes too long", runtime.GOOS, runtime.GOARCH)
319	}
320
321	// Set up some roots, intermediate CAs, and leaf certs with various algorithms.
322	// X_Y is X signed by Y.
323	R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
324	R2 := boringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA)
325
326	M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
327	M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
328
329	I_R1 := boringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK)
330	I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK)
331	I_M1 := boringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
332	I_M2 := boringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
333
334	L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
335	L2_I := boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
336
337	// client verifying server cert
338	testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
339		clientConfig := testConfig.Clone()
340		clientConfig.RootCAs = pool
341		clientConfig.InsecureSkipVerify = false
342		clientConfig.ServerName = "example.com"
343
344		serverConfig := testConfig.Clone()
345		serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
346		serverConfig.BuildNameToCertificate()
347
348		clientErr, _ := boringHandshake(t, clientConfig, serverConfig)
349
350		if (clientErr == nil) == ok {
351			if ok {
352				t.Logf("%s: accept", desc)
353			} else {
354				t.Logf("%s: reject", desc)
355			}
356		} else {
357			if ok {
358				t.Errorf("%s: BAD reject (%v)", desc, clientErr)
359			} else {
360				t.Errorf("%s: BAD accept", desc)
361			}
362		}
363	}
364
365	// server verifying client cert
366	testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
367		clientConfig := testConfig.Clone()
368		clientConfig.ServerName = "example.com"
369		clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
370
371		serverConfig := testConfig.Clone()
372		serverConfig.ClientCAs = pool
373		serverConfig.ClientAuth = RequireAndVerifyClientCert
374
375		_, serverErr := boringHandshake(t, clientConfig, serverConfig)
376
377		if (serverErr == nil) == ok {
378			if ok {
379				t.Logf("%s: accept", desc)
380			} else {
381				t.Logf("%s: reject", desc)
382			}
383		} else {
384			if ok {
385				t.Errorf("%s: BAD reject (%v)", desc, serverErr)
386			} else {
387				t.Errorf("%s: BAD accept", desc)
388			}
389		}
390	}
391
392	// Run simple basic test with known answers before proceeding to
393	// exhaustive test with computed answers.
394	r1pool := x509.NewCertPool()
395	r1pool.AddCert(R1.cert)
396	testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
397	testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
398	fipstls.Force()
399	testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
400	testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
401	fipstls.Abandon()
402
403	if t.Failed() {
404		t.Fatal("basic test failed, skipping exhaustive test")
405	}
406
407	if testing.Short() {
408		t.Logf("basic test passed; skipping exhaustive test in -short mode")
409		return
410	}
411
412	for l := 1; l <= 2; l++ {
413		leaf := L1_I
414		if l == 2 {
415			leaf = L2_I
416		}
417		for i := 0; i < 64; i++ {
418			reachable := map[string]bool{leaf.parentOrg: true}
419			reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK}
420			list := [][]byte{leaf.der}
421			listName := leaf.name
422			addList := func(cond int, c *boringCertificate) {
423				if cond != 0 {
424					list = append(list, c.der)
425					listName += "," + c.name
426					if reachable[c.org] {
427						reachable[c.parentOrg] = true
428					}
429					if reachableFIPS[c.org] && c.fipsOK {
430						reachableFIPS[c.parentOrg] = true
431					}
432				}
433			}
434			addList(i&1, I_R1)
435			addList(i&2, I_R2)
436			addList(i&4, I_M1)
437			addList(i&8, I_M2)
438			addList(i&16, M1_R1)
439			addList(i&32, M2_R1)
440
441			for r := 1; r <= 3; r++ {
442				pool := x509.NewCertPool()
443				rootName := ","
444				shouldVerify := false
445				shouldVerifyFIPS := false
446				addRoot := func(cond int, c *boringCertificate) {
447					if cond != 0 {
448						rootName += "," + c.name
449						pool.AddCert(c.cert)
450						if reachable[c.org] {
451							shouldVerify = true
452						}
453						if reachableFIPS[c.org] && c.fipsOK {
454							shouldVerifyFIPS = true
455						}
456					}
457				}
458				addRoot(r&1, R1)
459				addRoot(r&2, R2)
460				rootName = rootName[1:] // strip leading comma
461				testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
462				testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
463				fipstls.Force()
464				testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
465				testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
466				fipstls.Abandon()
467			}
468		}
469	}
470}
471
472const (
473	boringCertCA = iota
474	boringCertLeaf
475	boringCertFIPSOK = 0x80
476)
477
478func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey {
479	k, err := rsa.GenerateKey(rand.Reader, size)
480	if err != nil {
481		t.Fatal(err)
482	}
483	return k
484}
485
486func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
487	k, err := ecdsa.GenerateKey(curve, rand.Reader)
488	if err != nil {
489		t.Fatal(err)
490	}
491	return k
492}
493
494type boringCertificate struct {
495	name      string
496	org       string
497	parentOrg string
498	der       []byte
499	cert      *x509.Certificate
500	key       interface{}
501	fipsOK    bool
502}
503
504func boringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate {
505	org := name
506	parentOrg := ""
507	if i := strings.Index(org, "_"); i >= 0 {
508		org = org[:i]
509		parentOrg = name[i+1:]
510	}
511	tmpl := &x509.Certificate{
512		SerialNumber: big.NewInt(1),
513		Subject: pkix.Name{
514			Organization: []string{org},
515		},
516		NotBefore: time.Unix(0, 0),
517		NotAfter:  time.Unix(0, 0),
518
519		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
520		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
521		BasicConstraintsValid: true,
522	}
523	if mode&^boringCertFIPSOK == boringCertLeaf {
524		tmpl.DNSNames = []string{"example.com"}
525	} else {
526		tmpl.IsCA = true
527		tmpl.KeyUsage |= x509.KeyUsageCertSign
528	}
529
530	var pcert *x509.Certificate
531	var pkey interface{}
532	if parent != nil {
533		pcert = parent.cert
534		pkey = parent.key
535	} else {
536		pcert = tmpl
537		pkey = key
538	}
539
540	var pub interface{}
541	switch k := key.(type) {
542	case *rsa.PrivateKey:
543		pub = &k.PublicKey
544	case *ecdsa.PrivateKey:
545		pub = &k.PublicKey
546	default:
547		t.Fatalf("invalid key %T", key)
548	}
549
550	der, err := x509.CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
551	if err != nil {
552		t.Fatal(err)
553	}
554	cert, err := x509.ParseCertificate(der)
555	if err != nil {
556		t.Fatal(err)
557	}
558
559	fipsOK := mode&boringCertFIPSOK != 0
560	return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK}
561}
562
563// A self-signed test certificate with an RSA key of size 2048, for testing
564// RSA-PSS with SHA512. SAN of example.golang.
565var (
566	testRSA2048Certificate []byte
567	testRSA2048PrivateKey  *rsa.PrivateKey
568)
569
570func init() {
571	block, _ := pem.Decode(obscuretestdata.Rot13([]byte(`
572-----ORTVA PREGVSVPNGR-----
573ZVVP/mPPNrrtNjVONtVENYUUK/xu4+4mZH9QnemORpDjQDLWXbMVuipANDRYODNj
574RwRDZN4TN1HRPuZUDJAgMFOQomNrSj0kZGNkZQRkAGN0ZQInSj0lZQRlZwxkAGN0
575ZQInZOVkRQNBOtAIONbGO0SwoJHtD28jttRvZN0TPFdTFVo3QDRONDHNN4VOQjNj
576ttRXNbVONDPs8sx0A6vrPOK4VBIVsXvgg4xTpBDYrvzPsfwddUplfZVITRgSFZ6R
5774Nl141s/7VdqJ0HgVdAo4CKuEBVQ7lQkE284kY6KoPhi/g5uC3HpruLp3uzYvlIq
578ZxMDvMJgsHHWs/1dBgZ+buAt59YEJc4q+6vK0yn1WY3RjPVpxxAwW9uDoS7Co2PF
579+RF9Lb55XNnc8XBoycpE8ZOFA38odajwsDqPKiBRBwnz2UHkXmRSK5ZN+sN0zr4P
580vbPpPEYJXy+TbA9S8sNOsbM+G+2rny4QYhB95eKE8FeBVIOu3KSBe/EIuwgKpAIS
581MXpiQg6q68I6wNXNLXz5ayw9TCcq4i+eNtZONNTwHQOBZN4TN1HqQjRO/jDRNjVS
582bQNGOtAIUFHRQQNXOtteOtRSODpQNGNZOtAIUEZONs8RNwNNZOxTN1HqRDDFZOPP
583QzI4LJ1joTHhM29fLJ5aZN0TPFdTFVo3QDROPjHNN4VONDPBbLfIpSPOuobdr3JU
584qP6I7KKKRPzawu01e8u80li0AE379aFQ3pj2Z+UXinKlfJdey5uwTIXj0igjQ81e
585I4WmQh7VsVbt5z8+DAP+7YdQMfm88iQXBefblFIBzHPtzPXSKrj+YN+rB/vDRWGe
5867rafqqBrKWRc27Rq5iJ+xzJJ3Dztyp2Tjl8jSeZQVdaeaBmON4bPaQRtgKWg0mbt
587aEjosRZNJv1nDEl5qG9XN3FC9zb5FrGSFmTTUvR4f4tUHr7wifNSS2dtgQ6+jU6f
588m9o6fukaP7t5VyOXuV7FIO/Hdg2lqW+xU1LowZpVd6ANZ5rAZXtMhWe3+mjfFtju
589TAnR
590-----RAQ PREGVSVPNGR-----`)))
591	testRSA2048Certificate = block.Bytes
592
593	block, _ = pem.Decode(obscuretestdata.Rot13([]byte(`
594-----ORTVA EFN CEVINGR XRL-----
595ZVVRcNVONNXPNDRNa/U5AQrbattI+PQyFUlbeorWOaQxP3bcta7V6du3ZeQPSEuY
596EHwBuBNZgrAK/+lXaIgSYFXwJ+Q14HGvN+8t8HqiBZF+y2jee/7rLG91UUbJUA4M
597v4fyKGWTHVzIeK1SPK/9nweGCdVGLBsF0IdrUshby9WJgFF9kZNvUWWQLlsLHTkr
598m29txiuRiJXBrFtTdsPwz5nKRsQNHwq/T6c8V30UDy7muQb2cgu1ZFfkOI+GNCaj
599AWahNbdNaNxF1vcsudQsEsUjNK6Tsx/gazcrNl7wirn10sRdmvSDLq1kGd/0ILL7
600I3QIEJFaYj7rariSrbjPtTPchM5L/Ew6KrY/djVQNDNONbVONDPAcZMvsq/it42u
601UqPiYhMnLF0E7FhaSycbKRfygTqYSfac0VsbWM/htSDOFNVVsYjZhzH6bKN1m7Hi
60298nVLI61QrCeGPQIQSOfUoAzC8WNb8JgohfRojq5mlbO7YLT2+pyxWxyJR73XdHd
603ezV+HWrlFpy2Tva7MGkOKm1JCOx9IjpajxrnKctNFVOJ23suRPZ9taLRRjnOrm5G
6046Zr8q1gUgLDi7ifXr7eb9j9/UXeEKrwdLXX1YkxusSevlI+z8YMWMa2aKBn6T3tS
605Ao8Dx1Hx5CHORAOzlZSWuG4Z/hhFd4LgZeeB2tv8D+sCuhTmp5FfuLXEOc0J4C5e
606zgIPgRSENbTONZRAOVSYeI2+UfTw0kLSnfXbi/DCr6UFGE1Uu2VMBAc+bX4bfmJR
607wOG4IpaVGzcy6gP1Jl4TpekwAtXVSMNw+1k1YHHYqbeKxhT8le0gNuT9mAlsJfFl
608CeFbiP0HIome8Wkkyn+xDIkRDDdJDkCyRIhY8xKnVQN6Ylg1Uchn2YiCNbTONADM
609p6Yd2G7+OkYkAqv2z8xMmrw5xtmOc/KqIfoSJEyroVK2XeSUfeUmG9CHx3QR1iMX
610Z6cmGg94aDuJFxQtPnj1FbuRyW3USVSjphfS1FWNp3cDrcq8ht6VLqycQZYgOw/C
611/5C6OIHgtb05R4+V/G3vLngztyDkGgyM0ExFI2yyNbTONYBKxXSK7nuCis0JxfQu
612hGshSBGCbbjtDT0RctJ0jEqPkrt/WYvp3yFQ0tfggDI2JfErpelJpknryEt10EzB
61338OobtzunS4kitfFihwBsvMGR8bX1G43Z+6AXfVyZY3LVYocH/9nWkCJl0f2QdQe
614pDWuMeyx+cmwON7Oas/HEqjkNbTNXE/PAj14Q+zeY3LYoovPKvlqdkIjki5cqMqm
6158guv3GApfJP4vTHEqpIdosHvaICqWvKr/Xnp3JTPrEWnSItoXNBkYgv1EO5ZxVut
616Q8rlhcOdx4J1Y1txekdfqw4GSykxjZljwy2R2F4LlD8COg6I04QbIEMfVXmdm+CS
617HvbaCd0PtLOPLKidvbWuCrjxBd/L5jeQOrMJ1SDX5DQ9J5Z8/5mkq4eqiWgwuoWc
618bBegiZqey6hcl9Um4OWQ3SKjISvCSR7wdrAdv0S21ivYkOCZZQ3HBQS6YY5RlYvE
6199I4kIZF8XKkit7ekfhdmZCfpIvnJHY6JAIOufQ2+92qUkFKmm5RWXD==
620-----RAQ EFN CEVINGR XRL-----`)))
621	var err error
622	testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
623	if err != nil {
624		panic(err)
625	}
626}
627