summaryrefslogtreecommitdiff
path: root/src/ssl/test/runner/common.go
blob: fd9fb3d55bff433604b47d7e66c169b607e445a0 (plain)
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
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runner

import (
	"container/list"
	"crypto"
	"crypto/ecdsa"
	"crypto/rand"
	"crypto/x509"
	"fmt"
	"io"
	"math/big"
	"strings"
	"sync"
	"time"
)

const (
	VersionSSL30 = 0x0300
	VersionTLS10 = 0x0301
	VersionTLS11 = 0x0302
	VersionTLS12 = 0x0303
	VersionTLS13 = 0x0304
)

const (
	VersionDTLS10 = 0xfeff
	VersionDTLS12 = 0xfefd
)

// A draft version of TLS 1.3 that is sent over the wire for the current draft.
const (
	tls13DraftVersion                = 0x7f12
	tls13ExperimentVersion           = 0x7e01
	tls13RecordTypeExperimentVersion = 0x7a12
)

const (
	TLS13Default              = 0
	TLS13Experiment           = 1
	TLS13RecordTypeExperiment = 2
)

var allTLSWireVersions = []uint16{
	tls13DraftVersion,
	tls13ExperimentVersion,
	tls13RecordTypeExperimentVersion,
	VersionTLS12,
	VersionTLS11,
	VersionTLS10,
	VersionSSL30,
}

var allDTLSWireVersions = []uint16{
	VersionDTLS12,
	VersionDTLS10,
}

const (
	maxPlaintext        = 16384        // maximum plaintext payload length
	maxCiphertext       = 16384 + 2048 // maximum ciphertext payload length
	tlsRecordHeaderLen  = 5            // record header length
	dtlsRecordHeaderLen = 13
	maxHandshake        = 65536 // maximum handshake we support (protocol max is 16 MB)

	minVersion = VersionSSL30
	maxVersion = VersionTLS13
)

// TLS record types.
type recordType uint8

const (
	recordTypeChangeCipherSpec   recordType = 20
	recordTypeAlert              recordType = 21
	recordTypeHandshake          recordType = 22
	recordTypeApplicationData    recordType = 23
	recordTypePlaintextHandshake recordType = 24
)

// TLS handshake message types.
const (
	typeHelloRequest        uint8 = 0
	typeClientHello         uint8 = 1
	typeServerHello         uint8 = 2
	typeHelloVerifyRequest  uint8 = 3
	typeNewSessionTicket    uint8 = 4
	typeHelloRetryRequest   uint8 = 6 // draft-ietf-tls-tls13-16
	typeEncryptedExtensions uint8 = 8 // draft-ietf-tls-tls13-16
	typeCertificate         uint8 = 11
	typeServerKeyExchange   uint8 = 12
	typeCertificateRequest  uint8 = 13
	typeServerHelloDone     uint8 = 14
	typeCertificateVerify   uint8 = 15
	typeClientKeyExchange   uint8 = 16
	typeFinished            uint8 = 20
	typeCertificateStatus   uint8 = 22
	typeKeyUpdate           uint8 = 24  // draft-ietf-tls-tls13-16
	typeNextProtocol        uint8 = 67  // Not IANA assigned
	typeChannelID           uint8 = 203 // Not IANA assigned
)

// TLS compression types.
const (
	compressionNone uint8 = 0
)

// TLS extension numbers
const (
	extensionServerName                 uint16 = 0
	extensionStatusRequest              uint16 = 5
	extensionSupportedCurves            uint16 = 10
	extensionSupportedPoints            uint16 = 11
	extensionSignatureAlgorithms        uint16 = 13
	extensionUseSRTP                    uint16 = 14
	extensionALPN                       uint16 = 16
	extensionSignedCertificateTimestamp uint16 = 18
	extensionExtendedMasterSecret       uint16 = 23
	extensionSessionTicket              uint16 = 35
	extensionKeyShare                   uint16 = 40    // draft-ietf-tls-tls13-16
	extensionPreSharedKey               uint16 = 41    // draft-ietf-tls-tls13-16
	extensionEarlyData                  uint16 = 42    // draft-ietf-tls-tls13-16
	extensionSupportedVersions          uint16 = 43    // draft-ietf-tls-tls13-16
	extensionCookie                     uint16 = 44    // draft-ietf-tls-tls13-16
	extensionPSKKeyExchangeModes        uint16 = 45    // draft-ietf-tls-tls13-18
	extensionTicketEarlyDataInfo        uint16 = 46    // draft-ietf-tls-tls13-18
	extensionCustom                     uint16 = 1234  // not IANA assigned
	extensionNextProtoNeg               uint16 = 13172 // not IANA assigned
	extensionRenegotiationInfo          uint16 = 0xff01
	extensionChannelID                  uint16 = 30032 // not IANA assigned
)

// TLS signaling cipher suite values
const (
	scsvRenegotiation uint16 = 0x00ff
)

// CurveID is the type of a TLS identifier for an elliptic curve. See
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
type CurveID uint16

const (
	CurveP224   CurveID = 21
	CurveP256   CurveID = 23
	CurveP384   CurveID = 24
	CurveP521   CurveID = 25
	CurveX25519 CurveID = 29
)

// TLS Elliptic Curve Point Formats
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
const (
	pointFormatUncompressed    uint8 = 0
	pointFormatCompressedPrime uint8 = 1
)

// TLS CertificateStatusType (RFC 3546)
const (
	statusTypeOCSP uint8 = 1
)

// Certificate types (for certificateRequestMsg)
const (
	CertTypeRSASign    = 1 // A certificate containing an RSA key
	CertTypeDSSSign    = 2 // A certificate containing a DSA key
	CertTypeRSAFixedDH = 3 // A certificate containing a static DH key
	CertTypeDSSFixedDH = 4 // A certificate containing a static DH key

	// See RFC4492 sections 3 and 5.5.
	CertTypeECDSASign      = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA.
	CertTypeRSAFixedECDH   = 65 // A certificate containing an ECDH-capable public key, signed with RSA.
	CertTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA.

	// Rest of these are reserved by the TLS spec
)

// signatureAlgorithm corresponds to a SignatureScheme value from TLS 1.3. Note
// that TLS 1.3 names the production 'SignatureScheme' to avoid colliding with
// TLS 1.2's SignatureAlgorithm but otherwise refers to them as 'signature
// algorithms' throughout. We match the latter.
type signatureAlgorithm uint16

const (
	// RSASSA-PKCS1-v1_5 algorithms
	signatureRSAPKCS1WithMD5    signatureAlgorithm = 0x0101
	signatureRSAPKCS1WithSHA1   signatureAlgorithm = 0x0201
	signatureRSAPKCS1WithSHA256 signatureAlgorithm = 0x0401
	signatureRSAPKCS1WithSHA384 signatureAlgorithm = 0x0501
	signatureRSAPKCS1WithSHA512 signatureAlgorithm = 0x0601

	// ECDSA algorithms
	signatureECDSAWithSHA1          signatureAlgorithm = 0x0203
	signatureECDSAWithP256AndSHA256 signatureAlgorithm = 0x0403
	signatureECDSAWithP384AndSHA384 signatureAlgorithm = 0x0503
	signatureECDSAWithP521AndSHA512 signatureAlgorithm = 0x0603

	// RSASSA-PSS algorithms
	signatureRSAPSSWithSHA256 signatureAlgorithm = 0x0804
	signatureRSAPSSWithSHA384 signatureAlgorithm = 0x0805
	signatureRSAPSSWithSHA512 signatureAlgorithm = 0x0806

	// EdDSA algorithms
	signatureEd25519 signatureAlgorithm = 0x0807
	signatureEd448   signatureAlgorithm = 0x0808
)

// supportedSignatureAlgorithms contains the default supported signature
// algorithms.
var supportedSignatureAlgorithms = []signatureAlgorithm{
	signatureRSAPSSWithSHA256,
	signatureRSAPKCS1WithSHA256,
	signatureECDSAWithP256AndSHA256,
	signatureRSAPKCS1WithSHA1,
	signatureECDSAWithSHA1,
	signatureEd25519,
}

