File: NIOSSLTestHelpers.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (654 lines) | stat: -rw-r--r-- 34,346 bytes parent folder | download
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
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import Foundation
#if compiler(>=5.1)
@_implementationOnly import CNIOBoringSSL
#else
import CNIOBoringSSL
#endif
@testable import NIOSSL

let samplePemCert = """
-----BEGIN CERTIFICATE-----
MIIGGzCCBAOgAwIBAgIJAJ/X0Fo0ynmEMA0GCSqGSIb3DQEBCwUAMIGjMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5z
b2t5bzEuMCwGA1UECgwlU2FuIEZyYW5zb2t5byBJbnN0aXR1dGUgb2YgVGVjaG5v
bG9neTEVMBMGA1UECwwMUm9ib3RpY3MgTGFiMSAwHgYDVQQDDBdyb2JvdHMuc2Fu
ZnJhbnNva3lvLmVkdTAeFw0xNzEwMTYyMTAxMDJaFw00NzEwMDkyMTAxMDJaMIGj
MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu
IEZyYW5zb2t5bzEuMCwGA1UECgwlU2FuIEZyYW5zb2t5byBJbnN0aXR1dGUgb2Yg
VGVjaG5vbG9neTEVMBMGA1UECwwMUm9ib3RpY3MgTGFiMSAwHgYDVQQDDBdyb2Jv
dHMuc2FuZnJhbnNva3lvLmVkdTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
ggIBAO9rzJOOE8cmsIqAJMCrHDxkBAMgZhMsJ863MnWtVz5JIJK6CKI/Nu26tEzo
kHy3EI9565RwikvauheMsWaTFA4PD/P+s1DtxRCGIcK5x+SoTN7Drn5ZueoJNZRf
TYuN+gwyhprzrZrYjXpvEVPYuSIeUqK5XGrTyFA2uGj9wY3f9IF4rd7JT0ewRb1U
8OcR7xQbXKGjkY4iJE1TyfmIsBZboKaG/aYa9KbnWyTkDssaELWUIKrjwwuPgVgS
vlAYmo12MlsGEzkO9z78jvFmhUOsaEldM8Ua2AhOKW0oSYgauVuro/Ap/o5zn8PD
IDapl9g+5vjN2LucqX2a9utoFvxSKXT4NvfpL9fJvzdBNMM4xpqtHIkV0fkiMbWk
EW2FFlOXKnIJV8wT4a9iduuIDMg8O7oc+gt9pG9MHTWthXm4S29DARTqfZ48bW77
z8RrEURV03o05b/twuAJSRyyOCUi61yMo3YNytebjY2W3Pxqpq+YmT5qhqBZDLlT
LMptuFdISv6SQgg7JoFHGMWRXUavMj/sn5qZD4pQyZToHJ2Vtg5W/MI1pKwc3oKD
6M3/7Gf35r92V/ox6XT7+fnEsAH8AtQiZJkEbvzJ5lpUihSIaV3a/S+jnk7Lw8Tp
vjtpfjOg+wBblc38Oa9tk2WdXwYDbnvbeL26WmyHwQTUBi1jAgMBAAGjUDBOMB0G
A1UdDgQWBBToPRmTBQEF5F5LcPiUI5qBNPBU+DAfBgNVHSMEGDAWgBToPRmTBQEF
5F5LcPiUI5qBNPBU+DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCY
gxM5lufF2lTB9sH0s1E1VTERv37qoapNP+aw06oZkAD67QOTXFzbsM3JU1diY6rV
Y0g9CLzRO7gZY+kmi1WWnsYiMMSIGjIfsB8S+ot43LME+AJXPVeDZQnoZ6KQ/9r+
71Umi4AKLoZ9dInyUIM3EHg9pg5B0eEINrh4J+OPGtlC3NMiWxdmIkZwzfXa+64Z
8k5aX5piMTI+9BQSMWw5l7tFT/PISuI8b/Ln4IUBXKA0xkONXVnjPOmS0h7MBoc2
EipChDKnK+Mtm9GQewOCKdS2nsrCndGkIBnUix4ConUYIoywVzWGMD+9OzKNg76d
O6A7MxdjEdKhf1JDvklxInntDUDTlSFL4iEFELwyRseoTzj8vJE+cL6h6ClasYQ6
p0EeL3UpICYerfIvPhohftCivCH3k7Q1BSf0fq73cQ55nrFAHrqqYjD7HBeBS9hn
3L6bz9Eo6U9cuxX42k3l1N44BmgcDPin0+CRTirEmahUMb3gmvoSZqQ3Cz86GkIg
7cNJosc9NyevQlU9SX3ptEbv33tZtlB5GwgZ2hiGBTY0C3HaVFjLpQiSS5ygZLgI
/+AKtah7sTHIAtpUH1ZZEgKPl1Hg6J4x/dBkuk3wxPommNHaYaHREXF+fHMhBrSi
yH8agBmmECpa21SVnr7vrL+KSqfuF+GxwjSNsSR4SA==
-----END CERTIFICATE-----
"""

