Minor refactors to remove unnecessary function

pull/184/head
Andy Wang 2 years ago
parent e157e73ade
commit 611bad91fd
No known key found for this signature in database
GPG Key ID: 181B49F9F38F3374

4
.gitignore vendored

@ -1,4 +1,6 @@
corpus/ corpus/
suppressions/ suppressions/
crashers/ crashers/
*.zip *.zip
.idea/
build/

@ -13,14 +13,14 @@ type clientHelloFields struct {
random []byte random []byte
sessionId []byte sessionId []byte
x25519KeyShare []byte x25519KeyShare []byte
sni []byte serverName string
} }
type browser interface { type browser interface {
composeClientHello(clientHelloFields) []byte composeClientHello(clientHelloFields) []byte
} }
func makeServerName(serverName string) []byte { func generateSNI(serverName string) []byte {
serverNameListLength := make([]byte, 2) serverNameListLength := make([]byte, 2)
binary.BigEndian.PutUint16(serverNameListLength, uint16(len(serverName)+3)) binary.BigEndian.PutUint16(serverNameListLength, uint16(len(serverName)+3))
serverNameType := []byte{0x00} // host_name serverNameType := []byte{0x00} // host_name
@ -45,16 +45,6 @@ func addExtRec(typ []byte, data []byte) []byte {
return ret return ret
} }
func genStegClientHello(ai authenticationPayload, serverName string) (ret clientHelloFields) {
// random is marshalled ephemeral pub key 32 bytes
// The authentication ciphertext and its tag are then distributed among SessionId and X25519KeyShare
ret.random = ai.randPubKey[:]
ret.sessionId = ai.ciphertextWithTag[0:32]
ret.x25519KeyShare = ai.ciphertextWithTag[32:64]
ret.sni = makeServerName(serverName)
return
}
type DirectTLS struct { type DirectTLS struct {
*common.TLSConn *common.TLSConn
browser browser browser browser
@ -64,7 +54,16 @@ type DirectTLS struct {
// if the server proceed with Cloak authentication // if the server proceed with Cloak authentication
func (tls *DirectTLS) Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error) { func (tls *DirectTLS) Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error) {
payload, sharedSecret := makeAuthenticationPayload(authInfo) payload, sharedSecret := makeAuthenticationPayload(authInfo)
chOnly := tls.browser.composeClientHello(genStegClientHello(payload, authInfo.MockDomain))
// random is marshalled ephemeral pub key 32 bytes
// The authentication ciphertext and its tag are then distributed among SessionId and X25519KeyShare
fields := clientHelloFields{
random: payload.randPubKey[:],
sessionId: payload.ciphertextWithTag[0:32],
x25519KeyShare: payload.ciphertextWithTag[32:64],
serverName: authInfo.MockDomain,
}
chOnly := tls.browser.composeClientHello(fields)
chWithRecordLayer := common.AddRecordLayer(chOnly, common.Handshake, common.VersionTLS11) chWithRecordLayer := common.AddRecordLayer(chOnly, common.Handshake, common.VersionTLS11)
_, err = rawConn.Write(chWithRecordLayer) _, err = rawConn.Write(chWithRecordLayer)
if err != nil { if err != nil {

@ -33,6 +33,6 @@ func TestMakeServerName(t *testing.T) {
} }
for _, p := range pairs { for _, p := range pairs {
assert.Equal(t, p.target, makeServerName(p.serverName)) assert.Equal(t, p.target, generateSNI(p.serverName))
} }
} }

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

@ -30,9 +30,7 @@ func TestComposeExtension(t *testing.T) {
serverName := "github.com" serverName := "github.com"
keyShare, _ := hex.DecodeString("690f074f5c01756982269b66d58c90c47dc0f281d654c7b2c16f63c9033f5604") keyShare, _ := hex.DecodeString("690f074f5c01756982269b66d58c90c47dc0f281d654c7b2c16f63c9033f5604")
sni := makeServerName(serverName) result := (&Chrome{}).composeExtensions(serverName, keyShare)
result := (&Chrome{}).composeExtensions(sni, keyShare)
target, _ := hex.DecodeString("8a8a00000000000f000d00000a6769746875622e636f6d00170000ff01000100000a000a00088a8a001d00170018000b00020100002300000010000e000c02683208687474702f312e31000500050100000000000d0012001004030804040105030805050108060601001200000033002b00298a8a000100001d0020690f074f5c01756982269b66d58c90c47dc0f281d654c7b2c16f63c9033f5604002d00020101002b000b0a3a3a0304030303020301001b00030200024a4a000100001500d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") target, _ := hex.DecodeString("8a8a00000000000f000d00000a6769746875622e636f6d00170000ff01000100000a000a00088a8a001d00170018000b00020100002300000010000e000c02683208687474702f312e31000500050100000000000d0012001004030804040105030805050108060601001200000033002b00298a8a000100001d0020690f074f5c01756982269b66d58c90c47dc0f281d654c7b2c16f63c9033f5604002d00020101002b000b0a3a3a0304030303020301001b00030200024a4a000100001500d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
for p := 0; p < len(result); p++ { for p := 0; p < len(result); p++ {
if result[p] != target[p] { if result[p] != target[p] {

@ -10,7 +10,7 @@ import (
type Firefox struct{} type Firefox struct{}
func (f *Firefox) composeExtensions(SNI []byte, keyShare []byte) []byte { func (f *Firefox) composeExtensions(serverName string, keyShare []byte) []byte {
composeKeyShare := func(hidden []byte) []byte { composeKeyShare := func(hidden []byte) []byte {
ret := make([]byte, 107) ret := make([]byte, 107)
ret[0], ret[1] = 0x00, 0x69 // length 105 ret[0], ret[1] = 0x00, 0x69 // length 105
@ -24,9 +24,9 @@ func (f *Firefox) composeExtensions(SNI []byte, keyShare []byte) []byte {
} }
// extension length is always 399, and server name length is variable // extension length is always 399, and server name length is variable
var ext [12][]byte var ext [12][]byte
ext[0] = addExtRec([]byte{0x00, 0x00}, SNI) // server name indication ext[0] = addExtRec([]byte{0x00, 0x00}, generateSNI(serverName)) // server name indication
ext[1] = addExtRec([]byte{0x00, 0x17}, nil) // extended_master_secret ext[1] = addExtRec([]byte{0x00, 0x17}, nil) // extended_master_secret
ext[2] = addExtRec([]byte{0xff, 0x01}, []byte{0x00}) // renegotiation_info ext[2] = addExtRec([]byte{0xff, 0x01}, []byte{0x00}) // renegotiation_info
suppGroup, _ := hex.DecodeString("000c001d00170018001901000101") suppGroup, _ := hex.DecodeString("000c001d00170018001901000101")
ext[3] = addExtRec([]byte{0x00, 0x0a}, suppGroup) // supported groups ext[3] = addExtRec([]byte{0x00, 0x0a}, suppGroup) // supported groups
ext[4] = addExtRec([]byte{0x00, 0x0b}, []byte{0x01, 0x00}) // ec point formats ext[4] = addExtRec([]byte{0x00, 0x0b}, []byte{0x01, 0x00}) // ec point formats
@ -63,7 +63,7 @@ func (f *Firefox) composeClientHello(hd clientHelloFields) (ch []byte) {
clientHello[8] = []byte{0x01} // compression methods length 1 clientHello[8] = []byte{0x01} // compression methods length 1
clientHello[9] = []byte{0x00} // compression methods clientHello[9] = []byte{0x00} // compression methods
clientHello[11] = f.composeExtensions(hd.sni, hd.x25519KeyShare) clientHello[11] = f.composeExtensions(hd.serverName, hd.x25519KeyShare)
clientHello[10] = []byte{0x00, 0x00} // extensions length clientHello[10] = []byte{0x00, 0x00} // extensions length
binary.BigEndian.PutUint16(clientHello[10], uint16(len(clientHello[11]))) binary.BigEndian.PutUint16(clientHello[10], uint16(len(clientHello[11])))

@ -11,8 +11,8 @@ func TestComposeExtensions(t *testing.T) {
serverName := "consent.google.com" serverName := "consent.google.com"
keyShare, _ := hex.DecodeString("8d8ea1b80430b7710b65f0d89b0144a5eeb218709ce6613d4fc8bfb117657c15") keyShare, _ := hex.DecodeString("8d8ea1b80430b7710b65f0d89b0144a5eeb218709ce6613d4fc8bfb117657c15")
sni := makeServerName(serverName)
result := (&Firefox{}).composeExtensions(sni, keyShare) result := (&Firefox{}).composeExtensions(serverName, keyShare)
// skip random secp256r1 // skip random secp256r1
if !bytes.Equal(result[:133], target[:133]) || !bytes.Equal(result[198:], target[198:]) { if !bytes.Equal(result[:133], target[:133]) || !bytes.Equal(result[198:], target[198:]) {
t.Errorf("got %x", result) t.Errorf("got %x", result)

Loading…
Cancel
Save