// SRTP protection profiles (See RFC 5764, section 4.1.2)
const (
	SRTP_AES128_CM_HMAC_SHA1_80 uint16 = 0x0001
	SRTP_AES128_CM_HMAC_SHA1_32        = 0x0002
)

// PskKeyExchangeMode values (see draft-ietf-tls-tls13-16)
const (
	pskKEMode    = 0
	pskDHEKEMode = 1
)

// KeyUpdateRequest values (see draft-ietf-tls-tls13-16, section 4.5.3)
const (
	keyUpdateNotRequested = 0
	keyUpdateRequested    = 1
)

// ConnectionState records basic TLS details about the connection.
type ConnectionState struct {
	Version                    uint16                // TLS version used by the connection (e.g. VersionTLS12)
	HandshakeComplete          bool                  // TLS handshake is complete
	DidResume                  bool                  // connection resumes a previous TLS connection
	CipherSuite                uint16                // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
	NegotiatedProtocol         string                // negotiated next protocol (from Config.NextProtos)
	NegotiatedProtocolIsMutual bool                  // negotiated protocol was advertised by server
	NegotiatedProtocolFromALPN bool                  // protocol negotiated with ALPN
	ServerName                 string                // server name requested by client, if any (server side only)
	PeerCertificates           []*x509.Certificate   // certificate chain presented by remote peer
	VerifiedChains             [][]*x509.Certificate // verified chains built from PeerCertificates
	ChannelID                  *ecdsa.PublicKey      // the channel ID for this connection
	SRTPProtectionProfile      uint16                // the negotiated DTLS-SRTP protection profile
	TLSUnique                  []byte                // the tls-unique channel binding
	SCTList                    []byte                // signed certificate timestamp list
	PeerSignatureAlgorithm     signatureAlgorithm    // algorithm used by the peer in the handshake
	CurveID                    CurveID               // the curve used in ECDHE
}

// ClientAuthType declares the policy the server will follow for
// TLS Client Authentication.
type ClientAuthType int

const (
	NoClientCert ClientAuthType = iota
	RequestClientCert
	RequireAnyClientCert
	VerifyClientCertIfGiven
	RequireAndVerifyClientCert
)

// ClientSessionState contains the state needed by clients to resume TLS
// sessions.
type ClientSessionState struct {
	sessionId            []uint8             // Session ID supplied by the server. nil if the session has a ticket.
	sessionTicket        []uint8             // Encrypted ticket used for session resumption with server
	vers                 uint16              // SSL/TLS version negotiated for the session
	cipherSuite          uint16              // Ciphersuite negotiated for the session
	masterSecret         []byte              // MasterSecret generated by client on a full handshake
	handshakeHash        []byte              // Handshake hash for Channel ID purposes.
	serverCertificates   []*x509.Certificate // Certificate chain presented by the server
	extendedMasterSecret bool                // Whether an extended master secret was used to generate the session
	sctList              []byte
	ocspResponse         []byte
	earlyALPN            string
	ticketCreationTime   time.Time
	ticketExpiration     time.Time
	ticketAgeAdd         uint32
	maxEarlyDataSize     uint32
}

// ClientSessionCache is a cache of ClientSessionState objects that can be used
// by a client to resume a TLS session with a given server. ClientSessionCache
// implementations should expect to be called concurrently from different
// goroutines.
type ClientSessionCache interface {
	// Get searches for a ClientSessionState associated with the given key.
	// On return, ok is true if one was found.
	Get(sessionKey string) (session *ClientSessionState, ok bool)

	// Put adds the ClientSessionState to the cache with the given key.
	Put(sessionKey string, cs *ClientSessionState)
}

// ServerSessionCache is a cache of sessionState objects that can be used by a
// client to resume a TLS session with a given server. ServerSessionCache
// implementations should expect to be called concurrently from different
// goroutines.
type ServerSessionCache interface {
	// Get searches for a sessionState associated with the given session
	// ID. On return, ok is true if one was found.
	Get(sessionId string) (session *sessionState, ok bool)

	// Put adds the sessionState to the cache with the given session ID.
	Put(sessionId string, session *sessionState)
}

// A Config structure is used to configure a TLS client or server.
// After one has been passed to a TLS function it must not be
// modified. A Config may be reused; the tls package will also not
// modify it.
type Config struct {
	// Rand provides the source of entropy for nonces and RSA blinding.
	// If Rand is nil, TLS uses the cryptographic random reader in package
	// crypto/rand.
	// The Reader must be safe for use by multiple goroutines.
	Rand io.Reader

	// Time returns the current time as the number of seconds since the epoch.
	// If Time is nil, TLS uses time.Now.
	Time func() time.Time

	// Certificates contains one or more certificate chains
	// to present to the other side of the connection.
	// Server configurations must include at least one certificate.
	Certificates []Certificate

	// NameToCertificate maps from a certificate name to an element of
	// Certificates. Note that a certificate name can be of the form
	// '*.example.com' and so doesn't have to be a domain name as such.
	// See Config.BuildNameToCertificate
	// The nil value causes the first element of Certificates to be used
	// for all connections.
	NameToCertificate map[string]*Certificate

	// RootCAs defines the set of root certificate authorities
	// that clients use when verifying server certificates.
	// If RootCAs is nil, TLS uses the host's root CA set.
	RootCAs *x509.CertPool

	// NextProtos is a list of supported, application level protocols.
	NextProtos []string

	// ServerName is used to verify the hostname on the returned
	// certificates unless InsecureSkipVerify is given. It is also included
	// in the client's handshake to support virtual hosting.
	ServerName string

	// ClientAuth determines the server's policy for
	// TLS Client Authentication. The default is NoClientCert.
	ClientAuth ClientAuthType

	// ClientCAs defines the set of root certificate authorities
	// that servers use if required to verify a client certificate
	// by the policy in ClientAuth.
	ClientCAs *x509.CertPool

	// ClientCertificateTypes defines the set of allowed client certificate
	// types. The default is CertTypeRSASign and CertTypeECDSASign.
	ClientCertificateTypes []byte

	// InsecureSkipVerify controls whether a client verifies the
	// server's certificate chain and host name.
	// If InsecureSkipVerify is true, TLS accepts any certificate
	// presented by the server and any host name in that certificate.
	// In this mode, TLS is susceptible to man-in-the-middle attacks.
	// This should be used only for testing.
	InsecureSkipVerify bool

	// CipherSuites is a list of supported cipher suites. If CipherSuites
	// is nil, TLS uses a list of suites supported by the implementation.
	CipherSuites []uint16

	// PreferServerCipherSuites controls whether the server selects the
	// client's most preferred ciphersuite, or the server's most preferred
	// ciphersuite. If true then the server's preference, as expressed in
	// the order of elements in CipherSuites, is used.
	PreferServerCipherSuites bool

	// SessionTicketsDisabled may be set to true to disable session ticket
	// (resumption) support.
	SessionTicketsDisabled bool

	// SessionTicketKey is used by TLS servers to provide session
	// resumption. See RFC 5077. If zero, it will be filled with
	// random data before the first server handshake.
	//
	// If multiple servers are terminating connections for the same host
	// they should all have the same SessionTicketKey. If the
	// SessionTicketKey leaks, previously recorded and future TLS
	// connections using that key are compromised.
	SessionTicketKey [32]byte

	// ClientSessionCache is a cache of ClientSessionState entries
	// for TLS session resumption.
	ClientSessionCache ClientSessionCache

	// ServerSessionCache is a cache of sessionState entries for TLS session
	// resumption.
	ServerSessionCache ServerSessionCache

	// MinVersion contains the minimum SSL/TLS version that is acceptable.
	// If zero, then SSLv3 is taken as the minimum.
	MinVersion uint16

	// MaxVersion contains the maximum SSL/TLS version that is acceptable.
	// If zero, then the maximum version supported by this package is used,
	// which is currently TLS 1.2.
	MaxVersion uint16

	// TLS13Variant is the variant of TLS 1.3 to use.
	TLS13Variant int

	// CurvePreferences contains the elliptic curves that will be used in
	// an ECDHE handshake, in preference order. If empty, the default will
	// be used.
	CurvePreferences []CurveID

	// DefaultCurves contains the elliptic curves for which public values will
	// be sent in the ClientHello's KeyShare extension. If this value is nil,
	// all supported curves will have public values sent. This field is ignored
	// on servers.
	DefaultCurves []CurveID

	// ChannelID contains the ECDSA key for the client to use as
	// its TLS Channel ID.
	ChannelID *ecdsa.PrivateKey

	// RequestChannelID controls whether the server requests a TLS
	// Channel ID. If negotiated, the client's public key is
	// returned in the ConnectionState.
	RequestChannelID bool

	// PreSharedKey, if not nil, is the pre-shared key to use with
	// the PSK cipher suites.
	PreSharedKey []byte

	// PreSharedKeyIdentity, if not empty, is the identity to use
	// with the PSK cipher suites.
	PreSharedKeyIdentity string

	// MaxEarlyDataSize controls the maximum number of bytes that the
	// server will accept in early data and advertise in a
	// NewSessionTicketMsg. If 0, no early data will be accepted and
	// the TicketEarlyDataInfo extension in the NewSessionTicketMsg
	// will be omitted.
	MaxEarlyDataSize uint32

	// SRTPProtectionProfiles, if not nil, is the list of SRTP
	// protection profiles to offer in DTLS-SRTP.
	SRTPProtectionProfiles []uint16

	// SignSignatureAlgorithms, if not nil, overrides the default set of
	// supported signature algorithms to sign with.
	SignSignatureAlgorithms []signatureAlgorithm

	// VerifySignatureAlgorithms, if not nil, overrides the default set of
	// supported signature algorithms that are accepted.
	VerifySignatureAlgorithms []signatureAlgorithm

	// Bugs specifies optional misbehaviour to be used for testing other
	// implementations.
	Bugs ProtocolBugs

	serverInitOnce sync.Once // guards calling (*Config).serverInit
}