let samplePemKey = """
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEA72vMk44TxyawioAkwKscPGQEAyBmEywnzrcyda1XPkkgkroI
oj827bq0TOiQfLcQj3nrlHCKS9q6F4yxZpMUDg8P8/6zUO3FEIYhwrnH5KhM3sOu
flm56gk1lF9Ni436DDKGmvOtmtiNem8RU9i5Ih5SorlcatPIUDa4aP3Bjd/0gXit
3slPR7BFvVTw5xHvFBtcoaORjiIkTVPJ+YiwFlugpob9phr0pudbJOQOyxoQtZQg
quPDC4+BWBK+UBiajXYyWwYTOQ73PvyO8WaFQ6xoSV0zxRrYCE4pbShJiBq5W6uj
8Cn+jnOfw8MgNqmX2D7m+M3Yu5ypfZr262gW/FIpdPg29+kv18m/N0E0wzjGmq0c
iRXR+SIxtaQRbYUWU5cqcglXzBPhr2J264gMyDw7uhz6C32kb0wdNa2FebhLb0MB
FOp9njxtbvvPxGsRRFXTejTlv+3C4AlJHLI4JSLrXIyjdg3K15uNjZbc/Gqmr5iZ
PmqGoFkMuVMsym24V0hK/pJCCDsmgUcYxZFdRq8yP+yfmpkPilDJlOgcnZW2Dlb8
wjWkrBzegoPozf/sZ/fmv3ZX+jHpdPv5+cSwAfwC1CJkmQRu/MnmWlSKFIhpXdr9
L6OeTsvDxOm+O2l+M6D7AFuVzfw5r22TZZ1fBgNue9t4vbpabIfBBNQGLWMCAwEA
AQKCAgArWV9PEBhwpIaubQk6gUC5hnpbfpA8xG/os67FM79qHZ9yMZDCn6N4Y6el
jS4sBpFPCQoodD/2AAJVpTmxksu8x+lhiio5avOVTFPsh+qzce2JH/EGG4TX5Rb4
aFEIBYrSjotknt49/RuQoW+HuOO8U7UulVUwWmwYae/1wow6/eOtVYZVoilil33p
C+oaTFr3TwT0l0MRcwkTnyogrikDw09RF3vxiUvmtFkCUvCCwZNo7QsFJfv4qeEH
a01d/zZsiowPgwgT+qu1kdDn0GIsoJi5P9DRzUx0JILHqtW1ePE6sdca8t+ON00k
Cr5YZ1iA5NK5Fbw6K+FcRqSSduRCLYXAnI5GH1zWMki5TUdl+psvCnpdZK5wysGe
tYfIbrVHXIlg7J3R4BrbMF4q3HwOppTHMrqsGyRVCCSjDwXjreugInV0CRzlapDs
JNEVyrbt6Ild6ie7c1AJqTpibJ9lVYRVpG35Dni9RJy5Uk5m89uWnF9PCjCRCHOf
4UATY+qie6wlu0E8y43LcTvDi8ROXQQoCnys2ES8DmS+GKJ1uzG1l8jx3jF9BMAJ
kyzZfSmPwuS2NUk8sftYQ8neJSgk4DOV4h7x5ghaBWYzseomy3uo3gD4IyuiO56K
y7IYZnXSt2s8LfzhVcB5I4IZbSIvP/MAEkGMC09SV+dEcEJSQQKCAQEA/uJex1ef
g+q4gb/C4/biPr+ZRFheVuHu49ES0DXxoxmTbosGRDPRFBLwtPxCLuzHXa1Du2Vc
c0E12zLy8wNczv5bGAxynPo57twJCyeptFNFJkb+0uxRrCi+CZ56Qertg2jr460Q
cg+TMYxauDleLzR7uwL6VnOhTSq3CVTA2TrQ+kjIHgVqmmpwgk5bPBRDj2EuqdyD
dEQmt4z/0fFFBmW6iBcXS9y8Q1rCnAHKjDUEoXKyJYL85szupjUuerOt6iTIe7CJ
pH0REwQO4djwM4Ju/PEGfBs+RqgNXoHmBMcFdf9RdogCuFit7lX0+LlRT/KJitan
LaaFgY1TXTVkcwKCAQEA8HgZuPGVHQTMHCOfNesXxnCY9Dwqa9ZVukqDLMaZ0TVy
PIqXhdNeVCWpP+VXWhj9JRLNuW8VWYMxk+poRmsZgbdwSbq30ljsGlfoupCpXfhd
AIhUeRwLVl4XnaHW+MjAmY/rqO156/LvNbV5e0YsqObzynlTczmhhYwi48x1tdf0
iuCn8o3+Ikv8xM7MuMnv5QmGp2l8Q3BhwxLN1x4MXfbG+4BGsqavudIkt71RVbSb
Sp7U4Khq3UEnCekrceRLQpJykRFu11/ntPsJ0Q+fLuvuRUMg/wsq8WTuVlwLrw46
hlRcq6S99jc9j2TbidxHyps6j8SDnEsEFHMHH8THUQKCAQAd03WN1CYZdL0UidEP
hhNhjmAsDD814Yhn5k5SSQ22rUaAWApqrrmXpMPAGgjQnuqRfrX/VtQjtIzN0r91
Sn5wxnj4bnR3BB0FY4A3avPD4z6jRQmKuxavk7DxRTc/QXN7vipkYRscjdAGq0ru
ZeAsm/Kipq2Oskc81XPHxsAua2CK+TtZr/6ShUQXK34noKNrQs8IF4LWdycksX46
Hgaawgq65CDYwsLRCuzc/qSqFYYuMlLAavyXMYH3tx9yQlZmoNlJCBaDRhNaa04m
hZFOJcRBGx9MJI/8CqxN09uL0ZJFBZSNz0qqMc5gpnRdKqpmNZZ8xbOYdvUGfPg1
XwsbAoIBAGdH7iRU/mp8SP48/oC1/HwqmEcuIDo40JE2t6hflGkav3npPLMp2XXi
xxK+egokeXWW4e0nHNBZXM3e+/JixY3FL+E65QDfWGjoIPkgcN3/clJsO3vY47Ww
rAv0GtS3xKEwA1OGy7rfmIZE72xW84+HwmXQPltbAVjOm52jj1sO6eVMIFY5TlGE
uYf+Gkez0+lXchItaEW+2v5h8S7XpRAmkcgrjDHnDcqNy19vXKOm8pvWJDBppZxq
A05qa1J7byekprhP+H9gnbBJsimsv/3zL19oOZ/ROBx98S/+ULZbMh/H1BWUqFI7
36Da/L/1cJBAo6JkEPLr9VCjJwgqCEECggEBAI6+35Lf4jDwRPvZV7kE+FQuFp1G
/tKxIJtPOZU3sbOVlsFsOoyEfV6+HbpeWxlWnrOnKRFOLoC3s5MVTjPglu1rC0ZX
4b0wMetvun5S1MGadB808rvu5EsEB1vznz1vOXV8oDdkdgBiiUcKewSeCrG1IrXy
B9ux859S3JjELzeuNdz+xHqu2AqR22gtqN72tJUEQ95qLGZ8vo+ytY9MDVDqoSWJ
9pqHXFUVLmwHTM0/pciXN4Kx1IL9FZ3fjXgME0vdYpWYQkcvSKLsswXN+LnYcpoQ
h33H/Kz4yji7jPN6Uk9wMyG7XGqpjYAuKCd6V3HEHUiGJZzho/VBgb3TVnw=
-----END RSA PRIVATE KEY-----
"""

let sampleECPemKey = """
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMJZj2Qw9NGv83izxbgRr5xRvb0RHymOfl5hDJ/RPI2GoAoGCCqGSM49
AwEHoUQDQgAEc5zHoemKB93GfO9MA/vLYEiYMtV3UWDIV88M/TP59R0dKIuPS2Dw
EeAoz1vgyHNpgE73eYX8NII6U11Xv8Lmgg==
-----END EC PRIVATE KEY-----
"""

let samplePemRSAEncryptedKey = """
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,701BA8806DAD9F13E63F41109F51B2AD

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
-----END RSA PRIVATE KEY-----
"""

