| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- package newobfuscated2
-
- import (
- "bytes"
- "crypto/aes"
- "crypto/cipher"
- "crypto/sha256"
- "encoding/binary"
- "io"
- "time"
-
- "github.com/juju/errors"
-
- "github.com/9seconds/mtg/newantireplay"
- "github.com/9seconds/mtg/newconfig"
- "github.com/9seconds/mtg/newprotocol"
- "github.com/9seconds/mtg/newwrappers"
- )
-
- const clientProtocolHandshakeTimeout = 10 * time.Second
-
- type ClientProtocol struct {
- newprotocol.BaseProtocol
- }
-
- func (c *ClientProtocol) Handshake(socket newwrappers.StreamReadWriteCloser) (newwrappers.StreamReadWriteCloser, error) {
- fm, err := c.ReadFrame(socket)
- if err != nil {
- return nil, errors.Annotate(err, "Cannot make client handshake")
- }
-
- decHasher := sha256.New()
- decHasher.Write(fm.key()) // nolint: errcheck
- decHasher.Write(newconfig.C.Secret) // nolint: errcheck
- decryptor := makeStreamCipher(decHasher.Sum(nil), fm.iv())
-
- invertedFrame := fm.invert()
- encHasher := sha256.New()
- encHasher.Write(invertedFrame.key()) // nolint: errcheck
- encHasher.Write(newconfig.C.Secret) // nolint: errcheck
- encryptor := makeStreamCipher(encHasher.Sum(nil), invertedFrame.iv())
-
- decryptedFrame := frame{}
- decryptor.XORKeyStream(decryptedFrame.bytes(), fm.bytes())
-
- magic := decryptedFrame.magic()
- switch {
- case bytes.Equal(magic, newprotocol.ConnectionTagAbridged):
- c.ConnectionType = newprotocol.ConnectionTypeAbridged
- case bytes.Equal(magic, newprotocol.ConnectionTagIntermediate):
- c.ConnectionType = newprotocol.ConnectionTypeIntermediate
- case bytes.Equal(magic, newprotocol.ConnectionTagSecure):
- c.ConnectionType = newprotocol.ConnectionTypeSecure
- default:
- return nil, errors.New("Unknown connection type")
- }
-
- c.ConnectionProtocol = newprotocol.ConnectionProtocolIPv4
- if socket.LocalAddr().IP.To4() == nil {
- c.ConnectionProtocol = newprotocol.ConnectionProtocolIPv6
- }
-
- buf := bytes.NewReader(decryptedFrame.dc())
- if err := binary.Read(buf, binary.LittleEndian, &c.DC); err != nil {
- c.DC = 1
- }
-
- antiReplayKey := decryptedFrame.unique()
- if newantireplay.Has(antiReplayKey) {
- return nil, errors.New("Replay attack is detected")
- }
- newantireplay.Add(antiReplayKey)
-
- return newwrappers.NewObfuscated2(socket, encryptor, decryptor), nil
- }
-
- func (c *ClientProtocol) ReadFrame(socket newwrappers.StreamReader) (fm frame, err error) {
- if _, err := io.ReadFull(handshakeReader{socket}, fm.bytes()); err != nil {
- err = errors.Annotate(err, "Cannot extract obfuscated2 frame")
- }
- return
- }
-
- type handshakeReader struct {
- parent newwrappers.StreamReader
- }
-
- func (h handshakeReader) Read(p []byte) (int, error) {
- return h.parent.ReadTimeout(p, clientProtocolHandshakeTimeout)
- }
-
- func makeStreamCipher(key, iv []byte) cipher.Stream {
- block, _ := aes.NewCipher(key) // nolint: gosec
- return cipher.NewCTR(block, iv)
- }
|