type BadValue int

const (
	BadValueNone BadValue = iota
	BadValueNegative
	BadValueZero
	BadValueLimit
	BadValueLarge
	NumBadValues
)

type RSABadValue int

const (
	RSABadValueNone RSABadValue = iota
	RSABadValueCorrupt
	RSABadValueTooLong
	RSABadValueTooShort
	RSABadValueWrongVersion
	NumRSABadValues
)

type ProtocolBugs struct {
	// InvalidSignature specifies that the signature in a ServerKeyExchange
	// or CertificateVerify message should be invalid.
	InvalidSignature bool

	// SendCurve, if non-zero, causes the server to send the specified curve
	// ID in ServerKeyExchange (TLS 1.2) or ServerHello (TLS 1.3) rather
	// than the negotiated one.
	SendCurve CurveID

	// InvalidECDHPoint, if true, causes the ECC points in
	// ServerKeyExchange or ClientKeyExchange messages to be invalid.
	InvalidECDHPoint bool

	// BadECDSAR controls ways in which the 'r' value of an ECDSA signature
	// can be invalid.
	BadECDSAR BadValue
	BadECDSAS BadValue

	// MaxPadding causes CBC records to have the maximum possible padding.
	MaxPadding bool
	// PaddingFirstByteBad causes the first byte of the padding to be
	// incorrect.
	PaddingFirstByteBad bool
	// PaddingFirstByteBadIf255 causes the first byte of padding to be
	// incorrect if there's a maximum amount of padding (i.e. 255 bytes).
	PaddingFirstByteBadIf255 bool

	// FailIfNotFallbackSCSV causes a server handshake to fail if the
	// client doesn't send the fallback SCSV value.
	FailIfNotFallbackSCSV bool

	// DuplicateExtension causes an extra empty extension of bogus type to
	// be emitted in either the ClientHello or the ServerHello.
	DuplicateExtension bool

	// UnauthenticatedECDH causes the server to pretend ECDHE_RSA
	// and ECDHE_ECDSA cipher suites are actually ECDH_anon. No
	// Certificate message is sent and no signature is added to
	// ServerKeyExchange.
	UnauthenticatedECDH bool

	// SkipHelloVerifyRequest causes a DTLS server to skip the
	// HelloVerifyRequest message.
	SkipHelloVerifyRequest bool

	// SkipCertificateStatus, if true, causes the server to skip the
	// CertificateStatus message. This is legal because CertificateStatus is
	// optional, even with a status_request in ServerHello.
	SkipCertificateStatus bool

	// SkipServerKeyExchange causes the server to skip sending
	// ServerKeyExchange messages.
	SkipServerKeyExchange bool

	// SkipNewSessionTicket causes the server to skip sending the
	// NewSessionTicket message despite promising to in ServerHello.
	SkipNewSessionTicket bool

	// SkipClientCertificate causes the client to skip the Certificate
	// message.
	SkipClientCertificate bool

	// SkipChangeCipherSpec causes the implementation to skip
	// sending the ChangeCipherSpec message (and adjusting cipher
	// state accordingly for the Finished message).
	SkipChangeCipherSpec bool

	// SkipFinished causes the implementation to skip sending the Finished
	// message.
	SkipFinished bool

	// SkipEndOfEarlyData causes the implementation to skip the
	// end_of_early_data alert.
	SkipEndOfEarlyData bool

	// EarlyChangeCipherSpec causes the client to send an early
	// ChangeCipherSpec message before the ClientKeyExchange. A value of
	// zero disables this behavior. One and two configure variants for 0.9.8
	// and 1.0.1 modes, respectively.
	EarlyChangeCipherSpec int

	// StrayChangeCipherSpec causes every pre-ChangeCipherSpec handshake
	// message in DTLS to be prefaced by stray ChangeCipherSpec record. This
	// may be used to test DTLS's handling of reordered ChangeCipherSpec.
	StrayChangeCipherSpec bool

	// FragmentAcrossChangeCipherSpec causes the implementation to fragment
	// the Finished (or NextProto) message around the ChangeCipherSpec
	// messages.
	FragmentAcrossChangeCipherSpec bool

	// SendUnencryptedFinished, if true, causes the Finished message to be
	// send unencrypted before ChangeCipherSpec rather than after it.
	SendUnencryptedFinished bool

	// PartialEncryptedExtensionsWithServerHello, if true, causes the TLS
	// 1.3 server to send part of EncryptedExtensions unencrypted
	// in the same record as ServerHello.
	PartialEncryptedExtensionsWithServerHello bool

	// PartialClientFinishedWithClientHello, if true, causes the TLS 1.3
	// client to send part of Finished unencrypted in the same record as
	// ClientHello.
	PartialClientFinishedWithClientHello bool

	// SendV2ClientHello causes the client to send a V2ClientHello
	// instead of a normal ClientHello.
	SendV2ClientHello bool

	// SendFallbackSCSV causes the client to include
	// TLS_FALLBACK_SCSV in the ClientHello.
	SendFallbackSCSV bool

	// SendRenegotiationSCSV causes the client to include the renegotiation
	// SCSV in the ClientHello.
	SendRenegotiationSCSV bool

	// MaxHandshakeRecordLength, if non-zero, is the maximum size of a
	// handshake record. Handshake messages will be split into multiple
	// records at the specified size, except that the client_version will
	// never be fragmented. For DTLS, it is the maximum handshake fragment
	// size, not record size; DTLS allows multiple handshake fragments in a
	// single handshake record. See |PackHandshakeFragments|.
	MaxHandshakeRecordLength int

	// FragmentClientVersion will allow MaxHandshakeRecordLength to apply to
	// the first 6 bytes of the ClientHello.
	FragmentClientVersion bool

	// FragmentAlert will cause all alerts to be fragmented across
	// two records.
	FragmentAlert bool

	// DoubleAlert will cause all alerts to be sent as two copies packed
	// within one record.
	DoubleAlert bool

	// SendSpuriousAlert, if non-zero, will cause an spurious, unwanted
	// alert to be sent.
	SendSpuriousAlert alert

	// BadRSAClientKeyExchange causes the client to send a corrupted RSA
	// ClientKeyExchange which would not pass padding checks.
	BadRSAClientKeyExchange RSABadValue

	// RenewTicketOnResume causes the server to renew the session ticket and
	// send a NewSessionTicket message during an abbreviated handshake.
	RenewTicketOnResume bool

	// SendClientVersion, if non-zero, causes the client to send the
	// specified value in the ClientHello version field.
	SendClientVersion uint16

	// OmitSupportedVersions, if true, causes the client to omit the
	// supported versions extension.
	OmitSupportedVersions bool

	// SendSupportedVersions, if non-empty, causes the client to send a
	// supported versions extension with the values from array.
	SendSupportedVersions []uint16

	// NegotiateVersion, if non-zero, causes the server to negotiate the
	// specifed wire version rather than the version supported by either
	// peer.
	NegotiateVersion uint16

	// NegotiateVersionOnRenego, if non-zero, causes the server to negotiate
	// the specified wire version on renegotiation rather than retaining it.
	NegotiateVersionOnRenego uint16

	// ExpectFalseStart causes the server to, on full handshakes,
	// expect the peer to False Start; the server Finished message
	// isn't sent until we receive an application data record
	// from the peer.
	ExpectFalseStart bool

	// AlertBeforeFalseStartTest, if non-zero, causes the server to, on full
	// handshakes, send an alert just before reading the application data
	// record to test False Start. This can be used in a negative False
	// Start test to determine whether the peer processed the alert (and
	// closed the connection) before or after sending app data.
	AlertBeforeFalseStartTest alert

	// ExpectServerName, if not empty, is the hostname the client
	// must specify in the server_name extension.
	ExpectServerName string

	// SwapNPNAndALPN switches the relative order between NPN and ALPN in
	// both ClientHello and ServerHello.
	SwapNPNAndALPN bool

	// ALPNProtocol, if not nil, sets the ALPN protocol that a server will
	// return.
	ALPNProtocol *string

	// AcceptAnySession causes the server to resume sessions regardless of
	// the version associated with the session or cipher suite. It also
	// causes the server to look in both TLS 1.2 and 1.3 extensions to
	// process a ticket.
	AcceptAnySession bool

	// SendBothTickets, if true, causes the client to send tickets in both
	// TLS 1.2 and 1.3 extensions.
	SendBothTickets bool

	// FilterTicket, if not nil, causes the client to modify a session
	// ticket before sending it in a resume handshake.
	FilterTicket func([]byte) ([]byte, error)

	// TicketSessionIDLength, if non-zero, is the length of the session ID
	// to send with a ticket resumption offer.
	TicketSessionIDLength int

	// EmptyTicketSessionID, if true, causes the client to send an empty
	// session ID with a ticket resumption offer. For simplicity, this will
	// also cause the client to interpret a ServerHello with empty session
	// ID as a resumption. (A client which sends empty session ID is
	// normally expected to look ahead for ChangeCipherSpec.)
	EmptyTicketSessionID bool

	// ExpectNoTLS12Session, if true, causes the server to fail the
	// connection if either a session ID or TLS 1.2 ticket is offered.
	ExpectNoTLS12Session bool

	// ExpectNoTLS13PSK, if true, causes the server to fail the connection
	// if a TLS 1.3 PSK is offered.
	ExpectNoTLS13PSK bool

	// RequireExtendedMasterSecret, if true, requires that the peer support
	// the extended master secret option.
	RequireExtendedMasterSecret bool

	// NoExtendedMasterSecret causes the client and server to behave as if
	// they didn't support an extended master secret in the initial
	// handshake.
	NoExtendedMasterSecret bool

	// NoExtendedMasterSecretOnRenegotiation causes the client and server to
	// behave as if they didn't support an extended master secret in
	// renegotiation handshakes.
	NoExtendedMasterSecretOnRenegotiation bool

	// EmptyRenegotiationInfo causes the renegotiation extension to be
	// empty in a renegotiation handshake.
	EmptyRenegotiationInfo bool

	// BadRenegotiationInfo causes the renegotiation extension value in a
	// renegotiation handshake to be incorrect at the start.
	BadRenegotiationInfo bool

	// BadRenegotiationInfoEnd causes the renegotiation extension value in
	// a renegotiation handshake to be incorrect at the end.
	BadRenegotiationInfoEnd bool

	// NoRenegotiationInfo disables renegotiation info support in all
	// handshakes.
	NoRenegotiationInfo bool

	// NoRenegotiationInfoInInitial disables renegotiation info support in
	// the initial handshake.
	NoRenegotiationInfoInInitial bool

	// NoRenegotiationInfoAfterInitial disables renegotiation info support
	// in renegotiation handshakes.
	NoRenegotiationInfoAfterInitial bool

	// RequireRenegotiationInfo, if true, causes the client to return an
	// error if the server doesn't reply with the renegotiation extension.
	RequireRenegotiationInfo bool

	// SequenceNumberMapping, if non-nil, is the mapping function to apply
	// to the sequence number of outgoing packets. For both TLS and DTLS,
	// the two most-significant bytes in the resulting sequence number are
	// ignored so that the DTLS epoch cannot be changed.
	SequenceNumberMapping func(uint64) uint64

	// RSAEphemeralKey, if true, causes the server to send a
	// ServerKeyExchange message containing an ephemeral key (as in
	// RSA_EXPORT) in the plain RSA key exchange.
	RSAEphemeralKey bool

	// SRTPMasterKeyIdentifer, if not empty, is the SRTP MKI value that the
	// client offers when negotiating SRTP. MKI support is still missing so
	// the peer must still send none.
	SRTPMasterKeyIdentifer string

	// SendSRTPProtectionProfile, if non-zero, is the SRTP profile that the
	// server sends in the ServerHello instead of the negotiated one.
	SendSRTPProtectionProfile uint16

	// NoSignatureAlgorithms, if true, causes the client to omit the
	// signature and hashes extension.
	//
	// For a server, it will cause an empty list to be sent in the
	// CertificateRequest message. None the less, the configured set will
	// still be enforced.
	NoSignatureAlgorithms bool

	// NoSupportedCurves, if true, causes the client to omit the
	// supported_curves extension.
	NoSupportedCurves bool

	// RequireSameRenegoClientVersion, if true, causes the server
	// to require that all ClientHellos match in offered version
	// across a renego.
	RequireSameRenegoClientVersion bool

	// ExpectInitialRecordVersion, if non-zero, is the expected value of
	// record-layer version field before the protocol version is determined.
	ExpectInitialRecordVersion uint16

	// SendRecordVersion, if non-zero, is the value to send as the
	// record-layer version.
	SendRecordVersion uint16

	// SendInitialRecordVersion, if non-zero, is the value to send as the
	// record-layer version before the protocol version is determined.
	SendInitialRecordVersion uint16

	// MaxPacketLength, if non-zero, is the maximum acceptable size for a
	// packet.
	MaxPacketLength int

	// SendCipherSuite, if non-zero, is the cipher suite value that the
	// server will send in the ServerHello. This does not affect the cipher
	// the server believes it has actually negotiated.
	SendCipherSuite uint16

	// SendCipherSuites, if not nil, is the cipher suite list that the
	// client will send in the ClientHello. This does not affect the cipher
	// the client believes it has actually offered.
	SendCipherSuites []uint16

	// AppDataBeforeHandshake, if not nil, causes application data to be
	// sent immediately before the first handshake message.
	AppDataBeforeHandshake []byte

	// AppDataAfterChangeCipherSpec, if not nil, causes application data to
	// be sent immediately after ChangeCipherSpec.
	AppDataAfterChangeCipherSpec []byte

	// AlertAfterChangeCipherSpec, if non-zero, causes an alert to be sent
	// immediately after ChangeCipherSpec.
	AlertAfterChangeCipherSpec alert

	// TimeoutSchedule is the schedule of packet drops and simulated
	// timeouts for before each handshake leg from the peer.
	TimeoutSchedule []time.Duration

	// PacketAdaptor is the packetAdaptor to use to simulate timeouts.
	PacketAdaptor *packetAdaptor

	// ReorderHandshakeFragments, if true, causes handshake fragments in
	// DTLS to overlap and be sent in the wrong order. It also causes
	// pre-CCS flights to be sent twice. (Post-CCS flights consist of
	// Finished and will trigger a spurious retransmit.)
	ReorderHandshakeFragments bool

	// ReverseHandshakeFragments, if true, causes handshake fragments in
	// DTLS to be reversed within a flight.
	ReverseHandshakeFragments bool

	// MixCompleteMessageWithFragments, if true, causes handshake
	// messages in DTLS to redundantly both fragment the message
	// and include a copy of the full one.
	MixCompleteMessageWithFragments bool

	// SendInvalidRecordType, if true, causes a record with an invalid
	// content type to be sent immediately following the handshake.
	SendInvalidRecordType bool

	// SendWrongMessageType, if non-zero, causes messages of the specified
	// type to be sent with the wrong value.
	SendWrongMessageType byte

	// SendTrailingMessageData, if non-zero, causes messages of the
	// specified type to be sent with trailing data.
	SendTrailingMessageData byte

	// FragmentMessageTypeMismatch, if true, causes all non-initial
	// handshake fragments in DTLS to have the wrong message type.
	FragmentMessageTypeMismatch bool

	// FragmentMessageLengthMismatch, if true, causes all non-initial
	// handshake fragments in DTLS to have the wrong message length.
	FragmentMessageLengthMismatch bool

	// SplitFragments, if non-zero, causes the handshake fragments in DTLS
	// to be split across two records. The value of |SplitFragments| is the
	// number of bytes in the first fragment.
	SplitFragments int

	// SendEmptyFragments, if true, causes handshakes to include empty
	// fragments in DTLS.
	SendEmptyFragments bool

	// SendSplitAlert, if true, causes an alert to be sent with the header
	// and record body split across multiple packets. The peer should
	// discard these packets rather than process it.
	SendSplitAlert bool

	// FailIfResumeOnRenego, if true, causes renegotiations to fail if the
	// client offers a resumption or the server accepts one.
	FailIfResumeOnRenego bool

	// IgnorePeerCipherPreferences, if true, causes the peer's cipher
	// preferences to be ignored.
	IgnorePeerCipherPreferences bool

	// IgnorePeerSignatureAlgorithmPreferences, if true, causes the peer's
	// signature algorithm preferences to be ignored.
	IgnorePeerSignatureAlgorithmPreferences bool

	// IgnorePeerCurvePreferences, if true, causes the peer's curve
	// preferences to be ignored.
	IgnorePeerCurvePreferences bool

	// BadFinished, if true, causes the Finished hash to be broken.
	BadFinished bool

	// PackHandshakeFragments, if true, causes handshake fragments in DTLS
	// to be packed into individual handshake records, up to the specified
	// record size.
	PackHandshakeFragments int

	// PackHandshakeRecords, if true, causes handshake records in DTLS to be
	// packed into individual packets, up to the specified packet size.
	PackHandshakeRecords int

	// PackHandshakeFlight, if true, causes each handshake flight in TLS to
	// be packed into records, up to the largest size record available.
	PackHandshakeFlight bool

	// AdvertiseAllConfiguredCiphers, if true, causes the client to
	// advertise all configured cipher suite values.
	AdvertiseAllConfiguredCiphers bool

	// EmptyCertificateList, if true, causes the server to send an empty
	// certificate list in the Certificate message.
	EmptyCertificateList bool

	// ExpectNewTicket, if true, causes the client to abort if it does not
	// receive a new ticket.
	ExpectNewTicket bool

	// RequireClientHelloSize, if not zero, is the required length in bytes
	// of the ClientHello /record/. This is checked by the server.
	RequireClientHelloSize int

	// CustomExtension, if not empty, contains the contents of an extension
	// that will be added to client/server hellos.
	CustomExtension string

	// CustomUnencryptedExtension, if not empty, contains the contents of
	// an extension that will be added to ServerHello in TLS 1.3.
	CustomUnencryptedExtension string

	// ExpectedCustomExtension, if not nil, contains the expected contents
	// of a custom extension.
	ExpectedCustomExtension *string

	// CustomTicketExtension, if not empty, contains the contents of an
	// extension what will be added to NewSessionTicket in TLS 1.3.
	CustomTicketExtension string

	// CustomTicketExtension, if not empty, contains the contents of an
	// extension what will be added to HelloRetryRequest in TLS 1.3.
	CustomHelloRetryRequestExtension string

	// NoCloseNotify, if true, causes the close_notify alert to be skipped
	// on connection shutdown.
	NoCloseNotify bool

	// SendAlertOnShutdown, if non-zero, is the alert to send instead of
	// close_notify on shutdown.
	SendAlertOnShutdown alert

	// ExpectCloseNotify, if true, requires a close_notify from the peer on
	// shutdown. Records from the peer received after close_notify is sent
	// are not discard.
	ExpectCloseNotify bool

	// SendLargeRecords, if true, allows outgoing records to be sent
	// arbitrarily large.
	SendLargeRecords bool

	// NegotiateALPNAndNPN, if true, causes the server to negotiate both
	// ALPN and NPN in the same connetion.
	NegotiateALPNAndNPN bool

	// SendALPN, if non-empty, causes the server to send the specified
	// string in the ALPN extension regardless of the content or presence of
	// the client offer.
	SendALPN string

	// SendUnencryptedALPN, if non-empty, causes the server to send the
	// specified string in a ServerHello ALPN extension in TLS 1.3.
	SendUnencryptedALPN string

	// SendEmptySessionTicket, if true, causes the server to send an empty
	// session ticket.
	SendEmptySessionTicket bool

	// SendPSKKeyExchangeModes, if present, determines the PSK key exchange modes
	// to send.
	SendPSKKeyExchangeModes []byte

	// ExpectNoNewSessionTicket, if present, means that the client will fail upon
	// receipt of a NewSessionTicket message.
	ExpectNoNewSessionTicket bool

	// DuplicateTicketEarlyDataInfo causes an extra empty extension of
	// ticket_early_data_info to be sent in NewSessionTicket.
	DuplicateTicketEarlyDataInfo bool

	// ExpectTicketEarlyDataInfo, if true, means that the client will fail upon
	// absence of the ticket_early_data_info extension.
	ExpectTicketEarlyDataInfo bool

	// ExpectTicketAge, if non-zero, is the expected age of the ticket that the
	// server receives from the client.
	ExpectTicketAge time.Duration

	// SendTicketAge, if non-zero, is the ticket age to be sent by the
	// client.
	SendTicketAge time.Duration

	// FailIfSessionOffered, if true, causes the server to fail any
	// connections where the client offers a non-empty session ID or session
	// ticket.
	FailIfSessionOffered bool

	// SendHelloRequestBeforeEveryAppDataRecord, if true, causes a
	// HelloRequest handshake message to be sent before each application
	// data record. This only makes sense for a server.
	SendHelloRequestBeforeEveryAppDataRecord bool

	// SendHelloRequestBeforeEveryHandshakeMessage, if true, causes a
	// HelloRequest handshake message to be sent before each handshake
	// message. This only makes sense for a server.
	SendHelloRequestBeforeEveryHandshakeMessage bool

	// BadChangeCipherSpec, if not nil, is the body to be sent in
	// ChangeCipherSpec records instead of {1}.
	BadChangeCipherSpec []byte

	// BadHelloRequest, if not nil, is what to send instead of a
	// HelloRequest.
	BadHelloRequest []byte

	// RequireSessionTickets, if true, causes the client to require new
	// sessions use session tickets instead of session IDs.
	RequireSessionTickets bool

	// NullAllCiphers, if true, causes every cipher to behave like the null
	// cipher.
	NullAllCiphers bool

	// SendSCTListOnResume, if not nil, causes the server to send the
	// supplied SCT list in resumption handshakes.
	SendSCTListOnResume []byte

	// SendOCSPResponseOnResume, if not nil, causes the server to advertise
	// OCSP stapling in resumption handshakes and, if applicable, send the
	// supplied stapled response.
	SendOCSPResponseOnResume []byte

	// SendExtensionOnCertificate, if not nil, causes the runner to send the
	// supplied bytes in the extensions on the Certificate message.
	SendExtensionOnCertificate []byte

	// SendOCSPOnIntermediates, if not nil, causes the server to send the
	// supplied OCSP on intermediate certificates in the Certificate message.
	SendOCSPOnIntermediates []byte

	// SendSCTOnIntermediates, if not nil, causes the server to send the
	// supplied SCT on intermediate certificates in the Certificate message.
	SendSCTOnIntermediates []byte

	// SendDuplicateCertExtensions, if true, causes the server to send an extra
	// copy of the OCSP/SCT extensions in the Certificate message.
	SendDuplicateCertExtensions bool

	// ExpectNoExtensionsOnIntermediate, if true, causes the client to
	// reject extensions on intermediate certificates.
	ExpectNoExtensionsOnIntermediate bool

	// RecordPadding is the number of bytes of padding to add to each
	// encrypted record in TLS 1.3.
	RecordPadding int

	// OmitRecordContents, if true, causes encrypted records in TLS 1.3 to
	// be missing their body and content type. Padding, if configured, is
	// still added.
	OmitRecordContents bool

	// OuterRecordType, if non-zero, is the outer record type to use instead
	// of application data.
	OuterRecordType recordType

	// SendSignatureAlgorithm, if non-zero, causes all signatures to be sent
	// with the given signature algorithm rather than the one negotiated.
	SendSignatureAlgorithm signatureAlgorithm

	// SkipECDSACurveCheck, if true, causes all ECDSA curve checks to be
	// skipped.
	SkipECDSACurveCheck bool

	// IgnoreSignatureVersionChecks, if true, causes all signature
	// algorithms to be enabled at all TLS versions.
	IgnoreSignatureVersionChecks bool

	// NegotiateRenegotiationInfoAtAllVersions, if true, causes
	// Renegotiation Info to be negotiated at all versions.
	NegotiateRenegotiationInfoAtAllVersions bool

	// NegotiateNPNAtAllVersions, if true, causes NPN to be negotiated at
	// all versions.
	NegotiateNPNAtAllVersions bool

	// NegotiateEMSAtAllVersions, if true, causes EMS to be negotiated at
	// all versions.
	NegotiateEMSAtAllVersions bool

	// AdvertiseTicketExtension, if true, causes the ticket extension to be
	// advertised in server extensions
	AdvertiseTicketExtension bool

	// NegotiatePSKResumption, if true, causes the server to attempt pure PSK
	// resumption.
	NegotiatePSKResumption bool

	// AlwaysSelectPSKIdentity, if true, causes the server in TLS 1.3 to
	// always acknowledge a session, regardless of one was offered.
	AlwaysSelectPSKIdentity bool

	// SelectPSKIdentityOnResume, if non-zero, causes the server to select
	// the specified PSK identity index rather than the actual value.
	SelectPSKIdentityOnResume uint16

	// ExtraPSKIdentity, if true, causes the client to send an extra PSK
	// identity.
	ExtraPSKIdentity bool

	// MissingKeyShare, if true, causes the TLS 1.3 implementation to skip
	// sending a key_share extension and use the zero ECDHE secret
	// instead.
	MissingKeyShare bool

	// SecondClientHelloMissingKeyShare, if true, causes the second TLS 1.3
	// ClientHello to skip sending a key_share extension and use the zero
	// ECDHE secret instead.
	SecondClientHelloMissingKeyShare bool

	// MisinterpretHelloRetryRequestCurve, if non-zero, causes the TLS 1.3
	// client to pretend the server requested a HelloRetryRequest with the
	// given curve rather than the actual one.
	MisinterpretHelloRetryRequestCurve CurveID

	// DuplicateKeyShares, if true, causes the TLS 1.3 client to send two
	// copies of each KeyShareEntry.
	DuplicateKeyShares bool

	// SendEarlyAlert, if true, sends a fatal alert after the ClientHello.
	SendEarlyAlert bool

	// SendFakeEarlyDataLength, if non-zero, is the amount of early data to
	// send after the ClientHello.
	SendFakeEarlyDataLength int

	// SendStrayEarlyHandshake, if non-zero, causes the client to send a stray
	// handshake record before sending end of early data.
	SendStrayEarlyHandshake bool

	// OmitEarlyDataExtension, if true, causes the early data extension to
	// be omitted in the ClientHello.
	OmitEarlyDataExtension bool

	// SendEarlyDataOnSecondClientHello, if true, causes the TLS 1.3 client to
	// send early data after the second ClientHello.
	SendEarlyDataOnSecondClientHello bool

	// InterleaveEarlyData, if true, causes the TLS 1.3 client to send early
	// data interleaved with the second ClientHello and the client Finished.
	InterleaveEarlyData bool

	// SendEarlyData causes a TLS 1.3 client to send the provided data
	// in application data records immediately after the ClientHello,
	// provided that the client offers a TLS 1.3 session. It will do this
	// whether or not the server advertised early data for the ticket.
	SendEarlyData [][]byte

	// ExpectEarlyDataAccepted causes a TLS 1.3 client to check that early data
	// was accepted by the server.
	ExpectEarlyDataAccepted bool

	// AlwaysAcceptEarlyData causes a TLS 1.3 server to always accept early data
	// regardless of ALPN mismatch.
	AlwaysAcceptEarlyData bool

	// AlwaysRejectEarlyData causes a TLS 1.3 server to always reject early data.
	AlwaysRejectEarlyData bool

	// SendEarlyDataExtension, if true, causes a TLS 1.3 server to send the
	// early_data extension in EncryptedExtensions, independent of whether
	// it was accepted.
	SendEarlyDataExtension bool

	// ExpectEarlyData causes a TLS 1.3 server to read application
	// data after the ClientHello (assuming the server is able to
	// derive the key under which the data is encrypted) before it
	// sends a ServerHello. It checks that the application data it
	// reads matches what is provided in ExpectEarlyData and errors if
	// the number of records or their content do not match.
	ExpectEarlyData [][]byte

	// ExpectLateEarlyData causes a TLS 1.3 server to read application
	// data after the ServerFinished (assuming the server is able to
	// derive the key under which the data is encrypted) before it
	// sends the ClientFinished. It checks that the application data it
	// reads matches what is provided in ExpectLateEarlyData and errors if
	// the number of records or their content do not match.
	ExpectLateEarlyData [][]byte

	// SendHalfRTTData causes a TLS 1.3 server to send the provided
	// data in application data records before reading the client's
	// Finished message.
	SendHalfRTTData [][]byte

	// ExpectHalfRTTData causes a TLS 1.3 client, if 0-RTT was accepted, to
	// read application data after reading the server's Finished message and
	// before sending any subsequent handshake messages. It checks that the
	// application data it reads matches what is provided in
	// ExpectHalfRTTData and errors if the number of records or their
	// content do not match.
	ExpectHalfRTTData [][]byte

	// EmptyEncryptedExtensions, if true, causes the TLS 1.3 server to
	// emit an empty EncryptedExtensions block.
	EmptyEncryptedExtensions bool

	// EncryptedExtensionsWithKeyShare, if true, causes the TLS 1.3 server to
	// include the KeyShare extension in the EncryptedExtensions block.
	EncryptedExtensionsWithKeyShare bool

	// AlwaysSendHelloRetryRequest, if true, causes a HelloRetryRequest to
	// be sent by the server, even if empty.
	AlwaysSendHelloRetryRequest bool

	// SecondHelloRetryRequest, if true, causes the TLS 1.3 server to send
	// two HelloRetryRequests instead of one.
	SecondHelloRetryRequest bool

	// SendHelloRetryRequestCurve, if non-zero, causes the server to send
	// the specified curve in a HelloRetryRequest.
	SendHelloRetryRequestCurve CurveID

	// SendHelloRetryRequestCookie, if not nil, contains a cookie to be
	// sent by the server in HelloRetryRequest.
	SendHelloRetryRequestCookie []byte

	// DuplicateHelloRetryRequestExtensions, if true, causes all
	// HelloRetryRequest extensions to be sent twice.
	DuplicateHelloRetryRequestExtensions bool

	// SendServerHelloVersion, if non-zero, causes the server to send the
	// specified value in ServerHello version field.
	SendServerHelloVersion uint16

	// SendServerSupportedExtensionVersion, if non-zero, causes the server to send
	// the specified value in supported_versions extension in the ServerHello.
	SendServerSupportedExtensionVersion uint16

	// SkipHelloRetryRequest, if true, causes the TLS 1.3 server to not send
	// HelloRetryRequest.
	SkipHelloRetryRequest bool

	// PackHelloRequestWithFinished, if true, causes the TLS server to send
	// HelloRequest in the same record as Finished.
	PackHelloRequestWithFinished bool

	// ExpectMissingKeyShare, if true, causes the TLS server to fail the
	// connection if the selected curve appears in the client's initial
	// ClientHello. That is, it requires that a HelloRetryRequest be sent.
	ExpectMissingKeyShare bool

	// SendExtraFinished, if true, causes an extra Finished message to be
	// sent.
	SendExtraFinished bool

	// SendRequestContext, if not empty, is the request context to send in
	// a TLS 1.3 CertificateRequest.
	SendRequestContext []byte

	// SendSNIWarningAlert, if true, causes the server to send an
	// unrecognized_name alert before the ServerHello.
	SendSNIWarningAlert bool

	// SendCompressionMethods, if not nil, is the compression method list to
	// send in the ClientHello.
	SendCompressionMethods []byte

	// SendCompressionMethod is the compression method to send in the
	// ServerHello.
	SendCompressionMethod byte

	// AlwaysSendPreSharedKeyIdentityHint, if true, causes the server to
	// always send a ServerKeyExchange for PSK ciphers, even if the identity
	// hint is empty.
	AlwaysSendPreSharedKeyIdentityHint bool

	// TrailingKeyShareData, if true, causes the client key share list to
	// include a trailing byte.
	TrailingKeyShareData bool

	// InvalidChannelIDSignature, if true, causes the client to generate an
	// invalid Channel ID signature.
	InvalidChannelIDSignature bool

	// ExpectGREASE, if true, causes messages without GREASE values to be
	// rejected. See draft-davidben-tls-grease-01.
	ExpectGREASE bool

	// SendShortPSKBinder, if true, causes the client to send a PSK binder
	// that is one byte shorter than it should be.
	SendShortPSKBinder bool

	// SendInvalidPSKBinder, if true, causes the client to send an invalid
	// PSK binder.
	SendInvalidPSKBinder bool

	// SendNoPSKBinder, if true, causes the client to send no PSK binders.
	SendNoPSKBinder bool

	// SendExtraPSKBinder, if true, causes the client to send an extra PSK
	// binder.
	SendExtraPSKBinder bool

	// PSKBinderFirst, if true, causes the client to send the PSK Binder
	// extension as the first extension instead of the last extension.
	PSKBinderFirst bool

	// NoOCSPStapling, if true, causes the client to not request OCSP
	// stapling.
	NoOCSPStapling bool

	// NoSignedCertificateTimestamps, if true, causes the client to not
	// request signed certificate timestamps.
	NoSignedCertificateTimestamps bool

	// SendSupportedPointFormats, if not nil, is the list of supported point
	// formats to send in ClientHello or ServerHello. If set to a non-nil
	// empty slice, no extension will be sent.
	SendSupportedPointFormats []byte

	// MaxReceivePlaintext, if non-zero, is the maximum plaintext record
	// length accepted from the peer.
	MaxReceivePlaintext int

	// SendTicketLifetime, if non-zero, is the ticket lifetime to send in
	// NewSessionTicket messages.
	SendTicketLifetime time.Duration

	// SendServerNameAck, if true, causes the server to acknowledge the SNI
	// extension.
	SendServerNameAck bool

	// ExpectCertificateReqNames, if not nil, contains the list of X.509
	// names that must be sent in a CertificateRequest from the server.
	ExpectCertificateReqNames [][]byte

	// RenegotiationCertificate, if not nil, is the certificate to use on
	// renegotiation handshakes.
	RenegotiationCertificate *Certificate

	// UseLegacySigningAlgorithm, if non-zero, is the signature algorithm
	// to use when signing in TLS 1.1 and earlier where algorithms are not
	// negotiated.
	UseLegacySigningAlgorithm signatureAlgorithm

	// SendServerHelloAsHelloRetryRequest, if true, causes the server to
	// send ServerHello messages with a HelloRetryRequest type field.
	SendServerHelloAsHelloRetryRequest bool

	// RejectUnsolicitedKeyUpdate, if true, causes all unsolicited
	// KeyUpdates from the peer to be rejected.
	RejectUnsolicitedKeyUpdate bool

	// OmitExtensions, if true, causes the extensions field in ClientHello
	// and ServerHello messages to be omitted.
	OmitExtensions bool

	// EmptyExtensions, if true, causese the extensions field in ClientHello
	// and ServerHello messages to be present, but empty.
	EmptyExtensions bool
}