let samplePKCS8PemPrivateKey = """
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIShGta1Mpj/QCAggA
MBQGCCqGSIb3DQMHBAjQbLTPjvMqpwSCBMh8omeDIM0ceuoiEhaepFqbst/jUwYh
m1pzLokTph0GS/81vmTDr9U7uI9rHiFbACRRMQBH/cCkZFUN2Jo3pJXA4q3RvGsh
4UIaWiP+SNkzKR54QcuWRzYoQs/YH8VickNp2per3zQ9R0Regx1ZaHSCk3cFRFy3
4sJtgoquwJYD2vUdQvhwcuF2Syl/VCpaQ0+KtfBqJ+4YLJPQcsL+OKLlaWFY0ivO
2oSVCg3QJrVbS8TDnrIgeL8MNhyVHQbuSyh2MlXKcjiKlJHdHXSlYSINgpUsc/Eg
cTSgod0JXvjbExrtBx2mODwM5hzDkGpdub+TptXinQg3FQjUKhBh/+wrP0HoKBcn
UFE1emd3n1s0MFN28uSN3OcX3833Lt4KAnxF4xaPfWEAk/2yuukiUqKU+K9cEhNX
V1arxKq8RLB7n7o6YFt3xuVgAJYWDk6nyr/0I2LgFj2Jz/C2v+YBFYGUcQUKgHQw
OLzzZnCrPj8JIP2cUqagZrW7JOoMsFCtroJptImaqhsm/4i3tyf2uoUWglZN8DVE
WbNbnAr5KZSl9U1/sNuEesixIWd+RrJC/l0tNmScCvJifL9WrJnccOI83EAkmz/+
W8UpcPCscAmAdOcjFQl8T37xHGxwVcvh8LyaoacBqQCYiZzO/M6bA2YuBYVpkk4v
DFXMmy2SaHGGhGHDmyn4uuzykGCOn1ZN92eT6PXZCmHz0/QCH6RIGx2cK5frfhUP
icU30GnK1jRv8QFHVx9IZQpHbALRgSNMbtF8EqWmONUIs9wQIQtEMZ2AYwq8gKL2
9Cwk2SkqO0Y8dbE/lw+iBA37/NO7KiSLB/Mpq0/zX5SfBVcGZAVzGKiyeOW5sKcI
pSOTTv5jLkoEnels2f0jsPM7aMjG+ys6wveL0tDhfKSbtjyC8Zw/eXpK9AHGW8Hr
xM7hwTkQpznyt/NUIDmjrDHg7n6O9sp7KWduP1L9bYC/n5Dj2gnxHj6FFTpMqmm7
Q6GEj/dttmqvSYeG93heWqoS/j6j45dppoKG/3vU9UWODStcc3y66WJ2ULEY0/CF
IiBd33GJgIKUJlrMGwUSAPxH2wklF3VwWFVXMnLbqpggaWlVxzVnvGjnzoHm3AW6
hWCMnvsP/pYVBMpaKKdPF6PCW1yQXjTbA67gxpGECoin2Bu/rp+t0GeVmgTcCS9a
Y2Su4cpwCD1ngIrdodWhVVJSObApRdn3SDI2xOZUgZPVT52AtEMPQ3R5eoIOfLI6
CPC7cYl2JDmMkKGLaSom1zZpCoXtPTkxDAIpaG4ofT6pIDibCSywllL1KeeVw4WX
Cr2b/BS5TZNFyPzdrMaN5og6hNkbyca73SyEADnJtHTQc6mi/Q93al4TI3RYaVpk
KWwIW4kZE/p5pONeZDNNt7dKrgkjaTylNpM9jdnBL3hU5Fxr4I6a6+IBWQC03EwC
o2zT+g6YmVkod050GMv0V60npTpbOpWIamzB+q3GMMkU9NNyw8xH7RkNS78eWLVv
niWQmWlbkzLEf5PT264+c4w9IkE8aUKY2V8Ev2k1FXZcLdfw3G5yVzrjXoAwFUaY
xnOAdO/QLMtD55Kn+jzV6dCXmyZQkBJAMLBF5xEX9DcnXCptZ2Asgvxa4EpO7jzX
v5o=
-----END ENCRYPTED PRIVATE KEY-----
"""

/// A CA that expired a while ago.
let sampleExpiredCA = """
-----BEGIN CERTIFICATE-----
MIIC5TCCAc2gAwIBAgIUTSNLkfg8YiYSq+fnrXP25txgCkUwDQYJKoZIhvcNAQEL
BQAwIjEgMB4GA1UEAwwXYmFkQ2VydGlmaWNhdGVBdXRob3JpdHkwHhcNMTkwODA5
MTk1MTExWhcNMTkxMTE3MTk1MTExWjAiMSAwHgYDVQQDDBdiYWRDZXJ0aWZpY2F0
ZUF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKqWcbgw
TFX14tKxUMIrla9Y0aLddlnnTDqsxtxJ7dSjE4+OBkVBslCq4WtjgaeubdHkTCtc
GRVeOpXVcEyznGBGW5k/5gCkmaGPe8jI4+caavtXnoTdPU91ukYkZkBXzCgycVS8
kQxyPwvTDUOfHQ3VqUfc2LMTXQYU3vzyrPzq7XAWgZR9d5lOtB9tpGnxCRP8GOFO
KHa3KroiRxJb2cReJsayJWx713pje5lPKtSKP0iYICR2kYgtP+8Y3wPzcLzPRM9u
6a0olO6PFFWdPNRtivObCr5Y3Cy0P8i2ZSyOO2c6cn0ksLmCe/qrRX9HKx7TrmEu
7Rs+ql6liiyrQ7ECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEAWSCh35Fk5Td+8uV3oe+K+IPbTrhtNmrwC42sGw/mpQC56zNjlDt9
jBZVZbu5iAwO/nrtn+JpCSA3ADugjisQKQdELb/ogaCnIu2vY/fjHv7a9/tYoYc2
i/rtcXIQdhSrniZuVnKG1Keu5qohKIP1ne4TAxADTlzl3Dx7QH/32hUBlJFwYiDQ
JIuZD9LM5Ic9jtrsfTN79tNPM3eHofWUdKyUk9fTrM7/28kSERLJJz/RcXDMP85z
5Y0zZar+qh+9A6kYy/xcaFVOX0bDsuArBA6d/n0skqJN8gylOvdsnpeJRrXxOSSE
dcvafu1dqy0zZdFMSzymwRnprqgdFYC1xw==
-----END CERTIFICATE-----
"""

/// An intermediate signed by the above CA.
let sampleIntermediateCA = """
-----BEGIN CERTIFICATE-----
MIIC3DCCAcSgAwIBAgIUDK9fkCTocM8Yu3csdNcm86ahG4IwDQYJKoZIhvcNAQEL
BQAwIjEgMB4GA1UEAwwXYmFkQ2VydGlmaWNhdGVBdXRob3JpdHkwHhcNMTkxMTE2
MTk1MTExWhcNMzAwNjAyMTk1MTExWjAZMRcwFQYDVQQDDA5pbnRlcm1lZGlhdGVD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALdj2KDFRR6Es/RpN+07
q4IiQMoLVcDu/CoxCJSteNuNShmScfyqG4e6AFDOKxjv2U2NHWmhVbBYN7b9jStf
uZBpvz4/JY4+mVfGASL7mBkcsTLzNG+7rmQ0Oi271KL5WlDmw6DUMIFNvYSy0q9y
MFS5qSYJh4JnXXtdxkGIjDmrWy1hCRzIGCpDZXvNjnhJDphgH3Ss+PR7wTJZXRiJ
uoO4plWWl3JsRIRoyuL7K2CeWrR7CvIEThTF/D2P/7odf+CNz//46lC83b5eKdIA
GD+RECQaA1YFygAbvEln+za5AjnH11Y310zvzAb1gCxGuxNaABNKhYLcDpDL/Mcd
Il0CAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA
X4D5jVygEJyp6Ub/Yao9miF/vZW0bep00gOzHVJ8i6y1Qjn9ieVyrX9l6V8ZNwQU
wrAkse99WoI94LT8QLWlAlDB7S0IS8IK7gkt+06pSbrhW5GJtEQJjug84DkOVqOm
JSCupM2BEiHVQPYerF+sJ7I/4eENkafVn0zXSL9SEh9fPXBYJKiCYIxKWmGF3KOp
KG5Y1W9sWz5NaatoL1kHFGDeuDWLwXJ8WZuNrtJNBe1iQ8yvuO1STRzjtq2iTDk3
TCYZoKnV3ui38BJn7libgUsN3lHD4yKdrw5LNeyjrYOZ5oFhe4QBQv0ZA+wUR+h7
1A4gDvFcIkbYSywqlirBQg==
-----END CERTIFICATE-----
"""

