2018-10-07 17:09:45 +00:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"encoding/binary"
|
2019-01-25 00:24:47 +00:00
|
|
|
"github.com/cbeuw/Cloak/internal/ecdh"
|
|
|
|
"github.com/cbeuw/Cloak/internal/util"
|
2019-08-02 00:01:19 +00:00
|
|
|
"sync/atomic"
|
2018-10-07 17:09:45 +00:00
|
|
|
)
|
|
|
|
|
2019-08-12 21:43:16 +00:00
|
|
|
const (
|
|
|
|
UNORDERED_FLAG = 0x01 // 0000 0001
|
|
|
|
)
|
|
|
|
|
2019-08-16 23:16:31 +00:00
|
|
|
type chHiddenData struct {
|
|
|
|
chRandom []byte
|
|
|
|
chSessionId []byte
|
|
|
|
chX25519KeyShare []byte
|
|
|
|
chExtSNI []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeHiddenData(sta *State) (ret chHiddenData, sharedSecret []byte) {
|
2019-08-02 00:01:19 +00:00
|
|
|
// random is marshalled ephemeral pub key 32 bytes
|
2019-08-12 21:43:16 +00:00
|
|
|
// TLSsessionID || keyShare is [encrypted UID 16 bytes, proxy method 12 bytes, encryption method 1 byte, timestamp 8 bytes, sessionID 4 bytes] [1 byte flag] [6 bytes reserved] [16 bytes authentication tag]
|
2019-08-02 00:01:19 +00:00
|
|
|
ephPv, ephPub, _ := ecdh.GenerateKey(rand.Reader)
|
2019-08-16 23:16:31 +00:00
|
|
|
ret.chRandom = ecdh.Marshal(ephPub)
|
2019-08-02 00:01:19 +00:00
|
|
|
|
|
|
|
plaintext := make([]byte, 48)
|
|
|
|
copy(plaintext, sta.UID)
|
|
|
|
copy(plaintext[16:28], sta.ProxyMethod)
|
|
|
|
plaintext[28] = sta.EncryptionMethod
|
2019-08-16 23:18:19 +00:00
|
|
|
binary.BigEndian.PutUint64(plaintext[29:37], uint64(sta.now().Unix()))
|
2019-08-02 00:01:19 +00:00
|
|
|
binary.BigEndian.PutUint32(plaintext[37:41], atomic.LoadUint32(&sta.SessionID))
|
|
|
|
|
2019-08-12 21:43:16 +00:00
|
|
|
if sta.Unordered {
|
|
|
|
plaintext[41] |= UNORDERED_FLAG
|
|
|
|
}
|
|
|
|
|
2019-08-02 00:01:19 +00:00
|
|
|
sharedSecret = ecdh.GenerateSharedSecret(ephPv, sta.staticPub)
|
2019-08-16 23:16:31 +00:00
|
|
|
nonce := ret.chRandom[0:12]
|
2019-08-02 00:01:19 +00:00
|
|
|
ciphertext, _ := util.AESGCMEncrypt(nonce, sharedSecret, plaintext)
|
2019-08-16 23:16:31 +00:00
|
|
|
ret.chSessionId = ciphertext[0:32]
|
|
|
|
ret.chX25519KeyShare = ciphertext[32:64]
|
|
|
|
ret.chExtSNI = makeServerName(sta.ServerName)
|
2019-08-02 00:01:19 +00:00
|
|
|
return
|
2018-10-07 17:09:45 +00:00
|
|
|
}
|