func (c *Config) serverInit() {
	if c.SessionTicketsDisabled {
		return
	}

	// If the key has already been set then we have nothing to do.
	for _, b := range c.SessionTicketKey {
		if b != 0 {
			return
		}
	}

	if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
		c.SessionTicketsDisabled = true
	}
}

func (c *Config) rand() io.Reader {
	r := c.Rand
	if r == nil {
		return rand.Reader
	}
	return r
}

func (c *Config) time() time.Time {
	t := c.Time
	if t == nil {
		t = time.Now
	}
	return t()
}

func (c *Config) cipherSuites() []uint16 {
	s := c.CipherSuites
	if s == nil {
		s = defaultCipherSuites()
	}
	return s
}

func (c *Config) minVersion(isDTLS bool) uint16 {
	ret := uint16(minVersion)
	if c != nil && c.MinVersion != 0 {
		ret = c.MinVersion
	}
	if isDTLS {
		// The lowest version of DTLS is 1.0. There is no DSSL 3.0.
		if ret < VersionTLS10 {
			return VersionTLS10
		}
		// There is no such thing as DTLS 1.1.
		if ret == VersionTLS11 {
			return VersionTLS12
		}
	}
	return ret
}

func (c *Config) maxVersion(isDTLS bool) uint16 {
	ret := uint16(maxVersion)
	if c != nil && c.MaxVersion != 0 {
		ret = c.MaxVersion
	}
	if isDTLS {
		// We only implement up to DTLS 1.2.
		if ret > VersionTLS12 {
			return VersionTLS12
		}
		// There is no such thing as DTLS 1.1.
		if ret == VersionTLS11 {
			return VersionTLS10
		}
	}
	return ret
}