/// The intermediate above, self-signed, as a root
let sampleIntermediateAsRootCA = """
-----BEGIN CERTIFICATE-----
MIIC0zCCAbugAwIBAgIUDK9fkCTocM8Yu3csdNcm86ahG4IwDQYJKoZIhvcNAQEL
BQAwGTEXMBUGA1UEAwwOaW50ZXJtZWRpYXRlQ0EwHhcNMTkxMTE2MTk1MTExWhcN
MzAwNjAyMTk1MTExWjAZMRcwFQYDVQQDDA5pbnRlcm1lZGlhdGVDQTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALdj2KDFRR6Es/RpN+07q4IiQMoLVcDu
/CoxCJSteNuNShmScfyqG4e6AFDOKxjv2U2NHWmhVbBYN7b9jStfuZBpvz4/JY4+
mVfGASL7mBkcsTLzNG+7rmQ0Oi271KL5WlDmw6DUMIFNvYSy0q9yMFS5qSYJh4Jn
XXtdxkGIjDmrWy1hCRzIGCpDZXvNjnhJDphgH3Ss+PR7wTJZXRiJuoO4plWWl3Js
RIRoyuL7K2CeWrR7CvIEThTF/D2P/7odf+CNz//46lC83b5eKdIAGD+RECQaA1YF
ygAbvEln+za5AjnH11Y310zvzAb1gCxGuxNaABNKhYLcDpDL/McdIl0CAwEAAaMT
MBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAWervzZUKKDEb
O9nXiJckFEBmCOlQuQ6O6+hVyRLAugtPDUyesCUDqoLF2wmMKNRM322gJKaWShaM
ueBrXHIx+ERXKJsgFic8b2m/v+VT16aAVPvQCLmZBpWR2ICqgNTpUzoDXqIZk/9l
ZkJZMaS9kiQmEPeTDH2O8acO9TjqmQbdZa+q6kBWBnNzLPOu5ziEdKrh7rNzikUw
qe0yKxavA5L8l8uWumGC8L6GE7ie7X8oMLwaLXFXt2TG9ZENrVQ0xcLSKTBAF2yL
4lqh2YnpZhntnCtv9Qvx81Asp2+6YfocAe9IKNIA534R2FgoZwt24SokDBhfg49d
2fV7ZO/cqQ==
-----END CERTIFICATE-----
"""

/// A client signed by the intermediate.
let sampleClientOfIntermediateCA = """
-----BEGIN CERTIFICATE-----
MIIC4TCCAcmgAwIBAgIUFJCxfytdLl/FpvlUqwJbztiALjcwDQYJKoZIhvcNAQEL
BQAwGTEXMBUGA1UEAwwOaW50ZXJtZWRpYXRlQ0EwHhcNMTkxMTE2MTk1MTExWhcN
MzAwNTI4MTk1MTExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDS9XBpPYlP3ToaYKmWaqhXd4lnLSvjReuknE9I
UmvFBoPTyGRU2UNv8N9tFT3xMOX2DrGOn7eVqXBXOvKYRB8+q3CIsh3F/5smdNKQ
PfsL2tFL4d2lvrZ+2GOr2yRtPm9nH0N2wrmJi6GtR1J+x2Uvm7EoHvk3Ujbo77fB
HvFauvwA3GsFT10J+f5buPcNW0rdpo+ASMfMpfBMsr0Ucy1ys9XM/ehCMeWMiX/d
d+fxqmOtl1tGyw4/Bbub5uf/HkiJStbKSCMgs7E4VgVhqFMu6jpeMlADXgDeOKEa
rW+Ds8eb3TkdIlYE2nmwxvdOPeW3AgChkE5RCRYW0aALTwEbAgMBAAGjJjAkMAwG
A1UdEwEB/wQCMAAwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUA
A4IBAQBarG3HrdOULNMGfY/UrSoc2qCQoK33SxM43ecFSXsDbPXLOZHp9iQmib1f
uKy2m4VVkxtxYrQ2i7bueqgRt91rM7hHR8+uopj/BdNYFZfIik+VNFoyKJeATYcx
FRjjAAoMpVYdAJXvtckNix8mlAdan5VNL1AsHYum25BjClQEy+kHM1i3bDLOIiDB
dKMwvI/1ZnUgrMFnAvK8U8WxbxVxij8IeloW+YgjOYXqzjCysVh3L7HkI3AOi6yw
eMNi5idG30y1NnTJWTSWzwR4UcoeLFdzMAmAxo5IVJBYnngcLTEkfofGFC9k2ODI
XANkLW5BKAnSmOQUBrExL4yAj5jt
-----END CERTIFICATE-----
"""

/// The key for the above cert.
let sampleKeyForCertificateOfClientOfIntermediateCA = """
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDS9XBpPYlP3Toa
YKmWaqhXd4lnLSvjReuknE9IUmvFBoPTyGRU2UNv8N9tFT3xMOX2DrGOn7eVqXBX
OvKYRB8+q3CIsh3F/5smdNKQPfsL2tFL4d2lvrZ+2GOr2yRtPm9nH0N2wrmJi6Gt
R1J+x2Uvm7EoHvk3Ujbo77fBHvFauvwA3GsFT10J+f5buPcNW0rdpo+ASMfMpfBM
sr0Ucy1ys9XM/ehCMeWMiX/dd+fxqmOtl1tGyw4/Bbub5uf/HkiJStbKSCMgs7E4
VgVhqFMu6jpeMlADXgDeOKEarW+Ds8eb3TkdIlYE2nmwxvdOPeW3AgChkE5RCRYW
0aALTwEbAgMBAAECggEBAIzYFxv8XK+4iPFRdggZ35i+EzuSegm8Be6Z+YjUlmUt
y1fbI7lOcOrMy669juR3/CCCgOMzGVPPk1R547vrR10FAxYQrTYjSIetWWO6LeEl
T7U08FGXeapIeIslvTU+iQw1YEprCYqecewJgTdpktHtRaL+wu6/ci+k1G8YZJVo
qPmkSJigrEppm8ciXjvae+89jgUSEUmumI7A+LwiD2qr1GjGMg01TvKJ3jVrU0yq
cGP58zAY/W1DcenJm26bpirE82Wnesosv3hQf2LBMGBMyVp6ErNzITSNN1fUSfyB
231DlGDor9oopfGfk9ApDUUVNXfFUv6ODnCSGBcdUkkCgYEA8snNvwok8IjbXzeG
zdDVUCVLX/o/vrFQg0KmktTArklLe7vAgcbmCp5TbdZKnpHam2KNu6ucgla5ZchV
5vHbAdAhhvZFnYEaDPlpvueVT2jLWZHvsld17vfy7PVpZBwJSa2SQL4aC5sk+Bsn
5LbSE4OL2o0KLQr6+BOAa9soVw8CgYEA3nA6u4Pxdhlf4UGo1fMWFbeXvU6myBs2
JXiAPEM/9wKiGS3LOseqBzLBAoiWND9J7ynDJ+w5uuezwJP6MZImj+J0kbXEm0vy
3iUBGBQvj1FJLN+wJx1QEzZBa+rslqX7vE+YsByJwfffqonGwXpj94Qxf6HMMDea
fRuHxqAjVTUCgYBsXe7bymdahXuFMH+W9hOARmUyXbx+HR7Wt7Up7JRkNorem5r9
Ug3zx19tsyxzQp7UpFSm455j/tmZuKW/A0zBrmiImPvRpYI/MEQm1a8rVpcNT7ox
XCBjnYBsi82SxYDPxg11oGR3sbP6mgRgbcmutBSEZFeaa0BB4lJ70cJbuQKBgQDE
a1gBo3ZB8hAvafp7yqby0GbmnKA7zYOXvPuHu16tcR7QmxZ9tjgXGSNEaHYydryD
u14AT+F+gQHCiSkCQutYXQDQdjDBbWRt80EvEQwaQw4Z2QDE2WaPQHaupAj80l8j
nynWQa0HoilYf0cKLFhABfRrnuUeossBtKDFrTzmDQKBgH2uBQ2v0hV3EW7u2wdy
y7V9lkY+GDm51P1GWAH5c0BBZp3iAW1IBNzbUB8wXVJmhYPWO5Mh7wCAnr18HEZz
OjJVhqRxwhY4NEUsyI86Xxb7rV23HAM6laDItQ/bPlR+b7py5GWCH/DRhhZjHuta
yVOAYA18BnJi7O7Cwd6krmQd
-----END PRIVATE KEY-----
"""

