From 439b7f0eb3dcd8d2ef0328f51097b5b056c50574 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Mon, 28 Dec 2020 12:15:01 +0000 Subject: [PATCH] Improve encapsulation --- internal/multiplex/obfs.go | 10 +++++----- internal/multiplex/obfs_test.go | 30 +++++++++++++++--------------- internal/multiplex/session.go | 4 ++++ internal/server/dispatcher.go | 2 +- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/internal/multiplex/obfs.go b/internal/multiplex/obfs.go index 8fdf9ce..9fa614d 100644 --- a/internal/multiplex/obfs.go +++ b/internal/multiplex/obfs.go @@ -25,7 +25,7 @@ const ( type Obfuscator struct { payloadCipher cipher.AEAD - SessionKey [32]byte + sessionKey [32]byte maxOverhead int } @@ -35,7 +35,7 @@ func (o *Obfuscator) obfuscate(f *Frame, buf []byte, payloadOffsetInBuf int) (in // The method here is to use the first payloadCipher.NonceSize() bytes of the serialised frame header // as iv/nonce for the AEAD cipher to encrypt the frame payload. Then we use // the authentication tag produced appended to the end of the ciphertext (of size payloadCipher.Overhead()) - // as nonce for Salsa20 to encrypt the frame header. Both with SessionKey as keys. + // as nonce for Salsa20 to encrypt the frame header. Both with sessionKey as keys. // // Several cryptographic guarantees we have made here: that payloadCipher, as an AEAD, is given a unique // iv/nonce each time, relative to its key; that the frame header encryptor Salsa20 is given a unique @@ -108,7 +108,7 @@ func (o *Obfuscator) obfuscate(f *Frame, buf []byte, payloadOffsetInBuf int) (in } nonce := buf[usefulLen-salsa20NonceSize : usefulLen] - salsa20.XORKeyStream(header, header, nonce, &o.SessionKey) + salsa20.XORKeyStream(header, header, nonce, &o.sessionKey) return usefulLen, nil } @@ -123,7 +123,7 @@ func (o *Obfuscator) deobfuscate(f *Frame, in []byte) error { pldWithOverHead := in[frameHeaderLength:] // payload + potential overhead nonce := in[len(in)-salsa20NonceSize:] - salsa20.XORKeyStream(header, header, nonce, &o.SessionKey) + salsa20.XORKeyStream(header, header, nonce, &o.sessionKey) streamID := binary.BigEndian.Uint32(header[0:4]) seq := binary.BigEndian.Uint64(header[4:12]) @@ -160,7 +160,7 @@ func (o *Obfuscator) deobfuscate(f *Frame, in []byte) error { func MakeObfuscator(encryptionMethod byte, sessionKey [32]byte) (o Obfuscator, err error) { o = Obfuscator{ - SessionKey: sessionKey, + sessionKey: sessionKey, } switch encryptionMethod { case EncryptionMethodPlain: diff --git a/internal/multiplex/obfs_test.go b/internal/multiplex/obfs_test.go index 21c29fd..2dad728 100644 --- a/internal/multiplex/obfs_test.go +++ b/internal/multiplex/obfs_test.go @@ -17,9 +17,9 @@ func TestGenerateObfs(t *testing.T) { run := func(o Obfuscator, t *testing.T) { obfsBuf := make([]byte, 512) - _testFrame, _ := quick.Value(reflect.TypeOf(&Frame{}), rand.New(rand.NewSource(42))) - testFrame := _testFrame.Interface().(*Frame) - i, err := o.obfuscate(testFrame, obfsBuf, 0) + _testFrame, _ := quick.Value(reflect.TypeOf(Frame{}), rand.New(rand.NewSource(42))) + testFrame := _testFrame.Interface().(Frame) + i, err := o.obfuscate(&testFrame, obfsBuf, 0) assert.NoError(t, err) var resultFrame Frame @@ -83,7 +83,7 @@ func TestObfuscate(t *testing.T) { t.Run("plain", func(t *testing.T) { o := Obfuscator{ payloadCipher: nil, - SessionKey: sessionKey, + sessionKey: sessionKey, maxOverhead: salsa20NonceSize, } runTest(t, o) @@ -96,7 +96,7 @@ func TestObfuscate(t *testing.T) { assert.NoError(t, err) o := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: sessionKey, + sessionKey: sessionKey, maxOverhead: payloadCipher.Overhead(), } runTest(t, o) @@ -109,7 +109,7 @@ func TestObfuscate(t *testing.T) { assert.NoError(t, err) o := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: sessionKey, + sessionKey: sessionKey, maxOverhead: payloadCipher.Overhead(), } runTest(t, o) @@ -120,7 +120,7 @@ func TestObfuscate(t *testing.T) { assert.NoError(t, err) o := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: sessionKey, + sessionKey: sessionKey, maxOverhead: payloadCipher.Overhead(), } runTest(t, o) @@ -148,7 +148,7 @@ func BenchmarkObfs(b *testing.B) { obfuscator := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: key, + sessionKey: key, maxOverhead: payloadCipher.Overhead(), } @@ -164,7 +164,7 @@ func BenchmarkObfs(b *testing.B) { obfuscator := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: key, + sessionKey: key, maxOverhead: payloadCipher.Overhead(), } b.SetBytes(int64(len(testFrame.Payload))) @@ -176,7 +176,7 @@ func BenchmarkObfs(b *testing.B) { b.Run("plain", func(b *testing.B) { obfuscator := Obfuscator{ payloadCipher: nil, - SessionKey: key, + sessionKey: key, maxOverhead: salsa20NonceSize, } b.SetBytes(int64(len(testFrame.Payload))) @@ -190,7 +190,7 @@ func BenchmarkObfs(b *testing.B) { obfuscator := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: key, + sessionKey: key, maxOverhead: payloadCipher.Overhead(), } b.SetBytes(int64(len(testFrame.Payload))) @@ -220,7 +220,7 @@ func BenchmarkDeobfs(b *testing.B) { payloadCipher, _ := cipher.NewGCM(c) obfuscator := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: key, + sessionKey: key, maxOverhead: payloadCipher.Overhead(), } @@ -239,7 +239,7 @@ func BenchmarkDeobfs(b *testing.B) { obfuscator := Obfuscator{ payloadCipher: payloadCipher, - SessionKey: key, + sessionKey: key, maxOverhead: payloadCipher.Overhead(), } n, _ := obfuscator.obfuscate(testFrame, obfsBuf, 0) @@ -254,7 +254,7 @@ func BenchmarkDeobfs(b *testing.B) { b.Run("plain", func(b *testing.B) { obfuscator := Obfuscator{ payloadCipher: nil, - SessionKey: key, + sessionKey: key, maxOverhead: salsa20NonceSize, } n, _ := obfuscator.obfuscate(testFrame, obfsBuf, 0) @@ -271,7 +271,7 @@ func BenchmarkDeobfs(b *testing.B) { obfuscator := Obfuscator{ payloadCipher: nil, - SessionKey: key, + sessionKey: key, maxOverhead: payloadCipher.Overhead(), } diff --git a/internal/multiplex/session.go b/internal/multiplex/session.go index e05e399..6abc90e 100644 --- a/internal/multiplex/session.go +++ b/internal/multiplex/session.go @@ -128,6 +128,10 @@ func MakeSession(id uint32, config SessionConfig) *Session { return sesh } +func (sesh *Session) GetSessionKey() [32]byte { + return sesh.sessionKey +} + func (sesh *Session) streamCountIncr() uint32 { return atomic.AddUint32(&sesh.activeStreamCount, 1) } diff --git a/internal/server/dispatcher.go b/internal/server/dispatcher.go index 9daa772..287e363 100644 --- a/internal/server/dispatcher.go +++ b/internal/server/dispatcher.go @@ -236,7 +236,7 @@ func dispatchConnection(conn net.Conn, sta *State) { return } - preparedConn, err := finishHandshake(conn, sesh.SessionKey, sta.WorldState.Rand) + preparedConn, err := finishHandshake(conn, sesh.GetSessionKey(), sta.WorldState.Rand) if err != nil { log.Error(err) return