-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
x509_test.go
534 lines (501 loc) · 19.6 KB
/
x509_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
package jwkset
import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"encoding/pem"
"errors"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"
)
func TestNewJWKFromX5C(t *testing.T) {
testCases := []struct {
name string
raw []byte
keyType any
}{
{
name: "EC",
raw: []byte(ec521Cert),
keyType: &ecdsa.PublicKey{},
},
{
name: "EdDSA",
raw: []byte(ed25519Cert),
keyType: ed25519.PublicKey{},
},
{
name: "RSA",
raw: []byte(rsa4096Cert),
keyType: &rsa.PublicKey{},
},
{
name: "Chain",
raw: []byte(ec521Cert + ed25519Cert + rsa4096Cert),
keyType: &ecdsa.PublicKey{},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
certs, err := LoadCertificates(testCase.raw)
if err != nil {
t.Fatal("Failed to load certificates:", err)
}
x509Options := JWKX509Options{
X5C: certs,
}
options := JWKOptions{
X509: x509Options,
}
jwk, err := NewJWKFromX5C(options)
if err != nil {
t.Fatal("Failed to create JWK from X5C:", err)
}
if reflect.TypeOf(jwk.Key()) != reflect.TypeOf(testCase.keyType) {
t.Fatal("Wrong key type:", reflect.TypeOf(jwk.Key()))
}
})
}
}
func TestDefaultGetX5U(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte(ec521Cert))
if err != nil {
t.Fatal("Failed to write certificate:", err)
}
}))
defer server.Close()
validateOptions := JWKValidateOptions{
GetX5U: DefaultGetX5U,
SkipX5UScheme: true,
}
x509 := JWKX509Options{
X5U: server.URL,
}
options := JWKOptions{
Validate: validateOptions,
X509: x509,
}
jwk, err := NewJWKFromX5U(options)
if err != nil {
t.Fatal("Failed to create JWK from X5U:", err)
}
_ = jwk.Key().(*ecdsa.PublicKey)
}
func TestLoadCertificate(t *testing.T) {
b := loadPEM(t, ec521Cert)
cert, err := LoadCertificate(b.Bytes)
if err != nil {
t.Fatal("Failed to load certificate:", err)
}
_ = cert.PublicKey.(*ecdsa.PublicKey)
b = loadPEM(t, ed25519Cert)
cert, err = LoadCertificate(b.Bytes)
if err != nil {
t.Fatal("Failed to load certificate:", err)
}
_ = cert.PublicKey.(ed25519.PublicKey)
b = loadPEM(t, rsa4096Cert)
cert, err = LoadCertificate(b.Bytes)
if err != nil {
t.Fatal("Failed to load certificate:", err)
}
_ = cert.PublicKey.(*rsa.PublicKey)
}
func TestLoadCertificates(t *testing.T) {
b := append(append([]byte(ec521Cert), []byte(ed25519Cert)...), []byte(rsa4096Cert)...)
certs, err := LoadCertificates(b)
if err != nil {
t.Fatal("Failed to load certificates:", err)
}
if len(certs) != 3 {
t.Fatal("Wrong number of certificates loaded:", len(certs))
}
_ = certs[0].PublicKey.(*ecdsa.PublicKey)
_ = certs[1].PublicKey.(ed25519.PublicKey)
_ = certs[2].PublicKey.(*rsa.PublicKey)
}
func TestLoadX509KeyInfer(t *testing.T) {
b := loadPEM(t, ec521Pub)
key, err := LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load public EC 521 X509 key:", err)
}
_ = key.(*ecdsa.PublicKey)
b = loadPEM(t, ed25519Pub)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load public EdDSA X509 key:", err)
}
_ = key.(ed25519.PublicKey)
b = loadPEM(t, rsa4096Pub)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load public RSA 4096 X509 key:", err)
}
_ = key.(*rsa.PublicKey)
b = loadPEM(t, ec521Priv)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load private EC 521 X509 key:", err)
}
_ = key.(*ecdsa.PrivateKey)
b = loadPEM(t, ed25519Priv)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load private EdDSA X509 key:", err)
}
_ = key.(ed25519.PrivateKey)
b = loadPEM(t, rsa4096Priv)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load private RSA 4096 X509 key:", err)
}
_ = key.(*rsa.PrivateKey)
b = loadPEM(t, rsa2048PKCS1Priv)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load private RSA 2048 PKCS1 X509 key:", err)
}
_ = key.(*rsa.PrivateKey)
b = loadPEM(t, rsa2048PKCS1Pub)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load public RSA 2048 PKCS1 X509 key:", err)
}
_ = key.(*rsa.PublicKey)
b = loadPEM(t, ec256SEC1Priv)
key, err = LoadX509KeyInfer(b)
if err != nil {
t.Fatal("Failed to load private EC P256 X509 key:", err)
}
_ = key.(*ecdsa.PrivateKey)
b = &pem.Block{}
_, err = LoadX509KeyInfer(b)
if !errors.Is(err, ErrX509Infer) {
t.Fatal("Should have failed to infer X509 key type:", err)
}
replaced := strings.ReplaceAll(rsa2048PKCS1Priv, "RSA PRIVATE KEY", "PRIVATE KEY")
b = loadPEM(t, replaced)
_, err = LoadX509KeyInfer(b)
if err == nil {
t.Fatal("Should have failed to infer X509 key type.")
}
}
func TestLoadPKCS1Private(t *testing.T) {
b := loadPEM(t, rsa2048PKCS1Priv)
_, err := loadPKCS1Private(b)
if err != nil {
t.Fatal("Failed to load private PKCS1 key:", err)
}
b = &pem.Block{}
_, err = loadPKCS1Private(b)
if err == nil {
t.Fatal("Should have failed to load private PKCS1 key.")
}
}
func TestLoadPKCS1Public(t *testing.T) {
b := loadPEM(t, rsa2048PKCS1Pub)
_, err := loadPKCS1Public(b)
if err != nil {
t.Fatal("Failed to load public PKCS1 key:", err)
}
b = &pem.Block{}
_, err = loadPKCS1Public(b)
if err == nil {
t.Fatal("Should have failed to load public PKCS1 key.")
}
}
func TestLoadECPrivate(t *testing.T) {
b := loadPEM(t, ec256SEC1Priv)
_, err := loadECPrivate(b)
if err != nil {
t.Fatal("Failed to load private EC key:", err)
}
b = &pem.Block{}
_, err = loadECPrivate(b)
if err == nil {
t.Fatal("Should have failed to load private EC key.")
}
}
func TestLoadPKCS8PrivateUnsupportedKey(t *testing.T) {
b := &pem.Block{}
_, err := loadPKCS8Private(b)
if err == nil {
t.Fatal("Should have failed to load empty PEM block.")
}
// The x509.ParsePKCS8PrivateKey function does not support loading private DSA keys.
}
func TestLoadPKIXPublicUnsupportedKey(t *testing.T) {
b := &pem.Block{}
_, err := loadPKIXPublic(b)
if err == nil {
t.Fatal("Should have failed to load empty PEM block.")
}
b = loadPEM(t, dsa2048Pub)
_, err = loadPKIXPublic(b)
if !errors.Is(err, ErrUnsupportedKey) {
t.Fatal("Should have failed to load unsupported DSA public key.")
}
}
func loadPEM(t *testing.T, rawPem string) *pem.Block {
rawPem = strings.TrimSpace(rawPem)
b, _ := pem.Decode([]byte(rawPem))
if b == nil {
t.Fatal("Failed to decode PEM.")
}
return b
}
// Certificates.
const (
ec521Cert = `
-----BEGIN CERTIFICATE-----
MIICuTCCAhqgAwIBAgIURHp0UtKTyrMNVuzjFxOPj09/fO8wCgYIKoZIzj0EAwIw
bjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCFZpcmdpbmlhMREwDwYDVQQHDAhSaWNo
bW9uZDEUMBIGA1UECgwLTWljYWggUGFya3MxDTALBgNVBAsMBFNlbGYxFDASBgNV
BAMMC2V4YW1wbGUuY29tMB4XDTIzMTExMjE3NTgxM1oXDTIzMTIxMjE3NTgxM1ow
bjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCFZpcmdpbmlhMREwDwYDVQQHDAhSaWNo
bW9uZDEUMBIGA1UECgwLTWljYWggUGFya3MxDTALBgNVBAsMBFNlbGYxFDASBgNV
BAMMC2V4YW1wbGUuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBtW2F+MPt
PcN+t5YtYcq8dluVBimcJ3cwTT/Hqrls0iHzpPVANAFRGqhvZnOb4rz7bh3bRqSm
zRNXT9lRJhg07gIA8n2j87Vg5r2FNwlRfD5eMNN3g+o62HUsB9sBfpMiGvLphgvy
g7Mtub7of4eBNphHTBvh3GU+S9TEHvTNP3Ja0aWjUzBRMB0GA1UdDgQWBBSRmKro
6jYkFz0suXUdjCeONWSZSDAfBgNVHSMEGDAWgBSRmKro6jYkFz0suXUdjCeONWSZ
SDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA4GMADCBiAJCARNYjIrrRbub
jF2D/I0Auw7sFQMvV3ImKp+L42kYpoFMXvnmKcuDt6n/OZCDAWpky/Uj/gLbvR2M
fsCNJ+9mbi+4AkIBB0L6Ue7Mxl5cNGprGKSy5c0mlXWezB3GhUKxNrOMUo3+Lt3G
slfqg3TSRlKC1YH863YkRGsE0XWwt9Myj2N6cVI=
-----END CERTIFICATE-----`
ed25519Cert = `
-----BEGIN CERTIFICATE-----
MIIB8TCCAaOgAwIBAgIUV1qgafWZ5a/PVYZiwTZIyCfiF6gwBQYDK2VwMG4xCzAJ
BgNVBAYTAlVTMREwDwYDVQQIDAhWaXJnaW5pYTERMA8GA1UEBwwIUmljaG1vbmQx
FDASBgNVBAoMC01pY2FoIFBhcmtzMQ0wCwYDVQQLDARTZWxmMRQwEgYDVQQDDAtl
eGFtcGxlLmNvbTAeFw0yMzExMTIxNzU4MTNaFw0yMzEyMTIxNzU4MTNaMG4xCzAJ
BgNVBAYTAlVTMREwDwYDVQQIDAhWaXJnaW5pYTERMA8GA1UEBwwIUmljaG1vbmQx
FDASBgNVBAoMC01pY2FoIFBhcmtzMQ0wCwYDVQQLDARTZWxmMRQwEgYDVQQDDAtl
eGFtcGxlLmNvbTAqMAUGAytlcAMhAFddnU/P7hWUHzdljcXTsfKN5QffdYSikqUo
dt4PAu7oo1MwUTAdBgNVHQ4EFgQUoblrsByGUQ2+Ttthwnm/Vwe+yB8wHwYDVR0j
BBgwFoAUoblrsByGUQ2+Ttthwnm/Vwe+yB8wDwYDVR0TAQH/BAUwAwEB/zAFBgMr
ZXADQQB89PtKOOmgALNTe14oSxMEeFXxGgns7ZiTsuQ+nRtlvkkCJVJKDEJxBXnZ
RqPHwMhPvj2Jw4lYx85CSr47R7cM
-----END CERTIFICATE-----`
rsa4096Cert = `
-----BEGIN CERTIFICATE-----
MIIFvTCCA6WgAwIBAgIUZNBtI415mo2zhbfEo3i9YeSocy8wDQYJKoZIhvcNAQEL
BQAwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCFZpcmdpbmlhMREwDwYDVQQHDAhS
aWNobW9uZDEUMBIGA1UECgwLTWljYWggUGFya3MxDTALBgNVBAsMBFNlbGYxFDAS
BgNVBAMMC2V4YW1wbGUuY29tMB4XDTIzMTExMjE3NTgxNFoXDTIzMTIxMjE3NTgx
NFowbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCFZpcmdpbmlhMREwDwYDVQQHDAhS
aWNobW9uZDEUMBIGA1UECgwLTWljYWggUGFya3MxDTALBgNVBAsMBFNlbGYxFDAS
BgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEA29D7ytMzYhjhw8eweNA73Xid4qpb2uspSmleN5BjWvFeM+tk9RCdc7UQDhrQ
Sv1nrH5sc7NcK2gznmETm+cgaXQeAxacXiC7pXCcSLGhp3BJtBFmOpINyUxPjQrt
WzTUP2AC85DoxQVdM9/cRY7AMLF20YhsgG3B+VxvihbiMSVYwonqB31n2aZgKina
R65JSJQf4SjTgYCtXe128Ch5tsRMMSUTqKzl63w+85VHLoQ+vZBnx6Ht7pBm3tGs
ZFeeaTmZAF+0A9PMkDaFBw6mRyPqus87jjcWv6/VkcVDiZnNw6gEQfltDXFsk03B
Fvs9KU4rfjHA3GuDfpu4OZRkziO9aRvdk1xofTqQSrd6rTTFydzOhmvp5A0mt1Ap
KQQn1f+zTh9ybTxDtJroRCKP+gJYq+kGbMDlpCZXyHv6D68pL04LVctga+5CkZ09
TzVijb85+LCUk5LNvFoh6NcFpz7z5Ru0EyMLDTazOvzQ/aNGl0IYMxs5Ske+cpiJ
XG0+dVe441TlRgwOeUKBg09vrWZoIaD8s7KiziRlrxfHSxJCgPMKCm0lMYQpaXAI
bDMVWr4a1O+WZy0z7R7e9QiFvSoy1ocL9m+5UwiOmS2Z/Oj9HZP+ZT+A/H0Z/hQw
nN7zpbsNms4LGgrneCOc7VaKYq+jeWIsoQ8Bq9aZwsTnH58CAwEAAaNTMFEwHQYD
VR0OBBYEFCXfwSpbQUoatjcGGpxcA0y63ZysMB8GA1UdIwQYMBaAFCXfwSpbQUoa
tjcGGpxcA0y63ZysMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
AGGGHDzxe+vSop9RUm5J1I8zmeVjxIC6FxEUSzXst+9DggjXRqaof4EhWKtW+Sdf
DgPGTvDZagDX1VKxuzolmMUgBRT9MrXrnNj3IOUkxptU1t1itIWNSOv0EuNfdMFo
kyDByLNXt8n3zewKZ0KEQkOHnl7sQSfnKxA4AuIaYUFOXAzn8LuL5ZCO3kl60Hla
M0DcRUaKJeJHFjxTXgBQr9M3dr55eQGw/jSWBk5jsfEQgKndQY27I43kMhFOmL5r
ldBB0LrTzuBToFG79oQpzvUkNQkbFevDE15RgtBV5xQTTYjxi3MBcFlL98Vtfj85
SjICsN0KNjolABtryrlQ32PwPp5dIelaILzuvvLsQNFt62RtcntfniScdZ5PZIae
bx0IJyhvy2ylhmYVwfJwUKqIMqnbhYJinvZ/NYjD7tQmnUq2AzopB6YHXDs/CrfU
YckvHj/LGWRyTzb00CWQMvmRZmUsVEThSThY+aTlcRiXu6OATMYii/w/hv+7sVwr
NcMXVckh2/bpHjlZM03LJoabhDp+6c16U+NvOxoVsaPT7y4avoGZZ/IU30i3QpDf
qx5NKPcC4HDK28Daw6zBdO+fkodKFcgsL4jUqP+Q6QCWBH88PlmlXx80XoPQu++W
VhA/xoU82uODjoUbY6FzMW49ESHddZfuFg9fXHm1z31q
-----END CERTIFICATE-----`
)
// PKCS#8 and PKIX formats.
const (
ec521Priv = `
-----BEGIN PRIVATE KEY-----
MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBK1phZlyXggGSevAh
qqdocYbUK0AQBeD52ZB14sXshymnv/VkMop9UkZRIv11GrIDInxdfRBTXHS4lS18
DvW6mOehgYkDgYYABAG1bYX4w+09w363li1hyrx2W5UGKZwndzBNP8equWzSIfOk
9UA0AVEaqG9mc5vivPtuHdtGpKbNE1dP2VEmGDTuAgDyfaPztWDmvYU3CVF8Pl4w
03eD6jrYdSwH2wF+kyIa8umGC/KDsy25vuh/h4E2mEdMG+HcZT5L1MQe9M0/clrR
pQ==
-----END PRIVATE KEY-----`
ec521Pub = `
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBtW2F+MPtPcN+t5YtYcq8dluVBimc
J3cwTT/Hqrls0iHzpPVANAFRGqhvZnOb4rz7bh3bRqSmzRNXT9lRJhg07gIA8n2j
87Vg5r2FNwlRfD5eMNN3g+o62HUsB9sBfpMiGvLphgvyg7Mtub7of4eBNphHTBvh
3GU+S9TEHvTNP3Ja0aU=
-----END PUBLIC KEY-----`
ed25519Priv = `
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIOC6YxHKyd+kPJo6N0lpdiGQLrre5P5W1GKDPwMN0Hxj
-----END PRIVATE KEY-----`
ed25519Pub = `
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAV12dT8/uFZQfN2WNxdOx8o3lB991hKKSpSh23g8C7ug=
-----END PUBLIC KEY-----`
rsa4096Priv = `
-----BEGIN PRIVATE KEY-----
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
NlwPSUy/6PKkQnZiQ0mW4LZqG/maLg==
-----END PRIVATE KEY-----`
rsa4096Pub = `
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA29D7ytMzYhjhw8eweNA7
3Xid4qpb2uspSmleN5BjWvFeM+tk9RCdc7UQDhrQSv1nrH5sc7NcK2gznmETm+cg
aXQeAxacXiC7pXCcSLGhp3BJtBFmOpINyUxPjQrtWzTUP2AC85DoxQVdM9/cRY7A
MLF20YhsgG3B+VxvihbiMSVYwonqB31n2aZgKinaR65JSJQf4SjTgYCtXe128Ch5
tsRMMSUTqKzl63w+85VHLoQ+vZBnx6Ht7pBm3tGsZFeeaTmZAF+0A9PMkDaFBw6m
RyPqus87jjcWv6/VkcVDiZnNw6gEQfltDXFsk03BFvs9KU4rfjHA3GuDfpu4OZRk
ziO9aRvdk1xofTqQSrd6rTTFydzOhmvp5A0mt1ApKQQn1f+zTh9ybTxDtJroRCKP
+gJYq+kGbMDlpCZXyHv6D68pL04LVctga+5CkZ09TzVijb85+LCUk5LNvFoh6NcF
pz7z5Ru0EyMLDTazOvzQ/aNGl0IYMxs5Ske+cpiJXG0+dVe441TlRgwOeUKBg09v
rWZoIaD8s7KiziRlrxfHSxJCgPMKCm0lMYQpaXAIbDMVWr4a1O+WZy0z7R7e9QiF
vSoy1ocL9m+5UwiOmS2Z/Oj9HZP+ZT+A/H0Z/hQwnN7zpbsNms4LGgrneCOc7VaK
Yq+jeWIsoQ8Bq9aZwsTnH58CAwEAAQ==
-----END PUBLIC KEY-----`
)
// Other formats.
const (
rsa2048PKCS1Priv = `
-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEA4v/3tBv7bKZgVyC8+Kjb82edPJmiEO2nJmTi/pAGK6bWEqOk
nsl9Qx5Ih1Z374mnIPWpeM/D4g/CC8E4NWWy6htGzZx8b5tcO08XJ7uGEWfG1Nyq
ACsQ18V6dPk3Wz8SvgqCxeZ5e+/wxHmPrhTRi1yKQBRfm/RqpaHgfFjM7ZTXG6MH
BUWUQD6I00o1hirs0oCka/Rlfy/OhikzvkiGDcS6VC+KFwP6wXx91TIwMLy+ncJ6
hZJHHXbQN5oVkga1ZAtid4xeYvC9Ma5ytIfeRG61cUetc173vdxBtcHPXfrSDvjC
G8vFTrtIkY4rE6zx9qrTXrYniSgrBKsn+HoWcQIDAQABAoIBAQCJXdKc6I4GmswU
DZitdSndKueI44OicN5Eqqp+19MUGVrUXrjg6hdmRW4okBf2GbvMgzzyAfCM3XJU
wLFuBsP1TVpUVI0s0LxIm7zsa1tfLwiwiXRKs8T2fedz39gy3IFQBXZLogQEDxgJ
HXLoKmr/xZlX27xb2NWss7/wH6CrZ9GD0YShN6Xo4G1qZsDSf8MrJ6dKNYm4Fej8
5ZsxtVvPi18lY6VO4bjJBq6VoPyJQYAacundyQ9Hifgg743+PTGBdcKP8SPb8X0u
yZEypAIVw3BXVJ3Shh8NN5iRfLaEvqMNhIzKiJxma7+J303icQJEurduSOM+to/7
5u9kUTvRAoGBAP0yyDd4RT2jBHnOxKabOFBygtWJBvbHRSXt9s9P6fNxoWquKhxt
b1oesKAljffRsbrJeI8G3vzElofMmcKsohDwv83Qc7J1Ph7S+hr4COnt3gVlsxaH
CDL/VaPESXTYXF8N/U6Ewz1FsYVxzs20MMFcoro9D2FJVLz1SKOZH6eNAoGBAOWC
+Yv0lv92IGKXj0p/0PaBz3vmxpl49o+o9OukgRJMJwmlMJn/pTF4Eu6QYe60dKsm
f/jnahBsHe/f/OCV1W0iDO85o+8Fg7jXGUyqIvCVMehmLVItHZLBGoqzRIUJzC2P
RDyHLVuV9PiHZ0SgRLroqRKZVQSe0cDp8jk3Bk91AoGBAM1AyGunFMJFj1BLHMFO
nRUh7wu5XCrbGSQJRwWB685MdCTt8PdAg38T1+zK5M5bb+9SeWfAky1nE/wcER1u
IqcG8wWeENw/DM+iCduo7FjuWggYDFibuDrXIA51BXMyHZd02L45A6h9Ac6ClrnM
c6WcOdItw3UDJC1Vzb/JVo7VAoGBAM5Gly6YmBXl/1ldSmX01sSXCvobAifxtfiM
LASWB4OAeh2LIFFomPoLJ0jO75XxDmK86Yu1wXgdFBMBx2+6euXpEqL3tUUgObEp
cg2bZGfCT+bF3rna3peFgutiD5Vapu3Ts8qK29NSxaeRWtktCljKvxp+QRE0BOVT
3mZZ9Av5AoGBAIqukzaeOWXsnpJI1E4MpaRiAkFsHtzPwxMZJURRYyg3C0ZFiqkF
txxRdz/fj2HNEkEconBHVRwyr/f7vy2qmmo9Xd1fnvvSjOcuuZLL4WxXrhSYvK9e
cbf0IYk6FVqTwLdW1PFAR9PsMPnb9OKQ2MBKZIuamw5GEhL0KoNjVsUc
-----END RSA PRIVATE KEY-----`
rsa2048PKCS1Pub = `
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA4v/3tBv7bKZgVyC8+Kjb82edPJmiEO2nJmTi/pAGK6bWEqOknsl9
Qx5Ih1Z374mnIPWpeM/D4g/CC8E4NWWy6htGzZx8b5tcO08XJ7uGEWfG1NyqACsQ
18V6dPk3Wz8SvgqCxeZ5e+/wxHmPrhTRi1yKQBRfm/RqpaHgfFjM7ZTXG6MHBUWU
QD6I00o1hirs0oCka/Rlfy/OhikzvkiGDcS6VC+KFwP6wXx91TIwMLy+ncJ6hZJH
HXbQN5oVkga1ZAtid4xeYvC9Ma5ytIfeRG61cUetc173vdxBtcHPXfrSDvjCG8vF
TrtIkY4rE6zx9qrTXrYniSgrBKsn+HoWcQIDAQAB
-----END RSA PUBLIC KEY-----`
ec256SEC1Priv = `
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPEHBaM5VfAK2Gss3HQcXg89UH/5+APhT+LeXv9QXJ5toAoGCCqGSM49
AwEHoUQDQgAEpKijCjLFUcDsIjNAXkzQsk1/YnObl5dx1KR/CfDzKklOIDiCaU4H
O6SocyslNS/EH5UqyZgShM3WhoHcdvdBSg==
-----END EC PRIVATE KEY-----`
)
// DSA keys (unsupported by any JWK RFC I know of).
const (
dsa2048Priv = `
-----BEGIN PRIVATE KEY-----
MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQCJi6h3cmIxHTrzsA3vrBM//AKv
/bM1K9FTJb/h+GTJpJ1Ccp4yURmxdS44/P1nhJBu0EcUCaP8UzBM9DLUtIVqO5Ag
KkxdgLsTspunGLykEkMcAN4Ij6ggcoSQ56SftQYZ1kgxJQPDT/KZk217Wwg1lLyJ
HobH6++HKfDB5z5NdCA3jau3ANNH9kptNGpnyai1FLJHBSHa8605fvRCvEtgL4jm
/7ZgIR8Xvm9D4CnIhtlYkWjy6dAykyjnh+AovJrEuB6DBEW5YU8PhEj2cYW7+GvV
KXFFsN90bocqf/6++dToB/bqUNW1j3Pg6+gDdqCkMD/k/4itZ5ObOBvw9yL3Ah0A
qtTg2DsMkJFSs3S9Q10LKJI561L9tj0mf7LinQKCAQA9BLRa4B1ozotJbiUNGRt9
H0Ebvnh3IlL3F4JjNQUqChUvsOTHvRG/Ogck1k1fTTBGugg+oZiHG4CAFtNvz4LZ
DehPy4A8BW+nQEXoUxmlJTBjgc5J5lYBIgRQLv8FGCxdd3zo/4cgXjpchosk4N/J
rz33BvpovUoQE8t1ks3bddRD7MsN6muCvyJYED69rnCn79OEOjOKhmOQb3G/rTH8
eO1acRjcTu1uMie/vHtltvd2TxGTNqzVBRvLIDWYD0UK/LFwig1TwWfZF3QLZ1HS
40//npFAd3C5Opf/ZPYOFlT3a/8GaZSSGzkugwLmSeCrI6DPQ6Z3r1sDkSY6ixXf
BB4CHAW4zQgr2nCGhaJmYvlaLmPfzpeN1LOOX0QCmy0=
-----END PRIVATE KEY-----`
dsa2048Pub = `
-----BEGIN PUBLIC KEY-----
MIIDQjCCAjUGByqGSM44BAEwggIoAoIBAQCJi6h3cmIxHTrzsA3vrBM//AKv/bM1
K9FTJb/h+GTJpJ1Ccp4yURmxdS44/P1nhJBu0EcUCaP8UzBM9DLUtIVqO5AgKkxd
gLsTspunGLykEkMcAN4Ij6ggcoSQ56SftQYZ1kgxJQPDT/KZk217Wwg1lLyJHobH
6++HKfDB5z5NdCA3jau3ANNH9kptNGpnyai1FLJHBSHa8605fvRCvEtgL4jm/7Zg
IR8Xvm9D4CnIhtlYkWjy6dAykyjnh+AovJrEuB6DBEW5YU8PhEj2cYW7+GvVKXFF
sN90bocqf/6++dToB/bqUNW1j3Pg6+gDdqCkMD/k/4itZ5ObOBvw9yL3Ah0AqtTg
2DsMkJFSs3S9Q10LKJI561L9tj0mf7LinQKCAQA9BLRa4B1ozotJbiUNGRt9H0Eb
vnh3IlL3F4JjNQUqChUvsOTHvRG/Ogck1k1fTTBGugg+oZiHG4CAFtNvz4LZDehP
y4A8BW+nQEXoUxmlJTBjgc5J5lYBIgRQLv8FGCxdd3zo/4cgXjpchosk4N/Jrz33
BvpovUoQE8t1ks3bddRD7MsN6muCvyJYED69rnCn79OEOjOKhmOQb3G/rTH8eO1a
cRjcTu1uMie/vHtltvd2TxGTNqzVBRvLIDWYD0UK/LFwig1TwWfZF3QLZ1HS40//
npFAd3C5Opf/ZPYOFlT3a/8GaZSSGzkugwLmSeCrI6DPQ6Z3r1sDkSY6ixXfA4IB
BQACggEAMEBw8GdcPUuYJExRfYQLKNih789so8favDqcRI+ilfrRJz+hF4ZIKnTH
I7jPB5Lj20inAazVLl4omNxBdFzfKuzAdrYEGBHL5rjGNafo6VrLiU1y5zWFjJq7
UAGZB1HbhnUXOaNlfVoSMMK+ErcazwUjPrzso/f9j5bmvkmT9vmuMieLEVaQ6dOJ
dScNUoz3aCEmxpOgPWFEYPtdN7QVg75CQ68PYjueNyyJR4nfovuIcGOmENV+FuDz
7GV23I8WCj1OBqERHrbXCYryMS7GOSKQiISOVKdi1kqyV2rBeFL9IWW1oUPyKC1P
8OvJojkV57e01tT6HN44BhWwhWRplg==
-----END PUBLIC KEY-----`
)