let sampleDerCertSPKI = Array(Data(base64Encoded: """
'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA72vMk44TxyawioAkwKscPGQEAyBmEywnzrcyda1XPkkgkroIoj827bq0TOiQfLcQj3nrlHCKS9q6F4yxZpMUDg8P8/6zUO3FEIYhwrnH5KhM3sOuflm56gk1lF9Ni436DDKGmvOtmtiNem8RU9i5Ih5SorlcatPIUDa4aP3Bjd/0gXit3slPR7BFvVTw5xHvFBtcoaORjiIkTVPJ+YiwFlugpob9phr0pudbJOQOyxoQtZQgquPDC4+BWBK+UBiajXYyWwYTOQ73PvyO8WaFQ6xoSV0zxRrYCE4pbShJiBq5W6uj8Cn+jnOfw8MgNqmX2D7m+M3Yu5ypfZr262gW/FIpdPg29+kv18m/N0E0wzjGmq0ciRXR+SIxtaQRbYUWU5cqcglXzBPhr2J264gMyDw7uhz6C32kb0wdNa2FebhLb0MBFOp9njxtbvvPxGsRRFXTejTlv+3C4AlJHLI4JSLrXIyjdg3K15uNjZbc/Gqmr5iZPmqGoFkMuVMsym24V0hK/pJCCDsmgUcYxZFdRq8yP+yfmpkPilDJlOgcnZW2Dlb8wjWkrBzegoPozf/sZ/fmv3ZX+jHpdPv5+cSwAfwC1CJkmQRu/MnmWlSKFIhpXdr9L6OeTsvDxOm+O2l+M6D7AFuVzfw5r22TZZ1fBgNue9t4vbpabIfBBNQGLWMCAwEAAQ=='
""", options: .ignoreUnknownCharacters)!)

// Custom Root for the certificates below.
// For example the following two certificates were issued from customCARoot:
// 1. leafCertificateForTLSIssuedFromCustomCARoot (Used for TLS)
// 2. leafCertificateForClientAuthenticationIssuedFromCustomCARoot (Used for client authentication)
//    The client authentication certificate contains the Extension for  Client Authentication.
//    Which is required for testing with the CertificateVerification case of .fullVerification.
let customCARoot = """
-----BEGIN CERTIFICATE-----
MIID8DCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjERMA8GA1UEAwwIQ3Vz
dG9tQ0ExGDAWBgNVBAoMD015IENvbXBhbnkgTmFtZTELMAkGA1UECwwCSVQxCzAJ
BgNVBAgMAkNBMQswCQYDVQQGEwJVUzESMBAGA1UEBwwJQ3VwZXJ0aW5vMSQwIgYJ
KoZIhvcNAQkBFhVjdXN0b21fY2FAZXhhbXBsZS5jb20wHhcNMjEwODEwMTMyOTQ3
WhcNMjIwODEwMTMyOTQ3WjCBjjERMA8GA1UEAwwIQ3VzdG9tQ0ExGDAWBgNVBAoM
D015IENvbXBhbnkgTmFtZTELMAkGA1UECwwCSVQxCzAJBgNVBAgMAkNBMQswCQYD
VQQGEwJVUzESMBAGA1UEBwwJQ3VwZXJ0aW5vMSQwIgYJKoZIhvcNAQkBFhVjdXN0
b21fY2FAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDlKh/b+/ZZm5mHQlyFskX8kmIz4Uk1l0qIc+IkhmVgGF/RYHJkNb334L7FYO+u
gf++jOHcQUcCft1d7I/Zj9dwQGzkkeEiHslZLoVk80zsg0PJ1MxvWdAEn9pR6kwy
nALwDoTVQOlYrVVWwCGfQS2z0Gg14H1QX5IVu/HMpk1eeMKhPWk9+ciTDLZ4a06/
LreTt1ypbrvWXIOWUeR9cf2w2DWDSRDVciav5y4ZK0P5F6TSGq/l7YlUPV9igrrM
Xu9gmJqhcS4NmggBEVisVTydrD/3REpJ3dX/NnZy2m22WEsbsUcGP33HFJRR8TGI
qJ6Cek47ZdUES4IO4N/iAuwHAgMBAAGjVzBVMA8GA1UdEwEB/wQFMAMBAf8wDgYD
VR0PAQH/BAQDAgKkMDIGA1UdJQEB/wQoMCYGCCsGAQUFBwMCBggrBgEFBQcDAQYH
KwYBBQIDBAYHKwYBBQIDBTANBgkqhkiG9w0BAQsFAAOCAQEAF4C77U1HCYwR4SA1
rvs6IIBXH4/xjR8To4YgfQIzI1COqkN+ONhUkLVRVj2PzwcsaX1yVPqj5E2IvOcB
MDHBTVRWlEL16giCYkByqr4rhurk/e7Rnl6kfNce4jCon+s0rWQQwypIx3a74eIx
bF0volJIQm9ygXqcOJLQtGc0PI87zDZOETzmbqAWzTUs/CgxdTpdug8Y0Ikcggtt
9i1fvSRTk3KTZ8SSoGjcpYAqFCa3/ayRyLRRoYqLkOwZ61YGe6zu4aDrQxcTT5xi
22527/fEEHBNhCVh1WcSO0WVj+AgfAGQspJmH+Ke97D6sbqPpGjc8k1VWuFnq9nq
AxBQdA==
-----END CERTIFICATE-----
"""