var defaultCurvePreferences = []CurveID{CurveX25519, CurveP256, CurveP384, CurveP521}

func (c *Config) curvePreferences() []CurveID {
	if c == nil || len(c.CurvePreferences) == 0 {
		return defaultCurvePreferences
	}
	return c.CurvePreferences
}

func (c *Config) defaultCurves() map[CurveID]bool {
	defaultCurves := make(map[CurveID]bool)
	curves := c.DefaultCurves
	if c == nil || c.DefaultCurves == nil {
		curves = c.curvePreferences()
	}
	for _, curveID := range curves {
		defaultCurves[curveID] = true
	}
	return defaultCurves
}

// isSupportedVersion checks if the specified wire version is acceptable. If so,
// it returns true and the corresponding protocol version. Otherwise, it returns
// false.
func (c *Config) isSupportedVersion(wireVers uint16, isDTLS bool) (uint16, bool) {
	if (c.TLS13Variant != TLS13Experiment && wireVers == tls13ExperimentVersion) ||
		(c.TLS13Variant != TLS13RecordTypeExperiment && wireVers == tls13RecordTypeExperimentVersion) ||
		(c.TLS13Variant != TLS13Default && wireVers == tls13DraftVersion) {
		return 0, false
	}

	vers, ok := wireToVersion(wireVers, isDTLS)
	if !ok || c.minVersion(isDTLS) > vers || vers > c.maxVersion(isDTLS) {
		return 0, false
	}
	return vers, true
}

