1// Copyright 2017 Google Inc. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package tls
6
7import (
8	"crypto/sha256"
9	"encoding/binary"
10	"errors"
11	"fmt"
12	"io"
13	"sort"
14	"strconv"
15)
16
17func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
18	switch id {
19	case HelloChrome_58, HelloChrome_62:
20		return ClientHelloSpec{
21			TLSVersMax: VersionTLS12,
22			TLSVersMin: VersionTLS10,
23			CipherSuites: []uint16{
24				GREASE_PLACEHOLDER,
25				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
26				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
27				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
28				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
29				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
30				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
31				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
32				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
33				TLS_RSA_WITH_AES_128_GCM_SHA256,
34				TLS_RSA_WITH_AES_256_GCM_SHA384,
35				TLS_RSA_WITH_AES_128_CBC_SHA,
36				TLS_RSA_WITH_AES_256_CBC_SHA,
37				TLS_RSA_WITH_3DES_EDE_CBC_SHA,
38			},
39			CompressionMethods: []byte{compressionNone},
40			Extensions: []TLSExtension{
41				&UtlsGREASEExtension{},
42				&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
43				&SNIExtension{},
44				&UtlsExtendedMasterSecretExtension{},
45				&SessionTicketExtension{},
46				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
47					ECDSAWithP256AndSHA256,
48					PSSWithSHA256,
49					PKCS1WithSHA256,
50					ECDSAWithP384AndSHA384,
51					PSSWithSHA384,
52					PKCS1WithSHA384,
53					PSSWithSHA512,
54					PKCS1WithSHA512,
55					PKCS1WithSHA1},
56				},
57				&StatusRequestExtension{},
58				&SCTExtension{},
59				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
60				&FakeChannelIDExtension{},
61				&SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}},
62				&SupportedCurvesExtension{[]CurveID{CurveID(GREASE_PLACEHOLDER),
63					X25519, CurveP256, CurveP384}},
64				&UtlsGREASEExtension{},
65				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
66			},
67			GetSessionID: sha256.Sum256,
68		}, nil
69	case HelloChrome_70:
70		return ClientHelloSpec{
71			TLSVersMin: VersionTLS10,
72			TLSVersMax: VersionTLS13,
73			CipherSuites: []uint16{
74				GREASE_PLACEHOLDER,
75				TLS_AES_128_GCM_SHA256,
76				TLS_AES_256_GCM_SHA384,
77				TLS_CHACHA20_POLY1305_SHA256,
78				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
79				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
80				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
81				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
82				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
83				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
84				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
85				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
86				TLS_RSA_WITH_AES_128_GCM_SHA256,
87				TLS_RSA_WITH_AES_256_GCM_SHA384,
88				TLS_RSA_WITH_AES_128_CBC_SHA,
89				TLS_RSA_WITH_AES_256_CBC_SHA,
90				TLS_RSA_WITH_3DES_EDE_CBC_SHA,
91			},
92			CompressionMethods: []byte{
93				compressionNone,
94			},
95			Extensions: []TLSExtension{
96				&UtlsGREASEExtension{},
97				&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
98				&SNIExtension{},
99				&UtlsExtendedMasterSecretExtension{},
100				&SessionTicketExtension{},
101				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
102					ECDSAWithP256AndSHA256,
103					PSSWithSHA256,
104					PKCS1WithSHA256,
105					ECDSAWithP384AndSHA384,
106					PSSWithSHA384,
107					PKCS1WithSHA384,
108					PSSWithSHA512,
109					PKCS1WithSHA512,
110					PKCS1WithSHA1,
111				}},
112				&StatusRequestExtension{},
113				&SCTExtension{},
114				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
115				&FakeChannelIDExtension{},
116				&SupportedPointsExtension{SupportedPoints: []byte{
117					pointFormatUncompressed,
118				}},
119				&KeyShareExtension{[]KeyShare{
120					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
121					{Group: X25519},
122				}},
123				&PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}},
124				&SupportedVersionsExtension{[]uint16{
125					GREASE_PLACEHOLDER,
126					VersionTLS13,
127					VersionTLS12,
128					VersionTLS11,
129					VersionTLS10}},
130				&SupportedCurvesExtension{[]CurveID{
131					CurveID(GREASE_PLACEHOLDER),
132					X25519,
133					CurveP256,
134					CurveP384,
135				}},
136				&CompressCertificateExtension{
137					Algorithms: []CertCompressionAlgo{CertCompressionBrotli},
138				},
139				&UtlsGREASEExtension{},
140				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
141			},
142		}, nil
143	case HelloChrome_72:
144		return ClientHelloSpec{
145			CipherSuites: []uint16{
146				GREASE_PLACEHOLDER,
147				TLS_AES_128_GCM_SHA256,
148				TLS_AES_256_GCM_SHA384,
149				TLS_CHACHA20_POLY1305_SHA256,
150				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
151				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
152				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
153				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
154				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
155				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
156				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
157				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
158				TLS_RSA_WITH_AES_128_GCM_SHA256,
159				TLS_RSA_WITH_AES_256_GCM_SHA384,
160				TLS_RSA_WITH_AES_128_CBC_SHA,
161				TLS_RSA_WITH_AES_256_CBC_SHA,
162				TLS_RSA_WITH_3DES_EDE_CBC_SHA,
163			},
164			CompressionMethods: []byte{
165				0x00, // compressionNone
166			},
167			Extensions: []TLSExtension{
168				&UtlsGREASEExtension{},
169				&SNIExtension{},
170				&UtlsExtendedMasterSecretExtension{},
171				&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
172				&SupportedCurvesExtension{[]CurveID{
173					CurveID(GREASE_PLACEHOLDER),
174					X25519,
175					CurveP256,
176					CurveP384,
177				}},
178				&SupportedPointsExtension{SupportedPoints: []byte{
179					0x00, // pointFormatUncompressed
180				}},
181				&SessionTicketExtension{},
182				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
183				&StatusRequestExtension{},
184				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
185					ECDSAWithP256AndSHA256,
186					PSSWithSHA256,
187					PKCS1WithSHA256,
188					ECDSAWithP384AndSHA384,
189					PSSWithSHA384,
190					PKCS1WithSHA384,
191					PSSWithSHA512,
192					PKCS1WithSHA512,
193					PKCS1WithSHA1,
194				}},
195				&SCTExtension{},
196				&KeyShareExtension{[]KeyShare{
197					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
198					{Group: X25519},
199				}},
200				&PSKKeyExchangeModesExtension{[]uint8{
201					PskModeDHE,
202				}},
203				&SupportedVersionsExtension{[]uint16{
204					GREASE_PLACEHOLDER,
205					VersionTLS13,
206					VersionTLS12,
207					VersionTLS11,
208					VersionTLS10,
209				}},
210				&CompressCertificateExtension{
211					Algorithms: []CertCompressionAlgo{CertCompressionBrotli},
212				},
213				&UtlsGREASEExtension{},
214				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
215			},
216		}, nil
217	case HelloFirefox_55, HelloFirefox_56:
218		return ClientHelloSpec{
219			TLSVersMax: VersionTLS12,
220			TLSVersMin: VersionTLS10,
221			CipherSuites: []uint16{
222				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
223				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
224				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
225				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
226				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
227				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
228				TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
229				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
230				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
231				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
232				FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
233				FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
234				TLS_RSA_WITH_AES_128_CBC_SHA,
235				TLS_RSA_WITH_AES_256_CBC_SHA,
236				TLS_RSA_WITH_3DES_EDE_CBC_SHA,
237			},
238			CompressionMethods: []byte{compressionNone},
239			Extensions: []TLSExtension{
240				&SNIExtension{},
241				&UtlsExtendedMasterSecretExtension{},
242				&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
243				&SupportedCurvesExtension{[]CurveID{X25519, CurveP256, CurveP384, CurveP521}},
244				&SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}},
245				&SessionTicketExtension{},
246				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
247				&StatusRequestExtension{},
248				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
249					ECDSAWithP256AndSHA256,
250					ECDSAWithP384AndSHA384,
251					ECDSAWithP521AndSHA512,
252					PSSWithSHA256,
253					PSSWithSHA384,
254					PSSWithSHA512,
255					PKCS1WithSHA256,
256					PKCS1WithSHA384,
257					PKCS1WithSHA512,
258					ECDSAWithSHA1,
259					PKCS1WithSHA1},
260				},
261				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
262			},
263			GetSessionID: nil,
264		}, nil
265	case HelloFirefox_63, HelloFirefox_65:
266		return ClientHelloSpec{
267			TLSVersMin: VersionTLS10,
268			TLSVersMax: VersionTLS13,
269			CipherSuites: []uint16{
270				TLS_AES_128_GCM_SHA256,
271				TLS_CHACHA20_POLY1305_SHA256,
272				TLS_AES_256_GCM_SHA384,
273				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
274				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
275				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
276				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
277				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
278				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
279				TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
280				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
281				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
282				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
283				FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
284				FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
285				TLS_RSA_WITH_AES_128_CBC_SHA,
286				TLS_RSA_WITH_AES_256_CBC_SHA,
287				TLS_RSA_WITH_3DES_EDE_CBC_SHA,
288			},
289			CompressionMethods: []byte{
290				compressionNone,
291			},
292			Extensions: []TLSExtension{
293				&SNIExtension{},
294				&UtlsExtendedMasterSecretExtension{},
295				&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
296				&SupportedCurvesExtension{[]CurveID{
297					X25519,
298					CurveP256,
299					CurveP384,
300					CurveP521,
301					CurveID(FakeFFDHE2048),
302					CurveID(FakeFFDHE3072),
303				}},
304				&SupportedPointsExtension{SupportedPoints: []byte{
305					pointFormatUncompressed,
306				}},
307				&SessionTicketExtension{},
308				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
309				&StatusRequestExtension{},
310				&KeyShareExtension{[]KeyShare{
311					{Group: X25519},
312					{Group: CurveP256},
313				}},
314				&SupportedVersionsExtension{[]uint16{
315					VersionTLS13,
316					VersionTLS12,
317					VersionTLS11,
318					VersionTLS10}},
319				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
320					ECDSAWithP256AndSHA256,
321					ECDSAWithP384AndSHA384,
322					ECDSAWithP521AndSHA512,
323					PSSWithSHA256,
324					PSSWithSHA384,
325					PSSWithSHA512,
326					PKCS1WithSHA256,
327					PKCS1WithSHA384,
328					PKCS1WithSHA512,
329					ECDSAWithSHA1,
330					PKCS1WithSHA1,
331				}},
332				&PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}},
333				&FakeRecordSizeLimitExtension{0x4001},
334				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
335			}}, nil
336	case HelloIOS_11_1:
337		return ClientHelloSpec{
338			TLSVersMax: VersionTLS12,
339			TLSVersMin: VersionTLS10,
340			CipherSuites: []uint16{
341				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
342				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
343				DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
344				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
345				TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
346				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
347				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
348				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
349				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
350				DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
351				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
352				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
353				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
354				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
355				TLS_RSA_WITH_AES_256_GCM_SHA384,
356				TLS_RSA_WITH_AES_128_GCM_SHA256,
357				DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256,
358				TLS_RSA_WITH_AES_128_CBC_SHA256,
359				TLS_RSA_WITH_AES_256_CBC_SHA,
360				TLS_RSA_WITH_AES_128_CBC_SHA,
361			},
362			CompressionMethods: []byte{
363				compressionNone,
364			},
365			Extensions: []TLSExtension{
366				&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
367				&SNIExtension{},
368				&UtlsExtendedMasterSecretExtension{},
369				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
370					ECDSAWithP256AndSHA256,
371					PSSWithSHA256,
372					PKCS1WithSHA256,
373					ECDSAWithP384AndSHA384,
374					PSSWithSHA384,
375					PKCS1WithSHA384,
376					PSSWithSHA512,
377					PKCS1WithSHA512,
378					PKCS1WithSHA1,
379				}},
380				&StatusRequestExtension{},
381				&NPNExtension{},
382				&SCTExtension{},
383				&ALPNExtension{AlpnProtocols: []string{"h2", "h2-16", "h2-15", "h2-14", "spdy/3.1", "spdy/3", "http/1.1"}},
384				&SupportedPointsExtension{SupportedPoints: []byte{
385					pointFormatUncompressed,
386				}},
387				&SupportedCurvesExtension{Curves: []CurveID{
388					X25519,
389					CurveP256,
390					CurveP384,
391					CurveP521,
392				}},
393			},
394		}, nil
395	case HelloIOS_12_1:
396		return ClientHelloSpec{
397			CipherSuites: []uint16{
398				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
399				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
400				DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
401				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
402				TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
403				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
404				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
405				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
406				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
407				DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
408				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
409				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
410				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
411				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
412				TLS_RSA_WITH_AES_256_GCM_SHA384,
413				TLS_RSA_WITH_AES_128_GCM_SHA256,
414				DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256,
415				TLS_RSA_WITH_AES_128_CBC_SHA256,
416				TLS_RSA_WITH_AES_256_CBC_SHA,
417				TLS_RSA_WITH_AES_128_CBC_SHA,
418				0xc008,
419				TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
420				TLS_RSA_WITH_3DES_EDE_CBC_SHA,
421			},
422			CompressionMethods: []byte{
423				compressionNone,
424			},
425			Extensions: []TLSExtension{
426				&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
427				&SNIExtension{},
428				&UtlsExtendedMasterSecretExtension{},
429				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
430					ECDSAWithP256AndSHA256,
431					PSSWithSHA256,
432					PKCS1WithSHA256,
433					ECDSAWithP384AndSHA384,
434					ECDSAWithSHA1,
435					PSSWithSHA384,
436					PSSWithSHA384,
437					PKCS1WithSHA384,
438					PSSWithSHA512,
439					PKCS1WithSHA512,
440					PKCS1WithSHA1,
441				}},
442				&StatusRequestExtension{},
443				&NPNExtension{},
444				&SCTExtension{},
445				&ALPNExtension{AlpnProtocols: []string{"h2", "h2-16", "h2-15", "h2-14", "spdy/3.1", "spdy/3", "http/1.1"}},
446				&SupportedPointsExtension{SupportedPoints: []byte{
447					pointFormatUncompressed,
448				}},
449				&SupportedCurvesExtension{[]CurveID{
450					X25519,
451					CurveP256,
452					CurveP384,
453					CurveP521,
454				}},
455			},
456		}, nil
457	default:
458		return ClientHelloSpec{}, errors.New("ClientHello ID " + id.Str() + " is unknown")
459	}
460}
461
462func (uconn *UConn) applyPresetByID(id ClientHelloID) (err error) {
463	var spec ClientHelloSpec
464	uconn.ClientHelloID = id
465	// choose/generate the spec
466	switch id.Client {
467	case helloRandomized, helloRandomizedNoALPN, helloRandomizedALPN:
468		spec, err = uconn.generateRandomizedSpec()
469		if err != nil {
470			return err
471		}
472	case helloCustom:
473		return nil
474
475	default:
476		spec, err = utlsIdToSpec(id)
477		if err != nil {
478			return err
479		}
480	}
481
482	return uconn.ApplyPreset(&spec)
483}
484
485// ApplyPreset should only be used in conjunction with HelloCustom to apply custom specs.
486// Fields of TLSExtensions that are slices/pointers are shared across different connections with
487// same ClientHelloSpec. It is advised to use different specs and avoid any shared state.
488func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
489	var err error
490
491	err = uconn.SetTLSVers(p.TLSVersMin, p.TLSVersMax, p.Extensions)
492	if err != nil {
493		return err
494	}
495
496	privateHello, ecdheParams, err := uconn.makeClientHello()
497	if err != nil {
498		return err
499	}
500	uconn.HandshakeState.Hello = privateHello.getPublicPtr()
501	uconn.HandshakeState.State13.EcdheParams = ecdheParamMapToPublic(ecdheParams)
502	hello := uconn.HandshakeState.Hello
503	session := uconn.HandshakeState.Session
504
505	switch len(hello.Random) {
506	case 0:
507		hello.Random = make([]byte, 32)
508		_, err := io.ReadFull(uconn.config.rand(), hello.Random)
509		if err != nil {
510			return errors.New("tls: short read from Rand: " + err.Error())
511		}
512	case 32:
513	// carry on
514	default:
515		return errors.New("ClientHello expected length: 32 bytes. Got: " +
516			strconv.Itoa(len(hello.Random)) + " bytes")
517	}
518	if len(hello.CipherSuites) == 0 {
519		hello.CipherSuites = defaultCipherSuites()
520	}
521	if len(hello.CompressionMethods) == 0 {
522		hello.CompressionMethods = []uint8{compressionNone}
523	}
524
525	// Currently, GREASE is assumed to come from BoringSSL
526	grease_bytes := make([]byte, 2*ssl_grease_last_index)
527	grease_extensions_seen := 0
528	_, err = io.ReadFull(uconn.config.rand(), grease_bytes)
529	if err != nil {
530		return errors.New("tls: short read from Rand: " + err.Error())
531	}
532	for i := range uconn.greaseSeed {
533		uconn.greaseSeed[i] = binary.LittleEndian.Uint16(grease_bytes[2*i : 2*i+2])
534	}
535	if uconn.greaseSeed[ssl_grease_extension1] == uconn.greaseSeed[ssl_grease_extension2] {
536		uconn.greaseSeed[ssl_grease_extension2] ^= 0x1010
537	}
538
539	hello.CipherSuites = make([]uint16, len(p.CipherSuites))
540	copy(hello.CipherSuites, p.CipherSuites)
541	for i := range hello.CipherSuites {
542		if hello.CipherSuites[i] == GREASE_PLACEHOLDER {
543			hello.CipherSuites[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_cipher)
544		}
545	}
546	uconn.GetSessionID = p.GetSessionID
547	uconn.Extensions = make([]TLSExtension, len(p.Extensions))
548	copy(uconn.Extensions, p.Extensions)
549
550	// reGrease, and point things to each other
551	for _, e := range uconn.Extensions {
552		switch ext := e.(type) {
553		case *SNIExtension:
554			if ext.ServerName == "" {
555				ext.ServerName = uconn.config.ServerName
556			}
557		case *UtlsGREASEExtension:
558			switch grease_extensions_seen {
559			case 0:
560				ext.Value = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_extension1)
561			case 1:
562				ext.Value = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_extension2)
563				ext.Body = []byte{0}
564			default:
565				return errors.New("at most 2 grease extensions are supported")
566			}
567			grease_extensions_seen += 1
568		case *SessionTicketExtension:
569			if session == nil && uconn.config.ClientSessionCache != nil {
570				cacheKey := clientSessionCacheKey(uconn.RemoteAddr(), uconn.config)
571				session, _ = uconn.config.ClientSessionCache.Get(cacheKey)
572				// TODO: use uconn.loadSession(hello.getPrivateObj()) to support TLS 1.3 PSK-style resumption
573			}
574			err := uconn.SetSessionState(session)
575			if err != nil {
576				return err
577			}
578		case *SupportedCurvesExtension:
579			for i := range ext.Curves {
580				if ext.Curves[i] == GREASE_PLACEHOLDER {
581					ext.Curves[i] = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group))
582				}
583			}
584		case *KeyShareExtension:
585			for i := range ext.KeyShares {
586				curveID := ext.KeyShares[i].Group
587				if curveID == GREASE_PLACEHOLDER {
588					ext.KeyShares[i].Group = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group))
589					continue
590				}
591				if len(ext.KeyShares[i].Data) > 1 {
592					continue
593				}
594
595				var params ecdheParameters
596				switch utlsSupportedGroups[curveID] {
597				case true:
598					var ok bool
599					params, ok = uconn.HandshakeState.State13.EcdheParams[curveID]
600					if !ok {
601						// Should never happen.
602						return fmt.Errorf("BUG: unsupported Curve in KeyShareExtension: %v.", curveID)
603					}
604				case false:
605					var err error
606					params, err = generateECDHEParameters(uconn.config.rand(), curveID)
607					if err != nil {
608						return fmt.Errorf("unsupported Curve in KeyShareExtension: %v."+
609							"To mimic it, fill the Data(key) field manually.", curveID)
610					}
611				}
612
613				ext.KeyShares[i].Data = params.PublicKey()
614			}
615		case *SupportedVersionsExtension:
616			for i := range ext.Versions {
617				if ext.Versions[i] == GREASE_PLACEHOLDER {
618					ext.Versions[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_version)
619				}
620			}
621		case *CompressCertificateExtension:
622			uconn.HandshakeState.State13.CertCompAlgs = ext.Algorithms
623		}
624	}
625	return nil
626}
627
628func (uconn *UConn) generateRandomizedSpec() (ClientHelloSpec, error) {
629	p := ClientHelloSpec{}
630
631	if uconn.ClientHelloID.Seed == nil {
632		seed, err := NewPRNGSeed()
633		if err != nil {
634			return p, err
635		}
636		uconn.ClientHelloID.Seed = seed
637	}
638
639	r := newPRNGWithSeed(uconn.ClientHelloID.Seed)
640
641	id := uconn.ClientHelloID
642
643	var WithALPN bool
644	switch id.Client {
645	case helloRandomizedALPN:
646		WithALPN = true
647	case helloRandomizedNoALPN:
648		WithALPN = false
649	case helloRandomized:
650		if r.FlipWeightedCoin(0.7) {
651			WithALPN = true
652		} else {
653			WithALPN = false
654		}
655	default:
656		return p, fmt.Errorf("using non-randomized ClientHelloID %v to generate randomized spec", id.Client)
657	}
658
659	p.CipherSuites = make([]uint16, len(defaultCipherSuites()))
660	copy(p.CipherSuites, defaultCipherSuites())
661	shuffledSuites, err := shuffledCiphers(r)
662	if err != nil {
663		return p, err
664	}
665
666	if r.FlipWeightedCoin(0.4) {
667		p.TLSVersMin = VersionTLS10
668		p.TLSVersMax = VersionTLS13
669		tls13ciphers := make([]uint16, len(defaultCipherSuitesTLS13()))
670		copy(tls13ciphers, defaultCipherSuitesTLS13())
671		r.rand.Shuffle(len(tls13ciphers), func(i, j int) {
672			tls13ciphers[i], tls13ciphers[j] = tls13ciphers[j], tls13ciphers[i]
673		})
674		// appending TLS 1.3 ciphers before TLS 1.2, since that's what popular implementations do
675		shuffledSuites = append(tls13ciphers, shuffledSuites...)
676
677		// TLS 1.3 forbids RC4 in any configurations
678		shuffledSuites = removeRC4Ciphers(shuffledSuites)
679	} else {
680		p.TLSVersMin = VersionTLS10
681		p.TLSVersMax = VersionTLS12
682	}
683
684	p.CipherSuites = removeRandomCiphers(r, shuffledSuites, 0.4)
685
686	sni := SNIExtension{uconn.config.ServerName}
687	sessionTicket := SessionTicketExtension{Session: uconn.HandshakeState.Session}
688
689	sigAndHashAlgos := []SignatureScheme{
690		ECDSAWithP256AndSHA256,
691		PKCS1WithSHA256,
692		ECDSAWithP384AndSHA384,
693		PKCS1WithSHA384,
694		PKCS1WithSHA1,
695		PKCS1WithSHA512,
696	}
697
698	if r.FlipWeightedCoin(0.63) {
699		sigAndHashAlgos = append(sigAndHashAlgos, ECDSAWithSHA1)
700	}
701	if r.FlipWeightedCoin(0.59) {
702		sigAndHashAlgos = append(sigAndHashAlgos, ECDSAWithP521AndSHA512)
703	}
704	if r.FlipWeightedCoin(0.51) || p.TLSVersMax == VersionTLS13 {
705		// https://tools.ietf.org/html/rfc8446 says "...RSASSA-PSS (which is mandatory in TLS 1.3)..."
706		sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA256)
707		if r.FlipWeightedCoin(0.9) {
708			// these usually go together
709			sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA384)
710			sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA512)
711		}
712	}
713
714	r.rand.Shuffle(len(sigAndHashAlgos), func(i, j int) {
715		sigAndHashAlgos[i], sigAndHashAlgos[j] = sigAndHashAlgos[j], sigAndHashAlgos[i]
716	})
717	sigAndHash := SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: sigAndHashAlgos}
718
719	status := StatusRequestExtension{}
720	sct := SCTExtension{}
721	ems := UtlsExtendedMasterSecretExtension{}
722	points := SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}}
723
724	curveIDs := []CurveID{}
725	if r.FlipWeightedCoin(0.71) || p.TLSVersMax == VersionTLS13 {
726		curveIDs = append(curveIDs, X25519)
727	}
728	curveIDs = append(curveIDs, CurveP256, CurveP384)
729	if r.FlipWeightedCoin(0.46) {
730		curveIDs = append(curveIDs, CurveP521)
731	}
732
733	curves := SupportedCurvesExtension{curveIDs}
734
735	padding := UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}
736	reneg := RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient}
737
738	p.Extensions = []TLSExtension{
739		&sni,
740		&sessionTicket,
741		&sigAndHash,
742		&points,
743		&curves,
744	}
745
746	if WithALPN {
747		if len(uconn.config.NextProtos) == 0 {
748			// if user didn't specify alpn yet, choose something popular
749			uconn.config.NextProtos = []string{"h2", "http/1.1"}
750		}
751		alpn := ALPNExtension{AlpnProtocols: uconn.config.NextProtos}
752		p.Extensions = append(p.Extensions, &alpn)
753	}
754
755	if r.FlipWeightedCoin(0.62) || p.TLSVersMax == VersionTLS13 {
756		// always include for TLS 1.3, since TLS 1.3 ClientHellos are often over 256 bytes
757		// and that's when padding is required to work around buggy middleboxes
758		p.Extensions = append(p.Extensions, &padding)
759	}
760	if r.FlipWeightedCoin(0.74) {
761		p.Extensions = append(p.Extensions, &status)
762	}
763	if r.FlipWeightedCoin(0.46) {
764		p.Extensions = append(p.Extensions, &sct)
765	}
766	if r.FlipWeightedCoin(0.75) {
767		p.Extensions = append(p.Extensions, &reneg)
768	}
769	if r.FlipWeightedCoin(0.77) {
770		p.Extensions = append(p.Extensions, &ems)
771	}
772	if p.TLSVersMax == VersionTLS13 {
773		ks := KeyShareExtension{[]KeyShare{
774			{Group: X25519}, // the key for the group will be generated later
775		}}
776		if r.FlipWeightedCoin(0.25) {
777			ks.KeyShares = append(ks.KeyShares, KeyShare{Group: CurveP256})
778		}
779		pskExchangeModes := PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}}
780		supportedVersionsExt := SupportedVersionsExtension{
781			Versions: makeSupportedVersions(p.TLSVersMin, p.TLSVersMax),
782		}
783		p.Extensions = append(p.Extensions, &ks, &pskExchangeModes, &supportedVersionsExt)
784	}
785	r.rand.Shuffle(len(p.Extensions), func(i, j int) {
786		p.Extensions[i], p.Extensions[j] = p.Extensions[j], p.Extensions[i]
787	})
788
789	return p, nil
790}
791
792func removeRandomCiphers(r *prng, s []uint16, maxRemovalProbability float64) []uint16 {
793	// removes elements in place
794	// probability to remove increases for further elements
795	// never remove first cipher
796	if len(s) <= 1 {
797		return s
798	}
799
800	// remove random elements
801	floatLen := float64(len(s))
802	sliceLen := len(s)
803	for i := 1; i < sliceLen; i++ {
804		if r.FlipWeightedCoin(maxRemovalProbability * float64(i) / floatLen) {
805			s = append(s[:i], s[i+1:]...)
806			sliceLen--
807			i--
808		}
809	}
810	return s[:sliceLen]
811}
812
813func shuffledCiphers(r *prng) ([]uint16, error) {
814	ciphers := make(sortableCiphers, len(cipherSuites))
815	perm := r.Perm(len(cipherSuites))
816	for i, suite := range cipherSuites {
817		ciphers[i] = sortableCipher{suite: suite.id,
818			isObsolete: ((suite.flags & suiteTLS12) == 0),
819			randomTag:  perm[i]}
820	}
821	sort.Sort(ciphers)
822	return ciphers.GetCiphers(), nil
823}
824
825type sortableCipher struct {
826	isObsolete bool
827	randomTag  int
828	suite      uint16
829}
830
831type sortableCiphers []sortableCipher
832
833func (ciphers sortableCiphers) Len() int {
834	return len(ciphers)
835}
836
837func (ciphers sortableCiphers) Less(i, j int) bool {
838	if ciphers[i].isObsolete && !ciphers[j].isObsolete {
839		return false
840	}
841	if ciphers[j].isObsolete && !ciphers[i].isObsolete {
842		return true
843	}
844	return ciphers[i].randomTag < ciphers[j].randomTag
845}
846
847func (ciphers sortableCiphers) Swap(i, j int) {
848	ciphers[i], ciphers[j] = ciphers[j], ciphers[i]
849}
850
851func (ciphers sortableCiphers) GetCiphers() []uint16 {
852	cipherIDs := make([]uint16, len(ciphers))
853	for i := range ciphers {
854		cipherIDs[i] = ciphers[i].suite
855	}
856	return cipherIDs
857}
858
859func removeRC4Ciphers(s []uint16) []uint16 {
860	// removes elements in place
861	sliceLen := len(s)
862	for i := 0; i < sliceLen; i++ {
863		cipher := s[i]
864		if cipher == TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ||
865			cipher == TLS_ECDHE_RSA_WITH_RC4_128_SHA ||
866			cipher == TLS_RSA_WITH_RC4_128_SHA {
867			s = append(s[:i], s[i+1:]...)
868			sliceLen--
869			i--
870		}
871	}
872	return s[:sliceLen]
873}
874