let leafCertificateForTLSIssuedFromCustomCARoot = """
-----BEGIN CERTIFICATE-----
MIID5TCCAs2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBjjERMA8GA1UEAwwIQ3Vz
dG9tQ0ExGDAWBgNVBAoMD015IENvbXBhbnkgTmFtZTELMAkGA1UECwwCSVQxCzAJ
BgNVBAgMAkNBMQswCQYDVQQGEwJVUzESMBAGA1UEBwwJQ3VwZXJ0aW5vMSQwIgYJ
KoZIhvcNAQkBFhVjdXN0b21fY2FAZXhhbXBsZS5jb20wHhcNMjEwODEwMTMzNDMx
WhcNMjIwODEwMTMzNDMxWjCBizESMBAGA1UEAwwJbG9jYWxob3N0MRQwEgYDVQQK
DAtDb21wYW55TmFtZTELMAkGA1UECwwCSVQxCzAJBgNVBAgMAkNBMQswCQYDVQQG
EwJVUzESMBAGA1UEBwwJQ3VwZXJ0aW5vMSQwIgYJKoZIhvcNAQkBFhVjdXN0b21f
Y2FAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+
52XknS1R0J57eiVAUfVqzAsoemSgCiCmFoTmkcpuP5XGBf0S2NGNI2EtwQE79eHK
Z2KyZX4ilF60bvPP+iOUbynoj2VGRHcRIsnNxL99oBM1X8FAXgRvLszD2Zbg6HBF
GJwfnBpRQK1lJqUdM1A1fbNj3KB7yJ4OK38BiH2Cfk6ohWIpMqrdvvZKx2sRuvUs
eaOs3dQ1uPlZmK6BKvq+JvPPcqxJmmrgvaw8WqYyJSwXo0seoCs1izVVpKHpxFw0
+F1yxTMCVXDlt5sFdFmPonzBkldynrQzBKhEuIsRTmUWKaOFDJ6Xeo48tXQgj7SC
pdoL2aTqnsNZOcf1T3A/AgMBAAGjTzBNMA4GA1UdDwEB/wQEAwIFoDAfBgNVHSUB
Af8EFTATBggrBgEFBQcDAQYHKwYBBQIDBTAaBgNVHREEEzARgglsb2NhbGhvc3SH
BH8AAAEwDQYJKoZIhvcNAQELBQADggEBAB+4PihYJj0mVpomcwgRGuq7gHhtgT/r
QAX9RkZQ4KcVsljGtbWChUML+bkSNujB4LwaP3bjfukDshYeB66WBJkhGuFNjvhC
wXq0pyO89xlGp0TdaMrNsNhv7dVGYoe0j7rgrhmpk3U1hKlWl23z0GRZ6x4vuewB
ckKz664eAErKl5xx1o6IVUQzcDE0EclrhT7QaBzKDT9EKeuyfAtbruFfnuzCs0RJ
GS1zOoLQ1ZWvOov8i0YnjTvvVcybEzc0qoVejtK2SGvAqtkGckM6IL/g7E5WSKGB
XHkBcrBeSIzdYrxM0qwi+uNemLRLhJ7YfzGyb+EKE/EY3OKv7VLLmzI=
-----END CERTIFICATE-----
"""

let privateKeyForLeafCertificate = """
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+52XknS1R0J57
eiVAUfVqzAsoemSgCiCmFoTmkcpuP5XGBf0S2NGNI2EtwQE79eHKZ2KyZX4ilF60
bvPP+iOUbynoj2VGRHcRIsnNxL99oBM1X8FAXgRvLszD2Zbg6HBFGJwfnBpRQK1l
JqUdM1A1fbNj3KB7yJ4OK38BiH2Cfk6ohWIpMqrdvvZKx2sRuvUseaOs3dQ1uPlZ
mK6BKvq+JvPPcqxJmmrgvaw8WqYyJSwXo0seoCs1izVVpKHpxFw0+F1yxTMCVXDl
t5sFdFmPonzBkldynrQzBKhEuIsRTmUWKaOFDJ6Xeo48tXQgj7SCpdoL2aTqnsNZ
Ocf1T3A/AgMBAAECggEAdLb8sNz3zEGD43I2PDDfnr/JQqIxyzbl5yV1c5JG9Uii
xUL8Cv3MgEHVNCgAHSyjMyAqU2+Bwpp7nE0Je2ovPp0IPksNW/yX3z4pq0hS2vd3
RvaYLEZO57rxLfxmJnN10IjPSvQhkvO8D0+lO0kYDNwhRTiqVYO+PmORbtqIAbMx
Cevcqyx3S42ngakAZiXXbUDPzFWBs5UPkBjPEiuf2kLHwnltfCBl3BYusFo/e2fd
vA6BY/0hledmM2qULQWv6xvACapJ7ZvnsctugaLOgml7jGSuPxyfp3l8yuSquPoP
qCqTm375mFzW5+URnWsaBDP+aeaa0NEwLBgmoI7dYQKBgQDeEesFhXcbq5xne7I0
k+r/9IE6kpA8oagVBb2HuMqmi3+Gz7G35pIb84WD1Qr0bnOAzvEjujM/XSIeS7yW
AlOwXyNeFqdgJJuNXC2AHxprjf13G/gJd5D1WIiAZJpSppa76nZqFE4feiKAKSv0
1833WOp+o2lFeQNgqe2eHxp1/QKBgQDcEnG8Z/lj9DsfqvfcW+Js2solf5NMIOP4
DMFeyJ1YU3OpLTyfgOvthwtDRdoPAn2aZD6NZerNhBFNdMdp07LUxZSGFb6Tt25C
NqO8gzwNnLI/cZ6Httm4YxPVC1MpybtPtWJxCcksFerBGGScBPnqdCPDsTEkLovq
3hBeh6L16wKBgHtvYj9zbD1JKmqq6ucmwRz8f0hbZykMgi0NP8hNAveH2p7Im3Qp
CVXYCoK4zJoJOtKCNK8zNIEn92r3lh+bs4D5oOMPnIFoV74/Wls47qqSBi1Kspgw
ibaWO2mCgfUm++n/7UoRd0svzDWIrRIvUiEGn3E8y6r+FM6KJbYae87RAoGARS5f
JrUgxvUt6OScCl+wLDwTM/qI2XO1dnK8DwnNvMhvIY2g8xtaD09WkQ1SYUmNJo3A
xD53s6eCsPC3B2OPYifCauxG/rS5KoN2sXon1LefqSYUieFHTBmJUH3A5PAPvBzv
F03WOc+h/pWmew1tavCblZcMNa2UOn8Ycj79UYUCgYB7FpPCSxOerUnd3b8WOjkK
F78k1rUxBGL0t31zfsAHr9YnRT+PwC56EfGntQpFQPN5KWVpAzX4OteK7f6LZjQr
xBOEqaSTHdD/YldNrqGyvtFgQa+ygYNYKvMyiEZPxpFiy9MtVLtU8qVjowSoxCei
xh02hyScDeaq3Tr+Ike2ZA==
-----END PRIVATE KEY-----
"""