func (c *Config) supportedVersions(isDTLS bool) []uint16 {
	versions := allTLSWireVersions
	if isDTLS {
		versions = allDTLSWireVersions
	}
	var ret []uint16
	for _, vers := range versions {
		if _, ok := c.isSupportedVersion(vers, isDTLS); ok {
			ret = append(ret, vers)
		}
	}
	return ret
}

// getCertificateForName returns the best certificate for the given name,
// defaulting to the first element of c.Certificates if there are no good
// options.
func (c *Config) getCertificateForName(name string) *Certificate {
	if len(c.Certificates) == 1 || c.NameToCertificate == nil {
		// There's only one choice, so no point doing any work.
		return &c.Certificates[0]
	}

	name = strings.ToLower(name)
	for len(name) > 0 && name[len(name)-1] == '.' {
		name = name[:len(name)-1]
	}

	if cert, ok := c.NameToCertificate[name]; ok {
		return cert
	}

	// try replacing labels in the name with wildcards until we get a
	// match.
	labels := strings.Split(name, ".")
	for i := range labels {
		labels[i] = "*"
		candidate := strings.Join(labels, ".")
		if cert, ok := c.NameToCertificate[candidate]; ok {
			return cert
		}
	}

	// If nothing matches, return the first certificate.
	return &c.Certificates[0]
}

