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("VersionTLS10", VersionTLS10, "")
42 test("VersionTLS11", VersionTLS11, "")
43 test("VersionTLS12", VersionTLS12, "")
44 test("VersionTLS13", VersionTLS13, "")
47 defer fipstls.Abandon()
48 test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
49 test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
50 test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
51 test("VersionTLS12", VersionTLS12, "")
52 test("VersionTLS13", VersionTLS13, "client offered only unsupported versions")
55 func isBoringVersion(v uint16) bool {
56 return v == VersionTLS12
59 func isBoringCipherSuite(id uint16) bool {
61 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
62 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
63 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
64 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
65 TLS_RSA_WITH_AES_128_GCM_SHA256,
66 TLS_RSA_WITH_AES_256_GCM_SHA384:
72 func isBoringCurve(id CurveID) bool {
74 case CurveP256, CurveP384, CurveP521:
80 func isECDSA(id uint16) bool {
81 for _, suite := range cipherSuites {
83 return suite.flags&suiteECSign == suiteECSign
86 panic(fmt.Sprintf("unknown cipher suite %#x", id))
89 func isBoringSignatureScheme(alg SignatureScheme) bool {
94 ECDSAWithP256AndSHA256,
96 ECDSAWithP384AndSHA384,
98 ECDSAWithP521AndSHA512,
107 func TestBoringServerCipherSuites(t *testing.T) {
108 serverConfig := testConfig.Clone()
109 serverConfig.CipherSuites = allCipherSuites()
110 serverConfig.Certificates = make([]Certificate, 1)
112 for _, id := range allCipherSuites() {
114 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
115 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
117 serverConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
118 serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
120 serverConfig.BuildNameToCertificate()
121 t.Run(fmt.Sprintf("suite=%#x", id), func(t *testing.T) {
122 clientHello := &clientHelloMsg{
124 random: make([]byte, 32),
125 cipherSuites: []uint16{id},
126 compressionMethods: []uint8{compressionNone},
127 supportedCurves: defaultCurvePreferences,
128 supportedPoints: []uint8{pointFormatUncompressed},
131 testClientHello(t, serverConfig, clientHello)
132 t.Run("fipstls", func(t *testing.T) {
134 defer fipstls.Abandon()
136 if !isBoringCipherSuite(id) {
137 msg = "no cipher suite supported by both client and server"
139 testClientHelloFailure(t, serverConfig, clientHello, msg)
145 func TestBoringServerCurves(t *testing.T) {
146 serverConfig := testConfig.Clone()
147 serverConfig.Certificates = make([]Certificate, 1)
148 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
149 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
150 serverConfig.BuildNameToCertificate()
152 for _, curveid := range defaultCurvePreferences {
153 t.Run(fmt.Sprintf("curve=%d", curveid), func(t *testing.T) {
154 clientHello := &clientHelloMsg{
156 random: make([]byte, 32),
157 cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
158 compressionMethods: []uint8{compressionNone},
159 supportedCurves: []CurveID{curveid},
160 supportedPoints: []uint8{pointFormatUncompressed},
163 testClientHello(t, serverConfig, clientHello)
165 // With fipstls forced, bad curves should be rejected.
166 t.Run("fipstls", func(t *testing.T) {
168 defer fipstls.Abandon()
170 if !isBoringCurve(curveid) {
171 msg = "no cipher suite supported by both client and server"
173 testClientHelloFailure(t, serverConfig, clientHello, msg)
179 func boringHandshake(t *testing.T, clientConfig, serverConfig *Config) (clientErr, serverErr error) {
181 client := Client(c, clientConfig)
182 server := Server(s, serverConfig)
183 done := make(chan error, 1)
185 done <- client.Handshake()
188 serverErr = server.Handshake()
194 func TestBoringServerSignatureAndHash(t *testing.T) {
196 testingOnlyForceClientHelloSignatureAlgorithms = nil
199 for _, sigHash := range defaultSupportedSignatureAlgorithms {
200 t.Run(fmt.Sprintf("%#x", sigHash), func(t *testing.T) {
201 serverConfig := testConfig.Clone()
202 serverConfig.Certificates = make([]Certificate, 1)
204 testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash}
206 switch signatureFromSignatureScheme(sigHash) {
207 case signaturePKCS1v15, signatureRSAPSS:
208 serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
209 serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
210 serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey
211 case signatureEd25519:
212 serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
213 serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
214 serverConfig.Certificates[0].PrivateKey = testEd25519PrivateKey
216 serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
217 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
218 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
220 serverConfig.BuildNameToCertificate()
221 // PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
222 // 1.3, and the ECDSA ones bind to the curve used.
223 // RSA-PSS signatures are not supported in TLS 1.2. Issue 32425.
224 if signatureFromSignatureScheme(sigHash) != signatureRSAPSS {
225 serverConfig.MaxVersion = VersionTLS12
228 clientErr, serverErr := boringHandshake(t, testConfig, serverConfig)
229 if clientErr != nil {
230 t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
233 // With fipstls forced, bad curves should be rejected.
234 t.Run("fipstls", func(t *testing.T) {
236 defer fipstls.Abandon()
237 clientErr, _ := boringHandshake(t, testConfig, serverConfig)
238 // RSA-PSS is only supported in TLS 1.3, prohibited by forcing fipstls. Issue 32425.
239 if isBoringSignatureScheme(sigHash) && signatureFromSignatureScheme(sigHash) != signatureRSAPSS {
240 if clientErr != nil {
241 t.Fatalf("expected handshake with %#x to succeed; err=%v", sigHash, clientErr)
244 if clientErr == nil {
245 t.Fatalf("expected handshake with %#x to fail, but it succeeded", sigHash)
253 func TestBoringClientHello(t *testing.T) {
254 // Test that no matter what we put in the client config,
255 // the client does not offer non-FIPS configurations.
257 defer fipstls.Abandon()
263 clientConfig := testConfig.Clone()
264 // All sorts of traps for the client to avoid.
265 clientConfig.MinVersion = VersionSSL30
266 clientConfig.MaxVersion = VersionTLS13
267 clientConfig.CipherSuites = allCipherSuites()
268 clientConfig.CurvePreferences = defaultCurvePreferences
270 go Client(c, testConfig).Handshake()
271 srv := Server(s, testConfig)
272 msg, err := srv.readHandshake()
276 hello, ok := msg.(*clientHelloMsg)
278 t.Fatalf("unexpected message type %T", msg)
281 if !isBoringVersion(hello.vers) {
282 t.Errorf("client vers=%#x, want %#x (TLS 1.2)", hello.vers, VersionTLS12)
284 for _, v := range hello.supportedVersions {
285 if !isBoringVersion(v) {
286 t.Errorf("client offered disallowed version %#x", v)
289 for _, id := range hello.cipherSuites {
290 if !isBoringCipherSuite(id) {
291 t.Errorf("client offered disallowed suite %#x", id)
294 for _, id := range hello.supportedCurves {
295 if !isBoringCurve(id) {
296 t.Errorf("client offered disallowed curve %d", id)
299 for _, sigHash := range hello.supportedSignatureAlgorithms {
300 if !isBoringSignatureScheme(sigHash) {
301 t.Errorf("client offered disallowed signature-and-hash %v", sigHash)
306 func TestBoringCertAlgs(t *testing.T) {
307 // NaCl, arm and wasm time out generating keys. Nothing in this test is architecture-specific, so just don't bother on those.
308 if runtime.GOOS == "nacl" || runtime.GOARCH == "arm" || runtime.GOOS == "js" {
309 t.Skipf("skipping on %s/%s because key generation takes too long", runtime.GOOS, runtime.GOARCH)
312 // Set up some roots, intermediate CAs, and leaf certs with various algorithms.
313 // X_Y is X signed by Y.
314 R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
315 R2 := boringCert(t, "R2", boringRSAKey(t, 4096), nil, boringCertCA)
317 M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
318 M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
320 I_R1 := boringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK)
321 I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK)
322 I_M1 := boringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
323 I_M2 := boringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
325 L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
326 L2_I := boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
328 // boringCert checked that isBoringCertificate matches the caller's boringCertFIPSOK bit.
329 // If not, no point in building bigger end-to-end tests.
331 t.Fatalf("isBoringCertificate failures; not continuing")
334 // client verifying server cert
335 testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
336 clientConfig := testConfig.Clone()
337 clientConfig.RootCAs = pool
338 clientConfig.InsecureSkipVerify = false
339 clientConfig.ServerName = "example.com"
341 serverConfig := testConfig.Clone()
342 serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
343 serverConfig.BuildNameToCertificate()
345 clientErr, _ := boringHandshake(t, clientConfig, serverConfig)
347 if (clientErr == nil) == ok {
349 t.Logf("%s: accept", desc)
351 t.Logf("%s: reject", desc)
355 t.Errorf("%s: BAD reject (%v)", desc, clientErr)
357 t.Errorf("%s: BAD accept", desc)
362 // server verifying client cert
363 testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
364 clientConfig := testConfig.Clone()
365 clientConfig.ServerName = "example.com"
366 clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
368 serverConfig := testConfig.Clone()
369 serverConfig.ClientCAs = pool
370 serverConfig.ClientAuth = RequireAndVerifyClientCert
372 _, serverErr := boringHandshake(t, clientConfig, serverConfig)
374 if (serverErr == nil) == ok {
376 t.Logf("%s: accept", desc)
378 t.Logf("%s: reject", desc)
382 t.Errorf("%s: BAD reject (%v)", desc, serverErr)
384 t.Errorf("%s: BAD accept", desc)
389 // Run simple basic test with known answers before proceeding to
390 // exhaustive test with computed answers.
391 r1pool := x509.NewCertPool()
392 r1pool.AddCert(R1.cert)
393 testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
394 testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
396 testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
397 testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
401 t.Fatal("basic test failed, skipping exhaustive test")
405 t.Logf("basic test passed; skipping exhaustive test in -short mode")
409 for l := 1; l <= 2; l++ {
414 for i := 0; i < 64; i++ {
415 reachable := map[string]bool{leaf.parentOrg: true}
416 reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK}
417 list := [][]byte{leaf.der}
418 listName := leaf.name
419 addList := func(cond int, c *boringCertificate) {
421 list = append(list, c.der)
422 listName += "," + c.name
423 if reachable[c.org] {
424 reachable[c.parentOrg] = true
426 if reachableFIPS[c.org] && c.fipsOK {
427 reachableFIPS[c.parentOrg] = true
438 for r := 1; r <= 3; r++ {
439 pool := x509.NewCertPool()
441 shouldVerify := false
442 shouldVerifyFIPS := false
443 addRoot := func(cond int, c *boringCertificate) {
445 rootName += "," + c.name
447 if reachable[c.org] {
450 if reachableFIPS[c.org] && c.fipsOK {
451 shouldVerifyFIPS = true
457 rootName = rootName[1:] // strip leading comma
458 testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
459 testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
461 testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
462 testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
472 boringCertFIPSOK = 0x80
475 func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey {
476 k, err := rsa.GenerateKey(rand.Reader, size)
483 func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
484 k, err := ecdsa.GenerateKey(curve, rand.Reader)
491 type boringCertificate struct {
496 cert *x509.Certificate
501 func boringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate {
504 if i := strings.Index(org, "_"); i >= 0 {
506 parentOrg = name[i+1:]
508 tmpl := &x509.Certificate{
509 SerialNumber: big.NewInt(1),
511 Organization: []string{org},
513 NotBefore: time.Unix(0, 0),
514 NotAfter: time.Unix(0, 0),
516 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
517 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
518 BasicConstraintsValid: true,
520 if mode&^boringCertFIPSOK == boringCertLeaf {
521 tmpl.DNSNames = []string{"example.com"}
524 tmpl.KeyUsage |= x509.KeyUsageCertSign
527 var pcert *x509.Certificate
539 switch k := key.(type) {
540 case *rsa.PrivateKey:
542 desc = fmt.Sprintf("RSA-%d", k.N.BitLen())
543 case *ecdsa.PrivateKey:
545 desc = "ECDSA-" + k.Curve.Params().Name
547 t.Fatalf("invalid key %T", key)
550 der, err := x509.CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
554 cert, err := x509.ParseCertificate(der)
559 // Tell isBoringCertificate to enforce FIPS restrictions for this check.
561 defer fipstls.Abandon()
563 fipsOK := mode&boringCertFIPSOK != 0
564 if isBoringCertificate(cert) != fipsOK {
565 t.Errorf("isBoringCertificate(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
567 return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK}
570 // A self-signed test certificate with an RSA key of size 2048, for testing
571 // RSA-PSS with SHA512. SAN of example.golang.
573 testRSA2048Certificate []byte
574 testRSA2048PrivateKey *rsa.PrivateKey
578 block, _ := pem.Decode([]byte(`
579 -----BEGIN CERTIFICATE-----
580 MIIC/zCCAeegAwIBAgIRALHHX/kh4+4zMU9DarzBEcQwDQYJKoZIhvcNAQELBQAw
581 EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xMTAxMDExNTA0MDVaFw0yMDEyMjkxNTA0
582 MDVaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
583 ggEKAoIBAQCf8fk0N6ieCBX4IOVIfKitt4kGcOQLeimCfsjqqHcysMIVGEtFSM6E
584 4Ay141f/7IqdW0UtIqNb4PXhROID7yDxR284xL6XbCuv/t5hP3UcehYc3hmLiyVd
585 MkZQiZWtfUUJf/1qOtM+ohNg59LRWp4d+6iX0la1JL3EwCIckkNjJ9hQbF7Pb2CS
586 +ES9Yo55KAap8KOblpcR8MBSN38bqnwjfQdCXvOEOjam2HUxKzEFX5MA+fA0me4C
587 ioCcCRLWKl+GoN9F8fABfoZ+T+2eal4DLuO95rXR8SrOIVBh3XFOr/RVhjtXcNVF
588 ZKcvDt6d68V6jAKAYKm5nlj9GPpd4v+rAgMBAAGjUDBOMA4GA1UdDwEB/wQEAwIF
589 oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCC
590 DmV4YW1wbGUuZ29sYW5nMA0GCSqGSIb3DQEBCwUAA4IBAQCOoYsVcFCBhboqe3WH
591 dC6V7XXXECmnjh01r8h80yv0NR379nSD3cw2M+HKvaXysWqrl5hjGVKw0vtwD81r
592 V4JzDu7IfIog5m8+QNC+7LqDZsz88vDKOrsoySVOmUCgmCKFXew+LA+eO/iQEJTr
593 7ensddOeXJEp27Ed5vW+kmWW3Qmglc2Gwy8wFrMDIqnrnOzBA4oCnDEgtXJt0zog
594 nRwbfEMAWi1aQRy5dT9KA3SP9mo5SeTFSzGGHiE4s4gHUe7jvsAFF2qgtD6+wH6s
595 z9b6shxnC7g5IlBKhI7SVB/Uqt2ydJ+kH1YbjMcIq6NAM5eNMKgZuJr3+zwsSgwh
597 -----END CERTIFICATE-----`))
598 testRSA2048Certificate = block.Bytes
600 block, _ = pem.Decode([]byte(`
601 -----BEGIN RSA PRIVATE KEY-----
602 MIIEpAIBAAKCAQEAn/H5NDeonggV+CDlSHyorbeJBnDkC3opgn7I6qh3MrDCFRhL
603 RUjOhOAMteNX/+yKnVtFLSKjW+D14UTiA+8g8UdvOMS+l2wrr/7eYT91HHoWHN4Z
604 i4slXTJGUImVrX1FCX/9ajrTPqITYOfS0VqeHfuol9JWtSS9xMAiHJJDYyfYUGxe
605 z29gkvhEvWKOeSgGqfCjm5aXEfDAUjd/G6p8I30HQl7zhDo2pth1MSsxBV+TAPnw
606 NJnuAoqAnAkS1ipfhqDfRfHwAX6Gfk/tnmpeAy7jvea10fEqziFQYd1xTq/0VYY7
607 V3DVRWSnLw7enevFeowCgGCpuZ5Y/Rj6XeL/qwIDAQABAoIBAQCNpMZifd/vg42h
608 HdCvLuZaYS0R7SunFlpoXEsltGdLFsnp0IfoJZ/ugFQBSAIIfLwMumU6oXA1z7Uv
609 98aIYV61DePrTCDVDFBsHbNmP8JAo8WtbusEbwd5zyoB7LYG2+clkJklWE73KqUq
610 rmI+UJeyScl2Gin7ZTxBXz1WPBk9VwcnwkeaXpgASIBW23fhECM9gnYEEwaBez5T
611 6Me8d1tHtYQv7vsKe7ro9w9/HKrRXejqYKK1LxkhfFriyV+m8LZJZn2nXOa6G3gF
612 Nb8Qk1Uk5PUBENBmyMFJhT4M/uuSq4YtMrrO2gi8Q+fPhuGzc5SshYKRBp0W4P5r
613 mtVCtEFRAoGBAMENBIFLrV2+HsGj0xYFasKov/QPe6HSTR1Hh2IZONp+oK4oszWE
614 jBT4VcnITmpl6tC1Wy4GcrxjNgKIFZAj+1x1LUULdorXkuG8yr0tAhG9zNyfWsSy
615 PrSovC0UVbzr8Jxxla+kQVxEQQqWQxPlEVuL8kXaIDA6Lyt1Hpua2LvPAoGBANQZ
616 c6Lq2T7+BxLxNdi2m8kZzej5kgzBp/XdVsbFWRlebIX2KrFHsrHzT9PUk3DE1vZK
617 M6pzTt94nQhWSkDgCaw1SohElJ3HFIFwcusF1SJAc3pQepd8ug6IYdlpDMLtBj/P
618 /5P6BVUtgo05E4+I/T3iYatmglQxTtlZ0RkSV2llAoGBALOXkKFX7ahPvf0WksDh
619 uTfuFOTPoowgQG0EpgW0wRdCxeg/JLic3lSD0gsttQV2WsRecryWcxaelRg10RmO
620 38BbogmhaF4xvgsSvujOfiZTE8oK1T43M+6NKsIlML3YILbpU/9aJxPWy0s2DqDr
621 cQJhZrlk+pzjBA7Bnf/URdwxAoGAKR/CNw14D+mrL3YLbbiCXiydqxVwxv5pdZdz
622 8thi3TNcsWC4iGURdcVqbfUinVPdJiXe/Kac3WGCeRJaFVgbKAOxLti1RB5MkIhg
623 D8eyupBqk4W1L1gkrxqsdj4TFlxkwMywjl2E2S4YyQ8PBt6V04DoVRZsIKzqz+PF
624 UionPq0CgYBCYXvqioJhPewkOq/Y5wrDBeZW1FQK5QD9W5M8/5zxd4rdvJtjhbJp
625 oOrtvMdrl6upy9Hz4BJD3FXwVFiPFE7jqeNqi0F21viLxBPMMD3UODF6LL5EyLiR
626 9V4xVMS8KXxvg7rxsuqzMPscViaWUL6WNVBhsD2+92dHxSXzz5EJKQ==
627 -----END RSA PRIVATE KEY-----`))
629 testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)