mirror of https://github.com/cbeuw/Cloak
Minor refactors to remove unnecessary function
This commit is contained in:
parent
e157e73ade
commit
611bad91fd
|
|
@ -1,4 +1,6 @@
|
|||
corpus/
|
||||
suppressions/
|
||||
crashers/
|
||||
*.zip
|
||||
*.zip
|
||||
.idea/
|
||||
build/
|
||||
|
|
@ -13,14 +13,14 @@ type clientHelloFields struct {
|
|||
random []byte
|
||||
sessionId []byte
|
||||
x25519KeyShare []byte
|
||||
sni []byte
|
||||
serverName string
|
||||
}
|
||||
|
||||
type browser interface {
|
||||
composeClientHello(clientHelloFields) []byte
|
||||
}
|
||||
|
||||
func makeServerName(serverName string) []byte {
|
||||
func generateSNI(serverName string) []byte {
|
||||
serverNameListLength := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(serverNameListLength, uint16(len(serverName)+3))
|
||||
serverNameType := []byte{0x00} // host_name
|
||||
|
|
@ -45,16 +45,6 @@ func addExtRec(typ []byte, data []byte) []byte {
|
|||
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 {
|
||||
*common.TLSConn
|
||||
browser browser
|
||||
|
|
@ -64,7 +54,16 @@ type DirectTLS struct {
|
|||
// if the server proceed with Cloak authentication
|
||||
func (tls *DirectTLS) Handshake(rawConn net.Conn, authInfo AuthInfo) (sessionKey [32]byte, err error) {
|
||||
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)
|
||||
_, err = rawConn.Write(chWithRecordLayer)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,6 @@ func TestMakeServerName(t *testing.T) {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ func TestComposeExtension(t *testing.T) {
|
|||
serverName := "github.com"
|
||||
keyShare, _ := hex.DecodeString("690f074f5c01756982269b66d58c90c47dc0f281d654c7b2c16f63c9033f5604")
|
||||
|
||||
sni := makeServerName(serverName)
|
||||
|
||||
result := (&Chrome{}).composeExtensions(sni, keyShare)
|
||||
result := (&Chrome{}).composeExtensions(serverName, keyShare)
|
||||
target, _ := hex.DecodeString("8a8a00000000000f000d00000a6769746875622e636f6d00170000ff01000100000a000a00088a8a001d00170018000b00020100002300000010000e000c02683208687474702f312e31000500050100000000000d0012001004030804040105030805050108060601001200000033002b00298a8a000100001d0020690f074f5c01756982269b66d58c90c47dc0f281d654c7b2c16f63c9033f5604002d00020101002b000b0a3a3a0304030303020301001b00030200024a4a000100001500d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||
for p := 0; p < len(result); p++ {
|
||||
if result[p] != target[p] {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
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 {
|
||||
ret := make([]byte, 107)
|
||||
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
|
||||
var ext [12][]byte
|
||||
ext[0] = addExtRec([]byte{0x00, 0x00}, SNI) // server name indication
|
||||
ext[1] = addExtRec([]byte{0x00, 0x17}, nil) // extended_master_secret
|
||||
ext[2] = addExtRec([]byte{0xff, 0x01}, []byte{0x00}) // renegotiation_info
|
||||
ext[0] = addExtRec([]byte{0x00, 0x00}, generateSNI(serverName)) // server name indication
|
||||
ext[1] = addExtRec([]byte{0x00, 0x17}, nil) // extended_master_secret
|
||||
ext[2] = addExtRec([]byte{0xff, 0x01}, []byte{0x00}) // renegotiation_info
|
||||
suppGroup, _ := hex.DecodeString("000c001d00170018001901000101")
|
||||
ext[3] = addExtRec([]byte{0x00, 0x0a}, suppGroup) // supported groups
|
||||
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[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
|
||||
binary.BigEndian.PutUint16(clientHello[10], uint16(len(clientHello[11])))
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ func TestComposeExtensions(t *testing.T) {
|
|||
|
||||
serverName := "consent.google.com"
|
||||
keyShare, _ := hex.DecodeString("8d8ea1b80430b7710b65f0d89b0144a5eeb218709ce6613d4fc8bfb117657c15")
|
||||
sni := makeServerName(serverName)
|
||||
result := (&Firefox{}).composeExtensions(sni, keyShare)
|
||||
|
||||
result := (&Firefox{}).composeExtensions(serverName, keyShare)
|
||||
// skip random secp256r1
|
||||
if !bytes.Equal(result[:133], target[:133]) || !bytes.Equal(result[198:], target[198:]) {
|
||||
t.Errorf("got %x", result)
|
||||
|
|
|
|||
Loading…
Reference in New Issue