func (c *Config) signSignatureAlgorithms() []signatureAlgorithm {
	if c != nil && c.SignSignatureAlgorithms != nil {
		return c.SignSignatureAlgorithms
	}
	return supportedSignatureAlgorithms
}

func (c *Config) verifySignatureAlgorithms() []signatureAlgorithm {
	if c != nil && c.VerifySignatureAlgorithms != nil {
		return c.VerifySignatureAlgorithms
	}
	return supportedSignatureAlgorithms
}

// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
// from the CommonName and SubjectAlternateName fields of each of the leaf
// certificates.
func (c *Config) BuildNameToCertificate() {
	c.NameToCertificate = make(map[string]*Certificate)
	for i := range c.Certificates {
		cert := &c.Certificates[i]
		x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
		if err != nil {
			continue
		}
		if len(x509Cert.Subject.CommonName) > 0 {
			c.NameToCertificate[x509Cert.Subject.CommonName] = cert
		}
		for _, san := range x509Cert.DNSNames {
			c.NameToCertificate[san] = cert
		}
	}
}

// A Certificate is a chain of one or more certificates, leaf first.
type Certificate struct {
	Certificate [][]byte
	PrivateKey  crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey
	// OCSPStaple contains an optional OCSP response which will be served
	// to clients that request it.
	OCSPStaple []byte
	// SignedCertificateTimestampList contains an optional encoded
	// SignedCertificateTimestampList structure which will be
	// served to clients that request it.
	SignedCertificateTimestampList []byte
	// Leaf is the parsed form of the leaf certificate, which may be
	// initialized using x509.ParseCertificate to reduce per-handshake
	// processing for TLS clients doing client authentication. If nil, the
	// leaf certificate will be parsed as needed.
	Leaf *x509.Certificate
}

