|
|
|
@ -21,7 +21,7 @@ func makeGREASE() []byte {
|
|
|
|
|
return doubleGREASE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Chrome) composeExtensions(sni []byte, keyShare []byte) []byte {
|
|
|
|
|
func (c *Chrome) composeExtensions(serverName string, keyShare []byte) []byte {
|
|
|
|
|
|
|
|
|
|
makeSupportedGroups := func() []byte {
|
|
|
|
|
suppGroupListLen := []byte{0x00, 0x08}
|
|
|
|
@ -47,13 +47,13 @@ func (c *Chrome) composeExtensions(sni []byte, keyShare []byte) []byte {
|
|
|
|
|
// extension length is always 403, and server name length is variable
|
|
|
|
|
|
|
|
|
|
var ext [17][]byte
|
|
|
|
|
ext[0] = addExtRec(makeGREASE(), nil) // First GREASE
|
|
|
|
|
ext[1] = addExtRec([]byte{0x00, 0x00}, sni) // server name indication
|
|
|
|
|
ext[2] = addExtRec([]byte{0x00, 0x17}, nil) // extended_master_secret
|
|
|
|
|
ext[3] = addExtRec([]byte{0xff, 0x01}, []byte{0x00}) // renegotiation_info
|
|
|
|
|
ext[4] = addExtRec([]byte{0x00, 0x0a}, makeSupportedGroups()) // supported groups
|
|
|
|
|
ext[5] = addExtRec([]byte{0x00, 0x0b}, []byte{0x01, 0x00}) // ec point formats
|
|
|
|
|
ext[6] = addExtRec([]byte{0x00, 0x23}, nil) // Session tickets
|
|
|
|
|
ext[0] = addExtRec(makeGREASE(), nil) // First GREASE
|
|
|
|
|
ext[1] = addExtRec([]byte{0x00, 0x00}, generateSNI(serverName)) // server name indication
|
|
|
|
|
ext[2] = addExtRec([]byte{0x00, 0x17}, nil) // extended_master_secret
|
|
|
|
|
ext[3] = addExtRec([]byte{0xff, 0x01}, []byte{0x00}) // renegotiation_info
|
|
|
|
|
ext[4] = addExtRec([]byte{0x00, 0x0a}, makeSupportedGroups()) // supported groups
|
|
|
|
|
ext[5] = addExtRec([]byte{0x00, 0x0b}, []byte{0x01, 0x00}) // ec point formats
|
|
|
|
|
ext[6] = addExtRec([]byte{0x00, 0x23}, nil) // Session tickets
|
|
|
|
|
ALPN, _ := hex.DecodeString("000c02683208687474702f312e31")
|
|
|
|
|
ext[7] = addExtRec([]byte{0x00, 0x10}, ALPN) // app layer proto negotiation
|
|
|
|
|
ext[8] = addExtRec([]byte{0x00, 0x05}, []byte{0x01, 0x00, 0x00, 0x00, 0x00}) // status request
|
|
|
|
@ -87,12 +87,12 @@ func (c *Chrome) composeClientHello(hd clientHelloFields) (ch []byte) {
|
|
|
|
|
clientHello[3] = hd.random // random
|
|
|
|
|
clientHello[4] = []byte{0x20} // session id length 32
|
|
|
|
|
clientHello[5] = hd.sessionId // session id
|
|
|
|
|
clientHello[6] = []byte{0x00, 0x20} // cipher suites length 34
|
|
|
|
|
clientHello[6] = []byte{0x00, 0x20} // cipher suites length 32
|
|
|
|
|
cipherSuites, _ := hex.DecodeString("130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035")
|
|
|
|
|
clientHello[7] = append(makeGREASE(), cipherSuites...) // cipher suites
|
|
|
|
|
clientHello[8] = []byte{0x01} // compression methods length 1
|
|
|
|
|
clientHello[9] = []byte{0x00} // compression methods
|
|
|
|
|
clientHello[11] = c.composeExtensions(hd.sni, hd.x25519KeyShare)
|
|
|
|
|
clientHello[11] = c.composeExtensions(hd.serverName, hd.x25519KeyShare)
|
|
|
|
|
clientHello[10] = []byte{0x00, 0x00} // extensions length 403
|
|
|
|
|
binary.BigEndian.PutUint16(clientHello[10], uint16(len(clientHello[11])))
|
|
|
|
|
var ret []byte
|
|
|
|
|