let leafCertificateForClientAuthenticationIssuedFromCustomCARoot = """
-----BEGIN CERTIFICATE-----
MIID1DCCArygAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBjjERMA8GA1UEAwwIQ3Vz
dG9tQ0ExGDAWBgNVBAoMD015IENvbXBhbnkgTmFtZTELMAkGA1UECwwCSVQxCzAJ
BgNVBAgMAkNBMQswCQYDVQQGEwJVUzESMBAGA1UEBwwJQ3VwZXJ0aW5vMSQwIgYJ
KoZIhvcNAQkBFhVjdXN0b21fY2FAZXhhbXBsZS5jb20wHhcNMjEwODEwMTMzOTQ1
WhcNMjIwODEwMTMzOTQ1WjCBljEdMBsGA1UEAwwUQ2xpZW50QXV0aGVudGljYXRp
b24xFDASBgNVBAoMC0NvbXBhbnlOYW1lMQswCQYDVQQLDAJJVDELMAkGA1UECAwC
Q0ExCzAJBgNVBAYTAlVTMRIwEAYDVQQHDAlDdXBlcnRpbm8xJDAiBgkqhkiG9w0B
CQEWFWN1c3RvbV9jYUBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALQCAU1b2RdM9/P2BguzoSYDFvIgFmtZL6ti6RG2h4V+GCevtN9Q
fezCkUrqm2JZhgmyvMZ4fkLzxU7CFyasd/ycAE9Iz7z8hKrWkLkqi1V0y9shCR7f
AFkZ0o1f00BPHy0HP5rQf9yJ9W5Hk9czLg1VYOlo/BrplVEC4SX+MCHOeEXZ+FZ2
798H6E4U28/lxL/S7flUakNS7tdt7qtKp3yUvj15TM0SyFyK/t1yL2Ew4xyrGkcy
EWdyNMb/TmeC3MQbO8TswAY06vGYG1baVqmUYUs+PuypIA8yxHxIp4MWXT0JE0N2
HR8nFqhOWQZFxQ9BAbfZ3gvy9rVC820/si8CAwEAAaMzMDEwDgYDVR0PAQH/BAQD
AgeAMB8GA1UdJQEB/wQVMBMGCCsGAQUFBwMCBgcrBgEFAgMEMA0GCSqGSIb3DQEB
CwUAA4IBAQDdsPPJwwvlGfMnBZKF7jwpapmQBXJewXCLFJ0I2NKNtxdo+Cxznm27
99qte1udcQz6J5Zwb4b0cabJnvZWlCl1ov6ES2mKH7ZsH8FAYAqRc4CiUkdJxMnb
IO42C468GTN/IJIe7Xtuxz+Kc8IVHT+jIidfnZ3hvnRBzgrIR10dB+hCgmhqN+aO
wtA6o+dW2ggN2J4QVzKyLbIyBYNX29XLR9fXcw4tYEKk6MZ5YJRFkgx0+2YVg1rw
83ZkXbr3FIUYC3vL1RZWnokZaE4qiG3sbTNdirEk/h3yFP5+DzvKVKiEbX7qcVmv
WoNW8vsr4ZKijq4dBqBLCWjWhSRQ2FQp
-----END CERTIFICATE-----
"""

let privateKeyForClientAuthentication = """
-----BEGIN PRIVATE KEY-----
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC0AgFNW9kXTPfz
9gYLs6EmAxbyIBZrWS+rYukRtoeFfhgnr7TfUH3swpFK6ptiWYYJsrzGeH5C88VO
whcmrHf8nABPSM+8/ISq1pC5KotVdMvbIQke3wBZGdKNX9NATx8tBz+a0H/cifVu
R5PXMy4NVWDpaPwa6ZVRAuEl/jAhznhF2fhWdu/fB+hOFNvP5cS/0u35VGpDUu7X
be6rSqd8lL49eUzNEshciv7dci9hMOMcqxpHMhFncjTG/05ngtzEGzvE7MAGNOrx
mBtW2laplGFLPj7sqSAPMsR8SKeDFl09CRNDdh0fJxaoTlkGRcUPQQG32d4L8va1
QvNtP7IvAgMBAAECggEBAIUnwozV94XL8tMtV5WKYBd9S5j58XuhMqkF9sCalC9E
clvRFuvmX/AmkVGosB6VeJht9kSeV0/xgS/cVUHPbMaZI4WCp+D1rrGtHMtMVFt3
lWDYVCXY8in29xCLJPq6TKaDaSJ9P0gFaV8VZaBYBKXqVVDzzyGdTk3p4mC3YiVu
laB608AjHsWoPe9m1vKKEGjTBHqI8rcCw37/lRWgSqBK7suDPOndHrRHZMBXymbM
AGPA117vc28z5QmvYqR4ETH7HPrNIvJJ4cwtmG0/HvokrnxWkLB9sApIg7Sp9MnD
Ng8jxlBC4RtP4bdnTM28rXuSUSJWRljNYrFGnE5h6lECgYEA7oRiD6CFLkwWmSl1
XCCqMQYfhkNiqwl9Fqxe1CTmuPSzFd/03q3d2Ej2HQu3Ax6X5lyPK9YMZL//Yn4F
RpmtNdBp3akHjkxcQu5X+HubrUtf9FpjCHP58IjlgUr2pCcZcxbC7EFbsrb3d4Hn
ugflhlGUbJhJ5d+S41hlTqXexHcCgYEAwTO7084Lvh3JTMd6pLMj7OO4y4hwVp87
Sb14Msst4hNyHUQEVeN2I93rUhj5gcLYp6uLitRIELVJjqh9mIf+kXxiwqBX9wYv
Ia2iLFtsj0kYN+WQ50xs4RCoJyFim5dM0SDEZ5yAscIH5TI2q/qCC5dio6mndvNR
xecjPqKwBgkCgYEA5NcCtneOD/NUozKRtQhqAYscZ9bzLaJ273AFs4iMDNxJji1H
ZPZvqHmoGAoLVuTdXFlly+scDPXg8wBx02DSPJVvXQo1g6NjyZufr3n4zPVKZMjr
x0pufQb7G2du5+PTmQY3kjDK59Z/65spVuUIpCxVOTOLgw9UgOdom2KtLtUCgYEA
qnDRStGDWn08kReKArJnBxz+cdA0Crb+vtb/qw/DsqYlDdxrVroMByhH6W1O8ELM
j16vBBKyYMsN0WSjKGURF5f8KGb8M1ipS7S6VRdydhWt3+IOK38oroTbU2oIa+rW
Qcf+fMl8X1UlUfUydhXRlBhBVNDeg/m0MjruxNsRHsECgYEAl7WsK/LWh0MrHUcS
+lovtXaBcfdhN0Ot9y1hF2PKtH8MQC8W+XcYvPtbnxkPm84M0cmhl8KscEhHp7KW
ELE8PyOfZSwuVtSDSKO0SKT0XyZrZB1GZxfi5hZxmM+WH0DAFjzpYo3mIQEunDSP
WEGz8RfeuoKswoB627yAT97QbQ4=
-----END PRIVATE KEY-----
"""

// This is a root certificate used to setup and test sending CA names to
// a client during client authentication.
// This certificate is used to test having multiple root certificates in a directory.
let secondaryRootCertificateForClientAuthentication = """
-----BEGIN CERTIFICATE-----
MIIDBDCCAeygAwIBAgIBATANBgkqhkiG9w0BAQsFADAnMRgwFgYDVQQDDA9TYW1w
bGVQcm9qZWN0Q0ExCzAJBgNVBAYTAlVTMB4XDTIxMDEyMjE0NTcyNFoXDTIyMDEy
MjE0NTcyNFowJzEYMBYGA1UEAwwPU2FtcGxlUHJvamVjdENBMQswCQYDVQQGEwJV
UzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpQ6rCiy6vtan1tb4Mj
T7QSgv4sqDeV2OaXK/kEOcL8kUkflQ2rCG2YV4zSLI3T4tuqJyKecn8Zm0oXHLhb
N3z0y+jIzcs6FkHaIKQYT15nPp8bKSEolBxDUZR8aX646vAYo620SRwNhSfbJA7A
aV/ZEZUJi66vay/OXJ8ScwVv7sCF+oELnN3xV9HMaNzi1VySgGNGEuxSChYvwLzR
h8zSAejsJEOxN6022oxCsdoEL1ki2iRSrqfBVRPY4neV+lTTMPtYkh60ac5GqWhN
3mcsCa8RXy9jYGe5kzDoUdWnYvVCNWcp2iQ8vCictrRN2fww9dXnjOCZkXqvDshX
y0kCAwEAAaM7MDkwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwFgYD
VR0lAQH/BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBADobYdPIhAAV
UK7MUI24+xUx3QRQXGUhbjOnVN2H71hrzWdrZbrJXGxM61Z65eAehNK1pDK65AAP
uq+rtFeEGjoOjrIETZd7oAvQ/Db8vWTFEfo+RZYE5UhcnVzC3iJLnfmQMhDJLgEf
aK5bkwkywPXHClu4KGCT4q8832NsqPQdfTMx3P4HRYaa8sXifvA81WZ5y317wqbb
xjvyaPh+4O+jPgEZQPOozPlwCB+jFaL7+kt6xRApIpAMl21mdW/uh4/xMgGCVSBX
sg/EX3nBQSLySMcMuXa7oafAEiier2mPq/Q4QRnd7rJLG2uDUCKmcTSLlCaDfEs2
lRLt7jejU3k=
-----END CERTIFICATE-----
"""

