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.
10 "crypto/internal/boring/fipstls"
25 func TestBoringServerProtocolVersion(t *testing.T) {
26 test := func(name string, v uint16, msg string) {
27 t.Run(name, func(t *testing.T) {
28 serverConfig := testConfig.Clone()
29 serverConfig.MinVersion = VersionSSL30
30 clientHello := &clientHelloMsg{
32 random: make([]byte, 32),
33 cipherSuites: allCipherSuites(),
34 compressionMethods: []uint8{compressionNone},
35 supportedVersions: []uint16{v},
37 testClientHelloFailure(t, serverConfig, clientHello, msg)
41 test("VersionSSL30", VersionSSL30, "")
42 test("VersionTLS10", VersionTLS10, "")
43 test("VersionTLS11", VersionTLS11, "")
44 test("VersionTLS12", VersionTLS12, "")
45 test("VersionTLS13", VersionTLS13, "")
48 defer fipstls.Abandon()
49 test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
50 test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
51 test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
52 test("VersionTLS12", VersionTLS12, "")
53 test("VersionTLS13", VersionTLS13, "client offered only unsupported versions")
56 func isBoringVersion(v uint16) bool {
57 return v == VersionTLS12
60 func isBoringCipherSuite(id uint16) bool {
62 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
63 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
64 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
65 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
66 TLS_RSA_WITH_AES_128_GCM_SHA256,
67 TLS_RSA_WITH_AES_256_GCM_SHA384:
73 func isBoringCurve(id CurveID) bool {
75 case CurveP256, CurveP384, CurveP521:
81 func isECDSA(id uint16) bool {
82 for _, suite := range cipherSuites {
84 return suite.flags&suiteECSign == suiteECSign
87 panic(fmt.Sprintf("unknown cipher suite %#x", id))
90 func isBoringSignatureScheme(alg SignatureScheme) bool {
95 ECDSAWithP256AndSHA256,
97 ECDSAWithP384AndSHA384,
99 ECDSAWithP521AndSHA512,
108 func TestBoringServerCipherSuites(t *testing.T) {
109 serverConfig := testConfig.Clone()
110 serverConfig.CipherSuites = allCipherSuites()
111 serverConfig.Certificates = make([]Certificate, 1)
113 for _, id := range allCipherSuites() {
115 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
116 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
118 serverConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
119 serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
121 serverConfig.BuildNameToCertificate()
122 t.Run(fmt.Sprintf("suite=%#x", id), func(t *testing.T) {
123 clientHello := &clientHelloMsg{
125 random: make([]byte, 32),
126 cipherSuites: []uint16{id},
127 compressionMethods: []uint8{compressionNone},
128 supportedCurves: defaultCurvePreferences,
129 supportedPoints: []uint8{pointFormatUncompressed},
132 testClientHello(t, serverConfig, clientHello)
133 t.Run("fipstls", func(t *testing.T) {
135 defer fipstls.Abandon()
137 if !isBoringCipherSuite(id) {
138 msg = "no cipher suite supported by both client and server"
140 testClientHelloFailure(t, serverConfig, clientHello, msg)
146 func TestBoringServerCurves(t *testing.T) {
147 serverConfig := testConfig.Clone()
148 serverConfig.Certificates = make([]Certificate, 1)
149 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
150 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
151 serverConfig.BuildNameToCertificate()
153 for _, curveid := range defaultCurvePreferences {
154 t.Run(fmt.Sprintf("curve=%d", curveid), func(t *testing.T) {
155 clientHello := &clientHelloMsg{
157 random: make([]byte, 32),
158 cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
159 compressionMethods: []uint8{compressionNone},
160 supportedCurves: []CurveID{curveid},
161 supportedPoints: []uint8{pointFormatUncompressed},
164 testClientHello(t, serverConfig, clientHello)
166 // With fipstls forced, bad curves should be rejected.
167 t.Run("fipstls", func(t *testing.T) {
169 defer fipstls.Abandon()
171 if !isBoringCurve(curveid) {
172 msg = "no cipher suite supported by both client and server"
174 testClientHelloFailure(t, serverConfig, clientHello, msg)
180 func boringHandshake(t *testing.T, clientConfig, serverConfig *Config) (clientErr, serverErr error) {
182 client := Client(c, clientConfig)
183 server := Server(s, serverConfig)
184 done := make(chan error, 1)
186 done <- client.Handshake()
189 serverErr = server.Handshake()
195 func TestBoringServerSignatureAndHash(t *testing.T) {
197 testingOnlyForceClientHelloSignatureAlgorithms = nil
200 for _, sigHash := range defaultSupportedSignatureAlgorithms {
201 t.Run(fmt.Sprintf("%#x", sigHash), func(t *testing.T) {
202 serverConfig := testConfig.Clone()
203 serverConfig.Certificates = make([]Certificate, 1)
205 testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash}
207 switch signatureFromSignatureScheme(sigHash) {
208 case signaturePKCS1v15, signatureRSAPSS:
209 serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
210 serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
211 serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey
212 case signatureEd25519:
213 serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
214 serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
215 serverConfig.Certificates[0].PrivateKey = testEd25519PrivateKey
217 serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
218 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
219 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
221 serverConfig.BuildNameToCertificate()
222 // PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
223 // 1.3, and the ECDSA ones bind to the curve used.
224 // RSA-PSS signatures are not supported in TLS 1.2. Issue 32425.
225 if signatureFromSignatureScheme(sigHash) != signatureRSAPSS {
226 serverConfig.MaxVersion = VersionTLS12
229 clientErr, serverErr := boringHandshake(t, testConfig, serverConfig)
230 if clientErr != nil {
231 t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
234 // With fipstls forced, bad curves should be rejected.
235 t.Run("fipstls", func(t *testing.T) {
237 defer fipstls.Abandon()
238 clientErr, _ := boringHandshake(t, testConfig, serverConfig)
239 // RSA-PSS is only supported in TLS 1.3, prohibited by forcing fipstls. Issue 32425.
240 if isBoringSignatureScheme(sigHash) && signatureFromSignatureScheme(sigHash) != signatureRSAPSS {
241 if clientErr != nil {
242 t.Fatalf("expected handshake with %#x to succeed; err=%v", sigHash, clientErr)
245 if clientErr == nil {
246 t.Fatalf("expected handshake with %#x to fail, but it succeeded", sigHash)
254 func TestBoringClientHello(t *testing.T) {
255 // Test that no matter what we put in the client config,
256 // the client does not offer non-FIPS configurations.
258 defer fipstls.Abandon()
264 clientConfig := testConfig.Clone()
265 // All sorts of traps for the client to avoid.
266 clientConfig.MinVersion = VersionSSL30
267 clientConfig.MaxVersion = VersionTLS13
268 clientConfig.CipherSuites = allCipherSuites()
269 clientConfig.CurvePreferences = defaultCurvePreferences
271 go Client(c, testConfig).Handshake()
272 srv := Server(s, testConfig)
273 msg, err := srv.readHandshake()
277 hello, ok := msg.(*clientHelloMsg)
279 t.Fatalf("unexpected message type %T", msg)
282 if !isBoringVersion(hello.vers) {
283 t.Errorf("client vers=%#x, want %#x (TLS 1.2)", hello.vers, VersionTLS12)
285 for _, v := range hello.supportedVersions {
286 if !isBoringVersion(v) {
287 t.Errorf("client offered disallowed version %#x", v)
290 for _, id := range hello.cipherSuites {
291 if !isBoringCipherSuite(id) {
292 t.Errorf("client offered disallowed suite %#x", id)
295 for _, id := range hello.supportedCurves {
296 if !isBoringCurve(id) {
297 t.Errorf("client offered disallowed curve %d", id)
300 for _, sigHash := range hello.supportedSignatureAlgorithms {
301 if !isBoringSignatureScheme(sigHash) {
302 t.Errorf("client offered disallowed signature-and-hash %v", sigHash)
307 func TestBoringCertAlgs(t *testing.T) {
308 // NaCl, arm and wasm time out generating keys. Nothing in this test is architecture-specific, so just don't bother on those.
309 if runtime.GOOS == "nacl" || runtime.GOARCH == "arm" || runtime.GOOS == "js" {
310 t.Skipf("skipping on %s/%s because key generation takes too long", runtime.GOOS, runtime.GOARCH)
313 // Set up some roots, intermediate CAs, and leaf certs with various algorithms.
314 // X_Y is X signed by Y.
315 R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
316 R2 := boringCert(t, "R2", boringRSAKey(t, 4096), nil, boringCertCA)
318 M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
319 M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
321 I_R1 := boringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK)
322 I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK)
323 I_M1 := boringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
324 I_M2 := boringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
326 L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
327 L2_I := boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
329 // boringCert checked that isBoringCertificate matches the caller's boringCertFIPSOK bit.
330 // If not, no point in building bigger end-to-end tests.
332 t.Fatalf("isBoringCertificate failures; not continuing")
335 // client verifying server cert
336 testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
337 clientConfig := testConfig.Clone()
338 clientConfig.RootCAs = pool
339 clientConfig.InsecureSkipVerify = false
340 clientConfig.ServerName = "example.com"
342 serverConfig := testConfig.Clone()
343 serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
344 serverConfig.BuildNameToCertificate()
346 clientErr, _ := boringHandshake(t, clientConfig, serverConfig)
348 if (clientErr == nil) == ok {
350 t.Logf("%s: accept", desc)
352 t.Logf("%s: reject", desc)
356 t.Errorf("%s: BAD reject (%v)", desc, clientErr)
358 t.Errorf("%s: BAD accept", desc)
363 // server verifying client cert
364 testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
365 clientConfig := testConfig.Clone()
366 clientConfig.ServerName = "example.com"
367 clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
369 serverConfig := testConfig.Clone()
370 serverConfig.ClientCAs = pool
371 serverConfig.ClientAuth = RequireAndVerifyClientCert
373 _, serverErr := boringHandshake(t, clientConfig, serverConfig)
375 if (serverErr == nil) == ok {
377 t.Logf("%s: accept", desc)
379 t.Logf("%s: reject", desc)
383 t.Errorf("%s: BAD reject (%v)", desc, serverErr)
385 t.Errorf("%s: BAD accept", desc)
390 // Run simple basic test with known answers before proceeding to
391 // exhaustive test with computed answers.
392 r1pool := x509.NewCertPool()
393 r1pool.AddCert(R1.cert)
394 testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
395 testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
397 testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
398 testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
402 t.Fatal("basic test failed, skipping exhaustive test")
406 t.Logf("basic test passed; skipping exhaustive test in -short mode")
410 for l := 1; l <= 2; l++ {
415 for i := 0; i < 64; i++ {
416 reachable := map[string]bool{leaf.parentOrg: true}
417 reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK}
418 list := [][]byte{leaf.der}
419 listName := leaf.name
420 addList := func(cond int, c *boringCertificate) {
422 list = append(list, c.der)
423 listName += "," + c.name
424 if reachable[c.org] {
425 reachable[c.parentOrg] = true
427 if reachableFIPS[c.org] && c.fipsOK {
428 reachableFIPS[c.parentOrg] = true
439 for r := 1; r <= 3; r++ {
440 pool := x509.NewCertPool()
442 shouldVerify := false
443 shouldVerifyFIPS := false
444 addRoot := func(cond int, c *boringCertificate) {
446 rootName += "," + c.name
448 if reachable[c.org] {
451 if reachableFIPS[c.org] && c.fipsOK {
452 shouldVerifyFIPS = true
458 rootName = rootName[1:] // strip leading comma
459 testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
460 testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
462 testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
463 testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
473 boringCertFIPSOK = 0x80
476 func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey {
477 k, err := rsa.GenerateKey(rand.Reader, size)
484 func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
485 k, err := ecdsa.GenerateKey(curve, rand.Reader)
492 type boringCertificate struct {
497 cert *x509.Certificate
502 func boringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate {
505 if i := strings.Index(org, "_"); i >= 0 {
507 parentOrg = name[i+1:]
509 tmpl := &x509.Certificate{
510 SerialNumber: big.NewInt(1),
512 Organization: []string{org},
514 NotBefore: time.Unix(0, 0),
515 NotAfter: time.Unix(0, 0),
517 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
518 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
519 BasicConstraintsValid: true,
521 if mode&^boringCertFIPSOK == boringCertLeaf {
522 tmpl.DNSNames = []string{"example.com"}
525 tmpl.KeyUsage |= x509.KeyUsageCertSign
528 var pcert *x509.Certificate
540 switch k := key.(type) {
541 case *rsa.PrivateKey:
543 desc = fmt.Sprintf("RSA-%d", k.N.BitLen())
544 case *ecdsa.PrivateKey:
546 desc = "ECDSA-" + k.Curve.Params().Name
548 t.Fatalf("invalid key %T", key)
551 der, err := x509.CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
555 cert, err := x509.ParseCertificate(der)
560 // Tell isBoringCertificate to enforce FIPS restrictions for this check.
562 defer fipstls.Abandon()
564 fipsOK := mode&boringCertFIPSOK != 0
565 if isBoringCertificate(cert) != fipsOK {
566 t.Errorf("isBoringCertificate(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
568 return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK}
571 // A self-signed test certificate with an RSA key of size 2048, for testing
572 // RSA-PSS with SHA512. SAN of example.golang.
574 testRSA2048Certificate []byte
575 testRSA2048PrivateKey *rsa.PrivateKey
579 block, _ := pem.Decode([]byte(`
580 -----BEGIN CERTIFICATE-----
581 MIIC/zCCAeegAwIBAgIRALHHX/kh4+4zMU9DarzBEcQwDQYJKoZIhvcNAQELBQAw
582 EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xMTAxMDExNTA0MDVaFw0yMDEyMjkxNTA0
583 MDVaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
584 ggEKAoIBAQCf8fk0N6ieCBX4IOVIfKitt4kGcOQLeimCfsjqqHcysMIVGEtFSM6E
585 4Ay141f/7IqdW0UtIqNb4PXhROID7yDxR284xL6XbCuv/t5hP3UcehYc3hmLiyVd
586 MkZQiZWtfUUJf/1qOtM+ohNg59LRWp4d+6iX0la1JL3EwCIckkNjJ9hQbF7Pb2CS
587 +ES9Yo55KAap8KOblpcR8MBSN38bqnwjfQdCXvOEOjam2HUxKzEFX5MA+fA0me4C
588 ioCcCRLWKl+GoN9F8fABfoZ+T+2eal4DLuO95rXR8SrOIVBh3XFOr/RVhjtXcNVF
589 ZKcvDt6d68V6jAKAYKm5nlj9GPpd4v+rAgMBAAGjUDBOMA4GA1UdDwEB/wQEAwIF
590 oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCC
591 DmV4YW1wbGUuZ29sYW5nMA0GCSqGSIb3DQEBCwUAA4IBAQCOoYsVcFCBhboqe3WH
592 dC6V7XXXECmnjh01r8h80yv0NR379nSD3cw2M+HKvaXysWqrl5hjGVKw0vtwD81r
593 V4JzDu7IfIog5m8+QNC+7LqDZsz88vDKOrsoySVOmUCgmCKFXew+LA+eO/iQEJTr
594 7ensddOeXJEp27Ed5vW+kmWW3Qmglc2Gwy8wFrMDIqnrnOzBA4oCnDEgtXJt0zog
595 nRwbfEMAWi1aQRy5dT9KA3SP9mo5SeTFSzGGHiE4s4gHUe7jvsAFF2qgtD6+wH6s
596 z9b6shxnC7g5IlBKhI7SVB/Uqt2ydJ+kH1YbjMcIq6NAM5eNMKgZuJr3+zwsSgwh
598 -----END CERTIFICATE-----`))
599 testRSA2048Certificate = block.Bytes
601 block, _ = pem.Decode([]byte(`
602 -----BEGIN RSA PRIVATE KEY-----
603 MIIEpAIBAAKCAQEAn/H5NDeonggV+CDlSHyorbeJBnDkC3opgn7I6qh3MrDCFRhL
604 RUjOhOAMteNX/+yKnVtFLSKjW+D14UTiA+8g8UdvOMS+l2wrr/7eYT91HHoWHN4Z
605 i4slXTJGUImVrX1FCX/9ajrTPqITYOfS0VqeHfuol9JWtSS9xMAiHJJDYyfYUGxe
606 z29gkvhEvWKOeSgGqfCjm5aXEfDAUjd/G6p8I30HQl7zhDo2pth1MSsxBV+TAPnw
607 NJnuAoqAnAkS1ipfhqDfRfHwAX6Gfk/tnmpeAy7jvea10fEqziFQYd1xTq/0VYY7
608 V3DVRWSnLw7enevFeowCgGCpuZ5Y/Rj6XeL/qwIDAQABAoIBAQCNpMZifd/vg42h
609 HdCvLuZaYS0R7SunFlpoXEsltGdLFsnp0IfoJZ/ugFQBSAIIfLwMumU6oXA1z7Uv
610 98aIYV61DePrTCDVDFBsHbNmP8JAo8WtbusEbwd5zyoB7LYG2+clkJklWE73KqUq
611 rmI+UJeyScl2Gin7ZTxBXz1WPBk9VwcnwkeaXpgASIBW23fhECM9gnYEEwaBez5T
612 6Me8d1tHtYQv7vsKe7ro9w9/HKrRXejqYKK1LxkhfFriyV+m8LZJZn2nXOa6G3gF
613 Nb8Qk1Uk5PUBENBmyMFJhT4M/uuSq4YtMrrO2gi8Q+fPhuGzc5SshYKRBp0W4P5r
614 mtVCtEFRAoGBAMENBIFLrV2+HsGj0xYFasKov/QPe6HSTR1Hh2IZONp+oK4oszWE
615 jBT4VcnITmpl6tC1Wy4GcrxjNgKIFZAj+1x1LUULdorXkuG8yr0tAhG9zNyfWsSy
616 PrSovC0UVbzr8Jxxla+kQVxEQQqWQxPlEVuL8kXaIDA6Lyt1Hpua2LvPAoGBANQZ
617 c6Lq2T7+BxLxNdi2m8kZzej5kgzBp/XdVsbFWRlebIX2KrFHsrHzT9PUk3DE1vZK
618 M6pzTt94nQhWSkDgCaw1SohElJ3HFIFwcusF1SJAc3pQepd8ug6IYdlpDMLtBj/P
619 /5P6BVUtgo05E4+I/T3iYatmglQxTtlZ0RkSV2llAoGBALOXkKFX7ahPvf0WksDh
620 uTfuFOTPoowgQG0EpgW0wRdCxeg/JLic3lSD0gsttQV2WsRecryWcxaelRg10RmO
621 38BbogmhaF4xvgsSvujOfiZTE8oK1T43M+6NKsIlML3YILbpU/9aJxPWy0s2DqDr
622 cQJhZrlk+pzjBA7Bnf/URdwxAoGAKR/CNw14D+mrL3YLbbiCXiydqxVwxv5pdZdz
623 8thi3TNcsWC4iGURdcVqbfUinVPdJiXe/Kac3WGCeRJaFVgbKAOxLti1RB5MkIhg
624 D8eyupBqk4W1L1gkrxqsdj4TFlxkwMywjl2E2S4YyQ8PBt6V04DoVRZsIKzqz+PF
625 UionPq0CgYBCYXvqioJhPewkOq/Y5wrDBeZW1FQK5QD9W5M8/5zxd4rdvJtjhbJp
626 oOrtvMdrl6upy9Hz4BJD3FXwVFiPFE7jqeNqi0F21viLxBPMMD3UODF6LL5EyLiR
627 9V4xVMS8KXxvg7rxsuqzMPscViaWUL6WNVBhsD2+92dHxSXzz5EJKQ==
628 -----END RSA PRIVATE KEY-----`))
630 testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)