// A TLS record.
type record struct {
	contentType  recordType
	major, minor uint8
	payload      []byte
}

type handshakeMessage interface {
	marshal() []byte
	unmarshal([]byte) bool
}

// lruSessionCache is a client or server session cache implementation
// that uses an LRU caching strategy.
type lruSessionCache struct {
	sync.Mutex

	m        map[string]*list.Element
	q        *list.List
	capacity int
}

type lruSessionCacheEntry struct {
	sessionKey string
	state      interface{}
}

// Put adds the provided (sessionKey, cs) pair to the cache.
func (c *lruSessionCache) Put(sessionKey string, cs interface{}) {
	c.Lock()
	defer c.Unlock()

	if elem, ok := c.m[sessionKey]; ok {
		entry := elem.Value.(*lruSessionCacheEntry)
		entry.state = cs
		c.q.MoveToFront(elem)
		return
	}

	if c.q.Len() < c.capacity {
		entry := &lruSessionCacheEntry{sessionKey, cs}
		c.m[sessionKey] = c.q.PushFront(entry)
		return
	}

	elem := c.q.Back()
	entry := elem.Value.(*lruSessionCacheEntry)
	delete(c.m, entry.sessionKey)
	entry.sessionKey = sessionKey
	entry.state = cs
	c.q.MoveToFront(elem)
	c.m[sessionKey] = elem
}

// Get returns the value associated with a given key. It returns (nil,
// false) if no value is found.
func (c *lruSessionCache) Get(sessionKey string) (interface{}, bool) {
	c.Lock()
	defer c.Unlock()

	if elem, ok := c.m[sessionKey]; ok {
		c.q.MoveToFront(elem)
		return elem.Value.(*lruSessionCacheEntry).state, true
	}
	return nil, false
}

// lruClientSessionCache is a ClientSessionCache implementation that
// uses an LRU caching strategy.
type lruClientSessionCache struct {
	lruSessionCache
}

func (c *lruClientSessionCache) Put(sessionKey string, cs *ClientSessionState) {
	c.lruSessionCache.Put(sessionKey, cs)
}

func (c *lruClientSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
	cs, ok := c.lruSessionCache.Get(sessionKey)
	if !ok {
		return nil, false
	}
	return cs.(*ClientSessionState), true
}

// lruServerSessionCache is a ServerSessionCache implementation that
// uses an LRU caching strategy.
type lruServerSessionCache struct {
	lruSessionCache
}

func (c *lruServerSessionCache) Put(sessionId string, session *sessionState) {
	c.lruSessionCache.Put(sessionId, session)
}

func (c *lruServerSessionCache) Get(sessionId string) (*sessionState, bool) {
	cs, ok := c.lruSessionCache.Get(sessionId)
	if !ok {
		return nil, false
	}
	return cs.(*sessionState), true
}

// NewLRUClientSessionCache returns a ClientSessionCache with the given
// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
// is used instead.
func NewLRUClientSessionCache(capacity int) ClientSessionCache {
	const defaultSessionCacheCapacity = 64

	if capacity < 1 {
		capacity = defaultSessionCacheCapacity
	}
	return &lruClientSessionCache{
		lruSessionCache{
			m:        make(map[string]*list.Element),
			q:        list.New(),
			capacity: capacity,
		},
	}
}

// NewLRUServerSessionCache returns a ServerSessionCache with the given
// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
// is used instead.
func NewLRUServerSessionCache(capacity int) ServerSessionCache {
	const defaultSessionCacheCapacity = 64

	if capacity < 1 {
		capacity = defaultSessionCacheCapacity
	}
	return &lruServerSessionCache{
		lruSessionCache{
			m:        make(map[string]*list.Element),
			q:        list.New(),
			capacity: capacity,
		},
	}
}

// TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
type dsaSignature struct {
	R, S *big.Int
}

type ecdsaSignature dsaSignature

var emptyConfig Config

func defaultConfig() *Config {
	return &emptyConfig
}

var (
	once                   sync.Once
	varDefaultCipherSuites []uint16
)

func defaultCipherSuites() []uint16 {
	once.Do(initDefaultCipherSuites)
	return varDefaultCipherSuites
}

func initDefaultCipherSuites() {
	for _, suite := range cipherSuites {
		if suite.flags&suitePSK == 0 {
			varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id)
		}
	}
}

func unexpectedMessageError(wanted, got interface{}) error {
	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
}

func isSupportedSignatureAlgorithm(sigAlg signatureAlgorithm, sigAlgs []signatureAlgorithm) bool {
	for _, s := range sigAlgs {
		if s == sigAlg {
			return true
		}
	}
	return false
}

var (
	// See draft-ietf-tls-tls13-16, section 6.3.1.2.
	downgradeTLS13 = []byte{0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01}
	downgradeTLS12 = []byte{0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00}
)

func containsGREASE(values []uint16) bool {
	for _, v := range values {
		if isGREASEValue(v) {
			return true
		}
	}
	return false
}