let samplePemCerts = "\(samplePemCert)\n\(samplePemCert)"
let sampleDerCert = pemToDer(samplePemCert)
let sampleDerKey = pemToDer(samplePemKey)
let sampleECDerKey = pemToDer(sampleECPemKey)
// No DER version of the private key becuase encrypted DERs aren't real.

func pemToDer(_ pem: String) -> Data {
    var lines = [String]()

    // This is very inefficient, but it doesn't really matter because this
    // code is run very infrequently and only in testing. Blame the inefficiency
    // on Linux Foundation, which currently lacks String.enumerateLines.
    let originalLines = pem.split(separator: "\n")
    for line in originalLines {
        let line = String(line)
        if !line.hasPrefix("-----") {
            lines.append(line)
        }
    }

    let encodedData = lines.joined(separator: "")
    return Data(base64Encoded: encodedData)!
}

// This function generates a random number suitable for use in an X509
// serial field. This needs to be a positive number less than 2^159
// (such that it will fit into 20 ASN.1 bytes).
// This also needs to be portable across operating systems, and the easiest
// way to do that is to use either getentropy() or read from urandom. Sadly
// we need to support old Linuxes which may not possess getentropy as a syscall
// (and definitely don't support it in glibc), so we need to read from urandom.
// In the future we should just use getentropy and be happy.
func randomSerialNumber() -> ASN1_INTEGER {
    let bytesToRead = 20
    let fd = open("/dev/urandom", O_RDONLY)
    precondition(fd != -1)
    defer {
        close(fd)
    }

    var readBytes = Array.init(repeating: UInt8(0), count: bytesToRead)
    let readCount = readBytes.withUnsafeMutableBytes {
        return read(fd, $0.baseAddress, bytesToRead)
    }
    precondition(readCount == bytesToRead)

    // Our 20-byte number needs to be converted into an integer. This is
    // too big for Swift's numbers, but BoringSSL can handle it fine.
    let bn = CNIOBoringSSL_BN_new()
    defer {
        CNIOBoringSSL_BN_free(bn)
    }
    
    _ = readBytes.withUnsafeBufferPointer {
        CNIOBoringSSL_BN_bin2bn($0.baseAddress, $0.count, bn)
    }

    // We want to bitshift this right by 1 bit to ensure it's smaller than
    // 2^159.
    CNIOBoringSSL_BN_rshift1(bn, bn)

    // Now we can turn this into our ASN1_INTEGER.
    var asn1int = ASN1_INTEGER()
    CNIOBoringSSL_BN_to_ASN1_INTEGER(bn, &asn1int)

    return asn1int
}

func generateRSAPrivateKey() -> UnsafeMutablePointer<EVP_PKEY> {
    let exponent = CNIOBoringSSL_BN_new()
    defer {
        CNIOBoringSSL_BN_free(exponent)
    }

    CNIOBoringSSL_BN_set_u64(exponent, 0x10001)

    let rsa = CNIOBoringSSL_RSA_new()!
    let generateRC = CNIOBoringSSL_RSA_generate_key_ex(rsa, CInt(2048), exponent, nil)
    precondition(generateRC == 1)

    let pkey = CNIOBoringSSL_EVP_PKEY_new()!
    let assignRC = CNIOBoringSSL_EVP_PKEY_assign(pkey, EVP_PKEY_RSA, rsa)
    
    precondition(assignRC == 1)
    return pkey
}

func addExtension(x509: UnsafeMutablePointer<X509>, nid: CInt, value: String) {
    var extensionContext = X509V3_CTX()
    
    CNIOBoringSSL_X509V3_set_ctx(&extensionContext, x509, x509, nil, nil, 0)
    let ext = value.withCString { (pointer) in
        return CNIOBoringSSL_X509V3_EXT_nconf_nid(nil, &extensionContext, nid, UnsafeMutablePointer(mutating: pointer))
    }!
    CNIOBoringSSL_X509_add_ext(x509, ext, -1)
    CNIOBoringSSL_X509_EXTENSION_free(ext)
}

func generateSelfSignedCert() -> (NIOSSLCertificate, NIOSSLPrivateKey) {
    let pkey = generateRSAPrivateKey()
    let x = CNIOBoringSSL_X509_new()!
    CNIOBoringSSL_X509_set_version(x, 2)

    // NB: X509_set_serialNumber uses an internal copy of the ASN1_INTEGER, so this is
    // safe, there will be no use-after-free.
    var serial = randomSerialNumber()
    CNIOBoringSSL_X509_set_serialNumber(x, &serial)
    
    let notBefore = CNIOBoringSSL_ASN1_TIME_new()!
    var now = time(nil)
    CNIOBoringSSL_ASN1_TIME_set(notBefore, now)
    CNIOBoringSSL_X509_set_notBefore(x, notBefore)
    CNIOBoringSSL_ASN1_TIME_free(notBefore)
    
    now += 60 * 60  // Give ourselves an hour
    let notAfter = CNIOBoringSSL_ASN1_TIME_new()!
    CNIOBoringSSL_ASN1_TIME_set(notAfter, now)
    CNIOBoringSSL_X509_set_notAfter(x, notAfter)
    CNIOBoringSSL_ASN1_TIME_free(notAfter)
    
    CNIOBoringSSL_X509_set_pubkey(x, pkey)
    
    let commonName = "localhost"
    let name = CNIOBoringSSL_X509_get_subject_name(x)
    commonName.withCString { (pointer: UnsafePointer<Int8>) -> Void in
        pointer.withMemoryRebound(to: UInt8.self, capacity: commonName.lengthOfBytes(using: .utf8)) { (pointer: UnsafePointer<UInt8>) -> Void in
            CNIOBoringSSL_X509_NAME_add_entry_by_NID(name,
                                                     NID_commonName,
                                                     MBSTRING_UTF8,
                                                     UnsafeMutablePointer(mutating: pointer),
                                                     CInt(commonName.lengthOfBytes(using: .utf8)),
                                                     -1,
                                                     0)
        }
    }
    CNIOBoringSSL_X509_set_issuer_name(x, name)
    
    addExtension(x509: x, nid: NID_basic_constraints, value: "critical,CA:FALSE")
    addExtension(x509: x, nid: NID_subject_key_identifier, value: "hash")
    addExtension(x509: x, nid: NID_subject_alt_name, value: "DNS:localhost")
    addExtension(x509: x, nid: NID_ext_key_usage, value: "critical,serverAuth,clientAuth")
    
    CNIOBoringSSL_X509_sign(x, pkey, CNIOBoringSSL_EVP_sha256())
    
    return (NIOSSLCertificate.fromUnsafePointer(takingOwnership: x), NIOSSLPrivateKey.fromUnsafePointer(takingOwnership: pkey))
}