From 00403e3a948d1fc43aeb91b4d3bc9453f5df9c37 Mon Sep 17 00:00:00 2001 From: 9seconds Date: Thu, 12 Mar 2026 19:11:39 +0100 Subject: [PATCH] Remove old faketls package --- mtglib/internal/faketls/client_hello.go | 134 ------------ .../faketls/client_hello_fuzz_test.go | 21 -- mtglib/internal/faketls/client_hello_test.go | 191 ------------------ mtglib/internal/faketls/conn.go | 72 ------- mtglib/internal/faketls/conn_test.go | 153 -------------- mtglib/internal/faketls/init.go | 59 ------ mtglib/internal/faketls/record/init.go | 84 -------- mtglib/internal/faketls/record/init_test.go | 79 -------- mtglib/internal/faketls/record/pools.go | 20 -- mtglib/internal/faketls/record/record.go | 86 -------- mtglib/internal/faketls/record/record_test.go | 110 ---------- .../record/testdata/05eb6b71f87b6802.json | 6 - .../record/testdata/4eef4abc15b206b6.json | 6 - .../record/testdata/736f358216afe91f.json | 6 - .../record/testdata/8405d94222bd0b6a.json | 6 - .../record/testdata/9036f76e517f0cd1.json | 6 - .../record/testdata/9244766a0fe4a02a.json | 6 - .../record/testdata/9255c73d3de76e7b.json | 6 - .../record/testdata/aeb65b9924315cf8.json | 6 - .../record/testdata/b0acd44296056b54.json | 6 - .../record/testdata/c0545a13fd9a3fa3.json | 6 - .../record/testdata/f083f4501668b759.json | 6 - .../record/testdata/f5696bcdffd11706.json | 6 - .../client-hello-bad-fa2e46cdb33e2a1b.json | 8 - .../client-hello-ok-19dfe38384b9884b.json | 8 - .../client-hello-ok-48f8a72a56f3174a.json | 8 - .../client-hello-ok-651054256093c6cd.json | 8 - .../client-hello-ok-79d01ef18a9d2621.json | 8 - .../client-hello-ok-7a5569f05b118145.json | 8 - mtglib/internal/faketls/welcome.go | 91 --------- mtglib/internal/faketls/welcome_test.go | 82 -------- 31 files changed, 1302 deletions(-) delete mode 100644 mtglib/internal/faketls/client_hello.go delete mode 100644 mtglib/internal/faketls/client_hello_fuzz_test.go delete mode 100644 mtglib/internal/faketls/client_hello_test.go delete mode 100644 mtglib/internal/faketls/conn.go delete mode 100644 mtglib/internal/faketls/conn_test.go delete mode 100644 mtglib/internal/faketls/init.go delete mode 100644 mtglib/internal/faketls/record/init.go delete mode 100644 mtglib/internal/faketls/record/init_test.go delete mode 100644 mtglib/internal/faketls/record/pools.go delete mode 100644 mtglib/internal/faketls/record/record.go delete mode 100644 mtglib/internal/faketls/record/record_test.go delete mode 100644 mtglib/internal/faketls/record/testdata/05eb6b71f87b6802.json delete mode 100644 mtglib/internal/faketls/record/testdata/4eef4abc15b206b6.json delete mode 100644 mtglib/internal/faketls/record/testdata/736f358216afe91f.json delete mode 100644 mtglib/internal/faketls/record/testdata/8405d94222bd0b6a.json delete mode 100644 mtglib/internal/faketls/record/testdata/9036f76e517f0cd1.json delete mode 100644 mtglib/internal/faketls/record/testdata/9244766a0fe4a02a.json delete mode 100644 mtglib/internal/faketls/record/testdata/9255c73d3de76e7b.json delete mode 100644 mtglib/internal/faketls/record/testdata/aeb65b9924315cf8.json delete mode 100644 mtglib/internal/faketls/record/testdata/b0acd44296056b54.json delete mode 100644 mtglib/internal/faketls/record/testdata/c0545a13fd9a3fa3.json delete mode 100644 mtglib/internal/faketls/record/testdata/f083f4501668b759.json delete mode 100644 mtglib/internal/faketls/record/testdata/f5696bcdffd11706.json delete mode 100644 mtglib/internal/faketls/testdata/client-hello-bad-fa2e46cdb33e2a1b.json delete mode 100644 mtglib/internal/faketls/testdata/client-hello-ok-19dfe38384b9884b.json delete mode 100644 mtglib/internal/faketls/testdata/client-hello-ok-48f8a72a56f3174a.json delete mode 100644 mtglib/internal/faketls/testdata/client-hello-ok-651054256093c6cd.json delete mode 100644 mtglib/internal/faketls/testdata/client-hello-ok-79d01ef18a9d2621.json delete mode 100644 mtglib/internal/faketls/testdata/client-hello-ok-7a5569f05b118145.json delete mode 100644 mtglib/internal/faketls/welcome.go delete mode 100644 mtglib/internal/faketls/welcome_test.go diff --git a/mtglib/internal/faketls/client_hello.go b/mtglib/internal/faketls/client_hello.go deleted file mode 100644 index 0e5e5b4..0000000 --- a/mtglib/internal/faketls/client_hello.go +++ /dev/null @@ -1,134 +0,0 @@ -package faketls - -import ( - "crypto/hmac" - "crypto/sha256" - "crypto/subtle" - "encoding/binary" - "fmt" - "time" - - "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record" -) - -type ClientHello struct { - Time time.Time - Random [RandomLen]byte - SessionID []byte - Host string - CipherSuite uint16 -} - -func (c ClientHello) Valid(hostname string, tolerateTimeSkewness time.Duration) error { - if c.Host != "" && c.Host != hostname { - return fmt.Errorf("incorrect hostname %s", hostname) - } - - now := time.Now() - - timeDiff := now.Sub(c.Time) - if timeDiff < 0 { - timeDiff = -timeDiff - } - - if timeDiff > tolerateTimeSkewness { - return fmt.Errorf("incorrect timestamp. got=%d, now=%d, diff=%s", - c.Time.Unix(), now.Unix(), timeDiff.String()) - } - - return nil -} - -func ParseClientHello(secret, handshake []byte) (ClientHello, error) { - hello := ClientHello{} - - if len(handshake) < ClientHelloMinLen { - return hello, fmt.Errorf("lengh of handshake is too small: %d", len(handshake)) - } - - if handshake[0] != HandshakeTypeClient { - return hello, fmt.Errorf("unknown handshake type %#x", handshake[0]) - } - - handshakeSizeBytes := [4]byte{0, handshake[1], handshake[2], handshake[3]} - handshakeLength := binary.BigEndian.Uint32(handshakeSizeBytes[:]) - - if len(handshake)-4 != int(handshakeLength) { - return hello, - fmt.Errorf("incorrect handshake size. manifested=%d, real=%d", - handshakeLength, len(handshake)-4) - } - - copy(hello.Random[:], handshake[ClientHelloRandomOffset:]) - copy(handshake[ClientHelloRandomOffset:], clientHelloEmptyRandom) - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - rec.Type = record.TypeHandshake - rec.Version = record.Version10 - rec.Payload.Write(handshake) - - // mac is calculated for the whole record, not only - // for the payload part - mac := hmac.New(sha256.New, secret) - rec.Dump(mac) //nolint: errcheck - - computedRandom := mac.Sum(nil) - - for i := range RandomLen { - computedRandom[i] ^= hello.Random[i] - } - - if subtle.ConstantTimeCompare(clientHelloEmptyRandom[:RandomLen-4], computedRandom[:RandomLen-4]) != 1 { - return hello, ErrBadDigest - } - - timestamp := int64(binary.LittleEndian.Uint32(computedRandom[RandomLen-4:])) - hello.Time = time.Unix(timestamp, 0) - - parseSessionID(&hello, handshake) - parseCipherSuite(&hello, handshake) - parseSNI(&hello, handshake) - - return hello, nil -} - -func parseSessionID(hello *ClientHello, handshake []byte) { - hello.SessionID = make([]byte, handshake[ClientHelloSessionIDOffset]) - copy(hello.SessionID, handshake[ClientHelloSessionIDOffset+1:]) -} - -func parseCipherSuite(hello *ClientHello, handshake []byte) { - cipherSuiteOffset := ClientHelloSessionIDOffset + len(hello.SessionID) + 3 - hello.CipherSuite = binary.BigEndian.Uint16(handshake[cipherSuiteOffset : cipherSuiteOffset+2]) -} - -func parseSNI(hello *ClientHello, handshake []byte) { - cipherSuiteOffset := ClientHelloSessionIDOffset + len(hello.SessionID) + 1 - handshake = handshake[cipherSuiteOffset:] - - cipherSuiteLength := binary.BigEndian.Uint16(handshake[:2]) - handshake = handshake[2+cipherSuiteLength:] - - compressionMethodsLength := int(handshake[0]) - handshake = handshake[1+compressionMethodsLength:] - - extensionsLength := binary.BigEndian.Uint16(handshake[:2]) - handshake = handshake[2 : 2+extensionsLength] - - for len(handshake) > 0 { - if binary.BigEndian.Uint16(handshake[:2]) != ExtensionSNI { - extensionsLength := binary.BigEndian.Uint16(handshake[2:4]) - handshake = handshake[4+extensionsLength:] - - continue - } - - hostnameLength := binary.BigEndian.Uint16(handshake[7:9]) - handshake = handshake[9:] - hello.Host = string(handshake[:int(hostnameLength)]) - - return - } -} diff --git a/mtglib/internal/faketls/client_hello_fuzz_test.go b/mtglib/internal/faketls/client_hello_fuzz_test.go deleted file mode 100644 index 84db20d..0000000 --- a/mtglib/internal/faketls/client_hello_fuzz_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package faketls_test - -import ( - "testing" - - "github.com/9seconds/mtg/v2/mtglib/internal/faketls" - "github.com/stretchr/testify/require" -) - -var FuzzClientHelloSecret = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - -func FuzzClientHello(f *testing.F) { - f.Add([]byte{1, 2, 3}) - - f.Fuzz(func(t *testing.T, frame []byte) { - _, err := faketls.ParseClientHello(FuzzClientHelloSecret, frame) - - // a probability of having != err is almost negligible - require.Error(t, err) - }) -} diff --git a/mtglib/internal/faketls/client_hello_test.go b/mtglib/internal/faketls/client_hello_test.go deleted file mode 100644 index 7c9446e..0000000 --- a/mtglib/internal/faketls/client_hello_test.go +++ /dev/null @@ -1,191 +0,0 @@ -package faketls_test - -import ( - "encoding/base64" - "encoding/json" - "os" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/9seconds/mtg/v2/mtglib" - "github.com/9seconds/mtg/v2/mtglib/internal/faketls" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -type ClientHelloSnapshot struct { - Time int `json:"time"` - Random string `json:"random"` - SessionID string `json:"sessionId"` - Host string `json:"host"` - CipherSuite int `json:"cipherSuite"` - Full string `json:"full"` -} - -func (c ClientHelloSnapshot) GetTime() time.Time { - return time.Unix(int64(c.Time), 0) -} - -func (c ClientHelloSnapshot) GetRandom() []byte { - data, _ := base64.StdEncoding.DecodeString(c.Random) - - return data -} - -func (c ClientHelloSnapshot) GetSessionID() []byte { - data, _ := base64.StdEncoding.DecodeString(c.SessionID) - - return data -} - -func (c ClientHelloSnapshot) GetHost() string { - return c.Host -} - -func (c ClientHelloSnapshot) GetCipherSuite() uint16 { - return uint16(c.CipherSuite) -} - -func (c ClientHelloSnapshot) GetFull() []byte { - data, _ := base64.StdEncoding.DecodeString(c.Full) - - return data -} - -type ClientHelloTestSuite struct { - suite.Suite - - secret mtglib.Secret -} - -func (suite *ClientHelloTestSuite) SetupSuite() { - parsed, err := mtglib.ParseSecret("ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d") - if err != nil { - panic(err) - } - - suite.secret = parsed -} - -func (suite *ClientHelloTestSuite) TestEmptyHandshake() { - _, err := faketls.ParseClientHello(suite.secret.Key[:], nil) - suite.Error(err) -} - -func (suite *ClientHelloTestSuite) TestIncorrectHandshakeType() { - data := make([]byte, 1024) - data[0] = 0x02 - - _, err := faketls.ParseClientHello(suite.secret.Key[:], data) - suite.Error(err) -} - -func (suite *ClientHelloTestSuite) TestIncorrectLength() { - data := make([]byte, 1024) - data[0] = 0x01 - data[1] = 0xff - data[2] = 0xff - - _, err := faketls.ParseClientHello(suite.secret.Key[:], data) - suite.Error(err) -} - -func (suite *ClientHelloTestSuite) TestSnapshotOk() { - files, err := os.ReadDir("testdata") - suite.NoError(err) - - testData := []string{} - - for _, v := range files { - if strings.HasPrefix(v.Name(), "client-hello-ok") { - testData = append(testData, v.Name()) - } - } - - for _, name := range testData { - path := filepath.Join("testdata", name) - - suite.T().Run(name, func(t *testing.T) { - fileData, err := os.ReadFile(path) - assert.NoError(t, err) - - snapshot := &ClientHelloSnapshot{} - assert.NoError(t, json.Unmarshal(fileData, snapshot)) - - hello, err := faketls.ParseClientHello(suite.secret.Key[:], snapshot.GetFull()) - assert.NoError(t, err) - assert.WithinDuration(t, snapshot.GetTime(), hello.Time, time.Second) - assert.Equal(t, snapshot.GetRandom(), hello.Random[:]) - assert.Equal(t, snapshot.GetSessionID(), hello.SessionID) - assert.Equal(t, snapshot.GetHost(), hello.Host) - assert.Equal(t, snapshot.GetCipherSuite(), hello.CipherSuite) - }) - } -} - -func (suite *ClientHelloTestSuite) TestSnapshotBad() { - files, err := os.ReadDir("testdata") - suite.NoError(err) - - testData := []string{} - - for _, v := range files { - if strings.HasPrefix(v.Name(), "client-hello-bad") { - testData = append(testData, v.Name()) - } - } - - for _, name := range testData { - path := filepath.Join("testdata", name) - - suite.T().Run(name, func(t *testing.T) { - fileData, err := os.ReadFile(path) - assert.NoError(t, err) - - snapshot := &ClientHelloSnapshot{} - assert.NoError(t, json.Unmarshal(fileData, snapshot)) - - _, err = faketls.ParseClientHello(suite.secret.Key[:], snapshot.GetFull()) - assert.Error(t, err) - }) - } -} - -func (suite *ClientHelloTestSuite) TestValidateHostname() { - hello := faketls.ClientHello{ - Time: time.Now(), - } - suite.NoError(hello.Valid("hostname", time.Second)) - - hello.Host = "hostname" - suite.Error(hello.Valid("hostname2", time.Second)) - suite.NoError(hello.Valid("hostname", time.Second)) -} - -func (suite *ClientHelloTestSuite) TestValidateTime() { - testData := []time.Duration{ - -2 * time.Second, - 2 * time.Second, - } - - for _, v := range testData { - value := v - - suite.T().Run(value.String(), func(t *testing.T) { - hello := faketls.ClientHello{ - Host: "hostname", - Time: time.Now().Add(value), - } - suite.Error(hello.Valid("hostname", 500*time.Millisecond)) - suite.Error(hello.Valid("hostname", time.Second)) - suite.NoError(hello.Valid("hostname", 3*time.Second)) - }) - } -} - -func TestClientHello(t *testing.T) { - t.Parallel() - suite.Run(t, &ClientHelloTestSuite{}) -} diff --git a/mtglib/internal/faketls/conn.go b/mtglib/internal/faketls/conn.go deleted file mode 100644 index 2d04978..0000000 --- a/mtglib/internal/faketls/conn.go +++ /dev/null @@ -1,72 +0,0 @@ -package faketls - -import ( - "bytes" - "fmt" - "math/rand/v2" - - "github.com/9seconds/mtg/v2/essentials" - "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record" -) - -type Conn struct { - essentials.Conn - - readBuffer bytes.Buffer -} - -func (c *Conn) Read(p []byte) (int, error) { - if n, _ := c.readBuffer.Read(p); n > 0 { - return n, nil - } - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - for { - if err := rec.Read(c.Conn); err != nil { - return 0, err //nolint: wrapcheck - } - - switch rec.Type { //nolint: exhaustive - case record.TypeApplicationData: - rec.Payload.WriteTo(&c.readBuffer) //nolint: errcheck - - return c.readBuffer.Read(p) //nolint: wrapcheck - case record.TypeChangeCipherSpec: - default: - return 0, fmt.Errorf("unsupported record type %v", rec.Type) - } - } -} - -func (c *Conn) Write(p []byte) (int, error) { - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - rec.Type = record.TypeApplicationData - rec.Version = record.Version12 - - written := 0 - - for len(p) > 0 { - chunkSize := rand.IntN(record.TLSMaxRecordSize) - if chunkSize > len(p) || chunkSize == 0 { - chunkSize = len(p) - } - - rec.Payload.Reset() - rec.Payload.Write(p[:chunkSize]) - - err := rec.Dump(c.Conn) - written += chunkSize - - if err != nil { - return written, err - } - - p = p[chunkSize:] - } - - return written, nil -} diff --git a/mtglib/internal/faketls/conn_test.go b/mtglib/internal/faketls/conn_test.go deleted file mode 100644 index 29a8c0d..0000000 --- a/mtglib/internal/faketls/conn_test.go +++ /dev/null @@ -1,153 +0,0 @@ -package faketls_test - -import ( - "bytes" - "crypto/rand" - "errors" - "io" - "testing" - - "github.com/9seconds/mtg/v2/internal/testlib" - "github.com/9seconds/mtg/v2/mtglib/internal/faketls" - "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/suite" -) - -type ConnMock struct { - testlib.EssentialsConnMock - - readBuffer bytes.Buffer - writeBuffer bytes.Buffer -} - -func (m *ConnMock) Read(p []byte) (int, error) { - m.Called(p) - - return m.readBuffer.Read(p) //nolint: wrapcheck -} - -func (m *ConnMock) Write(p []byte) (int, error) { - m.Called(p) - - return m.writeBuffer.Write(p) //nolint: wrapcheck -} - -type ConnTestSuite struct { - suite.Suite - - connMock *ConnMock - c *faketls.Conn -} - -func (suite *ConnTestSuite) SetupTest() { - suite.connMock = &ConnMock{} - suite.c = &faketls.Conn{ - Conn: suite.connMock, - } -} - -func (suite *ConnTestSuite) TearDownTest() { - suite.connMock.AssertExpectations(suite.T()) -} - -func (suite *ConnTestSuite) TestRead() { - suite.connMock.On("Read", mock.Anything).Return(0, nil) - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - rec.Type = record.TypeChangeCipherSpec - rec.Version = record.Version12 - - rec.Payload.WriteByte(0x01) - rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck - rec.Reset() - - rec.Type = record.TypeApplicationData - rec.Version = record.Version12 - - rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) - rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck - - resultBuffer := &bytes.Buffer{} - buf := make([]byte, 2) - - for { - n, err := suite.c.Read(buf) - if errors.Is(err, io.EOF) { - break - } - - resultBuffer.Write(buf[:n]) - } - - suite.Equal([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, resultBuffer.Bytes()) -} - -func (suite *ConnTestSuite) TestReadUnexpected() { - suite.connMock.On("Read", mock.Anything).Return(0, nil) - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - rec.Type = record.TypeChangeCipherSpec - rec.Version = record.Version12 - - rec.Payload.WriteByte(0x01) - rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck - rec.Reset() - - rec.Type = record.TypeHandshake - rec.Version = record.Version12 - - rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) - rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck - - buf := make([]byte, 2) - - for { - _, err := suite.c.Read(buf) - - switch { - case err == nil: - case errors.Is(err, io.EOF): - suite.FailNow("unexpected to finish") - default: - return - } - } -} - -func (suite *ConnTestSuite) TestWrite() { - suite.connMock.On("Write", mock.Anything).Return(0, nil) - - dataToRec := make([]byte, record.TLSMaxRecordSize*2) - rand.Read(dataToRec) //nolint: staticcheck, errcheck - - n, err := suite.c.Write(dataToRec) - suite.NoError(err) - suite.Equal(len(dataToRec), n) - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - buf := &bytes.Buffer{} - - for { - if err := rec.Read(&suite.connMock.writeBuffer); err != nil { - break - } - - suite.Equal(record.TypeApplicationData, rec.Type) - suite.Equal(record.Version12, rec.Version) - rec.Payload.WriteTo(buf) //nolint: errcheck - } - - suite.Equal(dataToRec, buf.Bytes()) -} - -func TestConn(t *testing.T) { - t.Parallel() - suite.Run(t, &ConnTestSuite{}) -} diff --git a/mtglib/internal/faketls/init.go b/mtglib/internal/faketls/init.go deleted file mode 100644 index b514b21..0000000 --- a/mtglib/internal/faketls/init.go +++ /dev/null @@ -1,59 +0,0 @@ -package faketls - -import ( - "bytes" - "errors" -) - -const ( - // RandomLen defines a size of the random digest in TLS Hellos. - RandomLen = 32 - - // ClientHelloRandomOffset is an offset in ClientHello record where - // random digest is started. - ClientHelloRandomOffset = 6 - - // ClientHelloSessionIDOffset is an offset in ClientHello record where - // SessionID is started. - ClientHelloSessionIDOffset = ClientHelloRandomOffset + RandomLen - - // ClientHelloMinLen is a minimal possible length of - // ClientHello record. - ClientHelloMinLen = 6 - - // WelcomePacketRandomOffset is an offset of random in ServerHello - // packet (including record envelope). - WelcomePacketRandomOffset = 11 - - // HandshakeTypeClient is a value representing a client handshake. - HandshakeTypeClient = 0x01 - - // HandshakeTypeServer is a value representing a server handshake. - HandshakeTypeServer = 0x02 - - // ChangeCipherValue is a value representing a change cipher - // specification record. - ChangeCipherValue = 0x01 - - // ExtensionSNI is a value for TLS extension 'SNI'. - ExtensionSNI = 0x00 -) - -var ( - // ErrBadDigest is returned if given TLS Client Hello mismatches with a - // derived one. - ErrBadDigest = errors.New("bad digest") - - serverHelloSuffix = []byte{ - 0x00, // no compression - 0x00, 0x2e, // 46 bytes of data - 0x00, 0x2b, // Extension - Supported Versions - 0x00, 0x02, // 2 bytes are following - 0x03, 0x04, // TLS 1.3 - 0x00, 0x33, // Extension - Key Share - 0x00, 0x24, // 36 bytes - 0x00, 0x1d, // x25519 curve - 0x00, 0x20, // 32 bytes of key - } - clientHelloEmptyRandom = bytes.Repeat([]byte{0}, RandomLen) -) diff --git a/mtglib/internal/faketls/record/init.go b/mtglib/internal/faketls/record/init.go deleted file mode 100644 index 9195113..0000000 --- a/mtglib/internal/faketls/record/init.go +++ /dev/null @@ -1,84 +0,0 @@ -package record - -import "fmt" - -const TLSMaxRecordSize = 65535 // max uint16 - -type Type uint8 - -const ( - // TypeChangeCipherSpec defines a byte value of the TLS record when a - // peer wants to change a specifications of the chosen cipher. - TypeChangeCipherSpec Type = 0x14 - - // TypeHandshake defines a byte value of the TLS record when a peer - // initiates a new TLS connection and wants to make a handshake - // ceremony. - TypeHandshake Type = 0x16 - - // TypeApplicationData defines a byte value of the TLS record when a - // peer sends an user data, not a control frames. - TypeApplicationData Type = 0x17 -) - -func (t Type) String() string { - switch t { - case TypeChangeCipherSpec: - return "changeCipher(0x14)" - case TypeHandshake: - return "handshake(0x16)" - case TypeApplicationData: - return "applicationData(0x17)" - } - - return fmt.Sprintf("unknown(%#x)", byte(t)) -} - -func (t Type) Valid() error { - switch t { - case TypeChangeCipherSpec, TypeHandshake, TypeApplicationData: - return nil - } - - return fmt.Errorf("unknown type %#x", byte(t)) -} - -type Version uint16 - -const ( - // Version10 defines a TLS1.0. - Version10 Version = 769 // 0x03 0x01 - - // Version11 defines a TLS1.1. - Version11 Version = 770 // 0x03 0x02 - - // Version12 defines a TLS1.2. - Version12 Version = 771 // 0x03 0x03 - - // Version13 defines a TLS1.3. - Version13 Version = 772 // 0x03 0x04 -) - -func (v Version) String() string { - switch v { - case Version10: - return "tls1.0" - case Version11: - return "tls1.1" - case Version12: - return "tls1.2" - case Version13: - return "tls1.3" - } - - return fmt.Sprintf("tls?(%d)", uint16(v)) -} - -func (v Version) Valid() error { - switch v { - case Version10, Version11, Version12, Version13: - return nil - } - - return fmt.Errorf("unknown version %d", uint16(v)) -} diff --git a/mtglib/internal/faketls/record/init_test.go b/mtglib/internal/faketls/record/init_test.go deleted file mode 100644 index 7922777..0000000 --- a/mtglib/internal/faketls/record/init_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package record_test - -import ( - "testing" - - "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record" - "github.com/stretchr/testify/suite" -) - -type TypeTestSuite struct { - suite.Suite -} - -func (suite *TypeTestSuite) TestChangeCipherSpec() { - suite.Contains(record.TypeChangeCipherSpec.String(), "changeCipher") - suite.Contains(record.TypeChangeCipherSpec.String(), "0x14") - suite.NoError(record.TypeChangeCipherSpec.Valid()) -} - -func (suite *TypeTestSuite) TestHandshake() { - suite.Contains(record.TypeHandshake.String(), "handshake") - suite.Contains(record.TypeHandshake.String(), "0x16") - suite.NoError(record.TypeHandshake.Valid()) -} - -func (suite *TypeTestSuite) TestApplicationData() { - suite.Contains(record.TypeApplicationData.String(), "applicationData") - suite.Contains(record.TypeApplicationData.String(), "0x17") - suite.NoError(record.TypeApplicationData.Valid()) -} - -func (suite *TypeTestSuite) TestUnknown() { - value := record.Type(0x20) - - suite.Contains(value.String(), "unknown") - suite.Contains(value.String(), "0x20") - suite.Error(value.Valid()) -} - -type VersionTestSuite struct { - suite.Suite -} - -func (suite *VersionTestSuite) Test10() { - suite.Equal("tls1.0", record.Version10.String()) - suite.NoError(record.Version10.Valid()) -} - -func (suite *VersionTestSuite) Test11() { - suite.Equal("tls1.1", record.Version11.String()) - suite.NoError(record.Version11.Valid()) -} - -func (suite *VersionTestSuite) Test12() { - suite.Equal("tls1.2", record.Version12.String()) - suite.NoError(record.Version12.Valid()) -} - -func (suite *VersionTestSuite) Test13() { - suite.Equal("tls1.3", record.Version13.String()) - suite.NoError(record.Version13.Valid()) -} - -func (suite *VersionTestSuite) TestUnknown() { - value := record.Version(900) - - suite.Equal("tls?(900)", value.String()) - suite.Error(value.Valid()) -} - -func TestType(t *testing.T) { - t.Parallel() - suite.Run(t, &TypeTestSuite{}) -} - -func TestVersion(t *testing.T) { - t.Parallel() - suite.Run(t, &VersionTestSuite{}) -} diff --git a/mtglib/internal/faketls/record/pools.go b/mtglib/internal/faketls/record/pools.go deleted file mode 100644 index 4f758b7..0000000 --- a/mtglib/internal/faketls/record/pools.go +++ /dev/null @@ -1,20 +0,0 @@ -package record - -import ( - "sync" -) - -var recordPool = sync.Pool{ - New: func() any { - return &Record{} - }, -} - -func AcquireRecord() *Record { - return recordPool.Get().(*Record) //nolint: forcetypeassert -} - -func ReleaseRecord(r *Record) { - r.Reset() - recordPool.Put(r) -} diff --git a/mtglib/internal/faketls/record/record.go b/mtglib/internal/faketls/record/record.go deleted file mode 100644 index 2c8b23e..0000000 --- a/mtglib/internal/faketls/record/record.go +++ /dev/null @@ -1,86 +0,0 @@ -package record - -import ( - "bytes" - "encoding/base64" - "encoding/binary" - "fmt" - "io" -) - -type Record struct { - Type Type - Version Version - Payload bytes.Buffer -} - -func (r *Record) String() string { - return fmt.Sprintf("", - r.Type, - r.Version, - base64.StdEncoding.EncodeToString(r.Payload.Bytes())) -} - -func (r *Record) Reset() { - r.Payload.Reset() -} - -func (r *Record) Read(reader io.Reader) error { - r.Reset() - - buf := [2]byte{} - - if _, err := io.ReadFull(reader, buf[:1]); err != nil { - return fmt.Errorf("cannot read type: %w", err) - } - - r.Type = Type(buf[0]) - if err := r.Type.Valid(); err != nil { - return fmt.Errorf("invalid type: %w", err) - } - - if _, err := io.ReadFull(reader, buf[:]); err != nil { - return fmt.Errorf("cannot read version: %w", err) - } - - r.Version = Version(binary.BigEndian.Uint16(buf[:])) - if err := r.Version.Valid(); err != nil { - return fmt.Errorf("invalid version: %w", err) - } - - if _, err := io.ReadFull(reader, buf[:]); err != nil { - return fmt.Errorf("cannot read payload length: %w", err) - } - - length := int64(binary.BigEndian.Uint16(buf[:])) - if _, err := io.CopyN(&r.Payload, reader, length); err != nil { - return fmt.Errorf("cannot read payload: %w", err) - } - - return nil -} - -func (r *Record) Dump(writer io.Writer) error { - buf := [2]byte{byte(r.Type), 0} - if _, err := writer.Write(buf[:1]); err != nil { - return fmt.Errorf("cannot dump record type: %w", err) - } - - binary.BigEndian.PutUint16(buf[:], uint16(r.Version)) - - if _, err := writer.Write(buf[:]); err != nil { - return fmt.Errorf("cannot dump version: %w", err) - } - - binary.BigEndian.PutUint16(buf[:], uint16(r.Payload.Len())) - - if _, err := writer.Write(buf[:]); err != nil { - return fmt.Errorf("cannot dump payload length: %w", err) - } - - if _, err := writer.Write(r.Payload.Bytes()); err != nil { - return fmt.Errorf("cannot dump record: %w", err) - } - - return nil -} diff --git a/mtglib/internal/faketls/record/record_test.go b/mtglib/internal/faketls/record/record_test.go deleted file mode 100644 index e29b5ba..0000000 --- a/mtglib/internal/faketls/record/record_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package record_test - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "os" - "path/filepath" - "testing" - - "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -type RecordTestSnapshot struct { - Type int `json:"type"` - Version int `json:"version"` - Payload string `json:"payload"` - Record string `json:"record"` -} - -func (r RecordTestSnapshot) RecordBytes() []byte { - data, _ := base64.StdEncoding.DecodeString(r.Record) - - return data -} - -func (r RecordTestSnapshot) PayloadBytes() []byte { - data, _ := base64.StdEncoding.DecodeString(r.Payload) - - return data -} - -type RecordTestSuite struct { - suite.Suite - - r *record.Record - buf *bytes.Buffer -} - -func (suite *RecordTestSuite) SetupTest() { - suite.r = record.AcquireRecord() - suite.buf = &bytes.Buffer{} -} - -func (suite *RecordTestSuite) TearDownTest() { - record.ReleaseRecord(suite.r) - suite.buf.Reset() -} - -func (suite *RecordTestSuite) TestIdempotent() { - suite.r.Type = record.TypeApplicationData - suite.r.Version = record.Version13 - - suite.r.Payload.Write([]byte{1, 2, 3}) - suite.NoError(suite.r.Dump(suite.buf)) - - suite.r.Reset() - suite.NoError(suite.r.Read(suite.buf)) - - suite.Equal(0, suite.buf.Len()) - suite.Equal(record.TypeApplicationData, suite.r.Type) - suite.Equal(record.Version13, suite.r.Version) - suite.Equal([]byte{1, 2, 3}, suite.r.Payload.Bytes()) -} - -func (suite *RecordTestSuite) TestString() { - _ = suite.r.String() -} - -func (suite *RecordTestSuite) TestSnapshot() { - files, err := os.ReadDir("testdata") - suite.NoError(err) - - testData := map[string]string{} - - for _, f := range files { - testData[f.Name()] = filepath.Join("testdata", f.Name()) - } - - for name, pathV := range testData { - path := pathV - - suite.T().Run(name, func(t *testing.T) { - data, err := os.ReadFile(path) - assert.NoError(t, err) - - snapshot := &RecordTestSnapshot{} - assert.NoError(t, json.Unmarshal(data, snapshot)) - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - assert.NoError(t, rec.Read(bytes.NewReader(snapshot.RecordBytes()))) - assert.Equal(t, snapshot.Type, int(rec.Type)) - assert.Equal(t, snapshot.Version, int(rec.Version)) - assert.Equal(t, snapshot.PayloadBytes(), rec.Payload.Bytes()) - - buf := &bytes.Buffer{} - assert.NoError(t, rec.Dump(buf)) - assert.Equal(t, snapshot.RecordBytes(), buf.Bytes()) - }) - } -} - -func TestRecord(t *testing.T) { - t.Parallel() - suite.Run(t, &RecordTestSuite{}) -} diff --git a/mtglib/internal/faketls/record/testdata/05eb6b71f87b6802.json b/mtglib/internal/faketls/record/testdata/05eb6b71f87b6802.json deleted file mode 100644 index 6cac5ae..0000000 --- a/mtglib/internal/faketls/record/testdata/05eb6b71f87b6802.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 20, - "version": 772, - "payload": "sxS+0oAyk+NBv0LLVtQOp9WSx4CweyUZPz01tQ0o4oyp8aaBl6/kMFvLq3q52KE8lCiKejLw2NxVBUkE+4izCf2gLx9qfr81opWnqJTChWzcDijvttbq9cmtDFNL+odKsS3v1/TfYEFtPsoRPrJRmOHRAnqnf49Y5Q==", - "record": "FAMEAHmzFL7SgDKT40G/QstW1A6n1ZLHgLB7JRk/PTW1DSjijKnxpoGXr+QwW8urernYoTyUKIp6MvDY3FUFSQT7iLMJ/aAvH2p+vzWilaeolMKFbNwOKO+21ur1ya0MU0v6h0qxLe/X9N9gQW0+yhE+slGY4dECeqd/j1jl" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/4eef4abc15b206b6.json b/mtglib/internal/faketls/record/testdata/4eef4abc15b206b6.json deleted file mode 100644 index 875d64f..0000000 --- a/mtglib/internal/faketls/record/testdata/4eef4abc15b206b6.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 22, - "version": 772, - "payload": "waNH223htyxCBKAb6hm0u/SK/9mhI8Ck91nfWob7QMOaIREogrDYREJH4Djcp47XrpAlEaUIDiCvoFLVJ/LK1nYs4swzfHSSl/+Aj1eqPA63XqPa8EG4FAbf0DwjwXxV9qVIhvP9b2TafKbzr4Yb5GCygzFRb/zawA==", - "record": "FgMEAHnBo0fbbeG3LEIEoBvqGbS79Ir/2aEjwKT3Wd9ahvtAw5ohESiCsNhEQkfgONynjteukCURpQgOIK+gUtUn8srWdizizDN8dJKX/4CPV6o8Drdeo9rwQbgUBt/QPCPBfFX2pUiG8/1vZNp8pvOvhhvkYLKDMVFv/NrA" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/736f358216afe91f.json b/mtglib/internal/faketls/record/testdata/736f358216afe91f.json deleted file mode 100644 index 5b322d4..0000000 --- a/mtglib/internal/faketls/record/testdata/736f358216afe91f.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 23, - "version": 769, - "payload": "jmJ0o1E5+ehAHHYAbCo4AMV03X7RSivYl250s06nD9CO44fyjaoGELz0N7IeCg1jFKcRVSCRmYYmiIY9wydn2fXOJhKif8B0BlM3qhbethYgyP+l1S8hyyETpIiOtiiiOnAJwl1D1j9OryFiJFSdRRXReIMZ4CPqPg==", - "record": "FwMBAHmOYnSjUTn56EAcdgBsKjgAxXTdftFKK9iXbnSzTqcP0I7jh/KNqgYQvPQ3sh4KDWMUpxFVIJGZhiaIhj3DJ2fZ9c4mEqJ/wHQGUzeqFt62FiDI/6XVLyHLIROkiI62KKI6cAnCXUPWP06vIWIkVJ1FFdF4gxngI+o+" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/8405d94222bd0b6a.json b/mtglib/internal/faketls/record/testdata/8405d94222bd0b6a.json deleted file mode 100644 index 16a4ba7..0000000 --- a/mtglib/internal/faketls/record/testdata/8405d94222bd0b6a.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 22, - "version": 769, - "payload": "hBnpBnNUdlqe/rKXa7Judcz79u7AkUgSGOycn8EqvbkZpVxnI31rNOvAsPZqG+GF7DWJ3R7H2ETmFmrpnyyng32MjSs1jptmV1oAs63zTADD7sVipgid9AJHwfl4CrC3FIQr43IPMYd29JPOl5bqu/SfrgI16PBiJw==", - "record": "FgMBAHmEGekGc1R2Wp7+spdrsm51zPv27sCRSBIY7JyfwSq9uRmlXGcjfWs068Cw9mob4YXsNYndHsfYROYWaumfLKeDfYyNKzWOm2ZXWgCzrfNMAMPuxWKmCJ30AkfB+XgKsLcUhCvjcg8xh3b0k86Xluq79J+uAjXo8GIn" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/9036f76e517f0cd1.json b/mtglib/internal/faketls/record/testdata/9036f76e517f0cd1.json deleted file mode 100644 index 5d60155..0000000 --- a/mtglib/internal/faketls/record/testdata/9036f76e517f0cd1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 23, - "version": 770, - "payload": "Vm/C+DO56czlbtR915aHzsugSyDtp8CtojF9w1jKY0efyyfcLrNuhNg/pZm3gQ7v2BBbL1UJ97v/RIjST+5gRIfg3bBN1BE9hkf+N2AYY2lHLi0yeInHB0zFWPeHscsDopDFadIi5KtC8HvbEMuK+kK8POVk5tN9UQ==", - "record": "FwMCAHlWb8L4M7npzOVu1H3XlofOy6BLIO2nwK2iMX3DWMpjR5/LJ9wus26E2D+lmbeBDu/YEFsvVQn3u/9EiNJP7mBEh+DdsE3UET2GR/43YBhjaUcuLTJ4iccHTMVY94exywOikMVp0iLkq0Lwe9sQy4r6Qrw85WTm031R" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/9244766a0fe4a02a.json b/mtglib/internal/faketls/record/testdata/9244766a0fe4a02a.json deleted file mode 100644 index 459986b..0000000 --- a/mtglib/internal/faketls/record/testdata/9244766a0fe4a02a.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 22, - "version": 770, - "payload": "ajPzpsgk4gwm2stRQKbllvKRLdI7vmyaj1uxEJ/kKoQnQSPumdDNKD618U2Cq6PVd0/b+9YtH67Uzx1QxtpKuby5fUXqw06WUuDAQsmjq7F26EkE5FND6rQUjUPC+e1U0dF4TQzOUSS4IAkFQPAaVehUVTRxVWa/0g==", - "record": "FgMCAHlqM/OmyCTiDCbay1FApuWW8pEt0ju+bJqPW7EQn+QqhCdBI+6Z0M0oPrXxTYKro9V3T9v71i0frtTPHVDG2kq5vLl9RerDTpZS4MBCyaOrsXboSQTkU0PqtBSNQ8L57VTR0XhNDM5RJLggCQVA8BpV6FRVNHFVZr/S" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/9255c73d3de76e7b.json b/mtglib/internal/faketls/record/testdata/9255c73d3de76e7b.json deleted file mode 100644 index e49ea0a..0000000 --- a/mtglib/internal/faketls/record/testdata/9255c73d3de76e7b.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 20, - "version": 771, - "payload": "d1Hiv1NYVgEDR9mtJyv9j8mg3dWqfUpeKfOsL+jzSDfVIxeDiJZFLDT50TjNW44/yEOVEX/Y/pk+wnc7E8aCEiwGwAvB+Insw1UCJ2ejt689VWLo2u4klGVKTHuOpUvdGVTc7Lo4FAt91KQSPLYB5iqxomjEv5e3Vg==", - "record": "FAMDAHl3UeK/U1hWAQNH2a0nK/2PyaDd1ap9Sl4p86wv6PNIN9UjF4OIlkUsNPnROM1bjj/IQ5URf9j+mT7CdzsTxoISLAbAC8H4iezDVQInZ6O3rz1VYuja7iSUZUpMe46lS90ZVNzsujgUC33UpBI8tgHmKrGiaMS/l7dW" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/aeb65b9924315cf8.json b/mtglib/internal/faketls/record/testdata/aeb65b9924315cf8.json deleted file mode 100644 index 7eac0da..0000000 --- a/mtglib/internal/faketls/record/testdata/aeb65b9924315cf8.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 23, - "version": 771, - "payload": "wbdU1CbrzuAJDsh6CFjGyE+AFArJj/Wmsa2wtDyW0kRuE2vUO8gg+nXkg0kkoz0WnvQEOdaswfJIaVrloD78yoyeQVfBB+VUP/63vqn60v5ccaQEn0jLdxgLjiTAxKDQDxCTMRoLnFE2ZZf28zw+HfqpIxiOZs8LhQ==", - "record": "FwMDAHnBt1TUJuvO4AkOyHoIWMbIT4AUCsmP9aaxrbC0PJbSRG4Ta9Q7yCD6deSDSSSjPRae9AQ51qzB8khpWuWgPvzKjJ5BV8EH5VQ//re+qfrS/lxxpASfSMt3GAuOJMDEoNAPEJMxGgucUTZll/bzPD4d+qkjGI5mzwuF" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/b0acd44296056b54.json b/mtglib/internal/faketls/record/testdata/b0acd44296056b54.json deleted file mode 100644 index 3fffda7..0000000 --- a/mtglib/internal/faketls/record/testdata/b0acd44296056b54.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 23, - "version": 772, - "payload": "qqnBMb1Af3zZt4DPHpVRuIiON9ODGJUNFicFjranORh67L/HI4D6HnHyycZFUSBOw2FjMBF6UialY8snOYaRKrQmQzuUNg1Ztq7yAZ+Lgj3TBarR6OMlYhEAY0Px9Xv1UuJ0YcvQx33gdM1skJ5HBR3yZvEKNJV1LA==", - "record": "FwMEAHmqqcExvUB/fNm3gM8elVG4iI4304MYlQ0WJwWOtqc5GHrsv8cjgPoecfLJxkVRIE7DYWMwEXpSJqVjyyc5hpEqtCZDO5Q2DVm2rvIBn4uCPdMFqtHo4yViEQBjQ/H1e/VS4nRhy9DHfeB0zWyQnkcFHfJm8Qo0lXUs" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/c0545a13fd9a3fa3.json b/mtglib/internal/faketls/record/testdata/c0545a13fd9a3fa3.json deleted file mode 100644 index aa11362..0000000 --- a/mtglib/internal/faketls/record/testdata/c0545a13fd9a3fa3.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 20, - "version": 769, - "payload": "NEe735TuQFp7bWpFQhASas/e1XaySvus0ovXmkfCbFq334MyFHq2eDMadziXsfu/GfBjoYggvk0LgYUeoAkBNKR0dfSovjSndaqmIUonoWl+6sZObiGZkRIMwuY2q4Eaw4/iuDu/pZhjRW/iAIH+YH7cyk/1tgdJDg==", - "record": "FAMBAHk0R7vflO5AWnttakVCEBJqz97VdrJK+6zSi9eaR8JsWrffgzIUerZ4Mxp3OJex+78Z8GOhiCC+TQuBhR6gCQE0pHR19Ki+NKd1qqYhSiehaX7qxk5uIZmREgzC5jargRrDj+K4O7+lmGNFb+IAgf5gftzKT/W2B0kO" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/f083f4501668b759.json b/mtglib/internal/faketls/record/testdata/f083f4501668b759.json deleted file mode 100644 index 2518193..0000000 --- a/mtglib/internal/faketls/record/testdata/f083f4501668b759.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 22, - "version": 771, - "payload": "wrXjZrPm3OSyzO0klv6/G+z2PDloR/colS/RlWwQE31Vb2xm8YkEchDDKwlc/KPLD73qMoz3MQOQLtSLc8LhVYp+l7L9jz49yTaVKtBI5UuGbo09snsKxFCgCyYUBETKabATBQtiaEu/D8dmF4Yk/2ww4sEb8DwKLQ==", - "record": "FgMDAHnCteNms+bc5LLM7SSW/r8b7PY8OWhH9yiVL9GVbBATfVVvbGbxiQRyEMMrCVz8o8sPveoyjPcxA5Au1ItzwuFVin6Xsv2PPj3JNpUq0EjlS4ZujT2yewrEUKALJhQERMppsBMFC2JoS78Px2YXhiT/bDDiwRvwPAot" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/record/testdata/f5696bcdffd11706.json b/mtglib/internal/faketls/record/testdata/f5696bcdffd11706.json deleted file mode 100644 index 055a7a6..0000000 --- a/mtglib/internal/faketls/record/testdata/f5696bcdffd11706.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": 20, - "version": 770, - "payload": "OU5s8Sa11hpXWEarWzFlX55IZt3Eo+F4AMbQ/2RwB4rfHS/JNl8n63OR4oYs9QXw3RfCrYJuU9n6Xn+I/+7ZzAgZ0PbLSXW1PrLtttdfmhTErK90b49YEWdY9na4g++NMkKykwgXvY1hNxZIHX/qawEWJgxXUR3DdQ==", - "record": "FAMCAHk5TmzxJrXWGldYRqtbMWVfnkhm3cSj4XgAxtD/ZHAHit8dL8k2Xyfrc5Hihiz1BfDdF8Ktgm5T2fpef4j/7tnMCBnQ9stJdbU+su2211+aFMSsr3Rvj1gRZ1j2driD740yQrKTCBe9jWE3Fkgdf+prARYmDFdRHcN1" -} \ No newline at end of file diff --git a/mtglib/internal/faketls/testdata/client-hello-bad-fa2e46cdb33e2a1b.json b/mtglib/internal/faketls/testdata/client-hello-bad-fa2e46cdb33e2a1b.json deleted file mode 100644 index 68bfd38..0000000 --- a/mtglib/internal/faketls/testdata/client-hello-bad-fa2e46cdb33e2a1b.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "time": 1617181365, - "random": "XvCPc3aAbHbhRLv0kUmy6BfPZOGvsused5/HNsKXEPs=", - "sessionId": "St2BZ2uHMFn3B2trD1jfdtpjoJOOg6JBeLhFcyCMCq4=", - "host": "storage.googleapis.com", - "cipherSuite": 4867, - "full": "AQAB/AMDXvCPc3aAbHbhRLv0kUmy6BfPZOGvsused5/HNsKXEPsgSt2BZ2uHMFn3B2trD1jfdtpjoJOOg6JBeLhFcyCACq4ANBMDEwETAsAswCvAJMAjwArACcypwDDAL8AowCfAFMATzKgAnQCcAD0APAA1AC/ACMASAAoBAAF//wEAAQAAAAAbABkAABZzdG9yYWdlLmdvb2dsZWFwaXMuY29tABcAAAANABgAFgQDCAQEAQUDAgMIBQgFBQEIBgYBAgEABQAFANAAAAAzdAAAABIAAAAQADAALgJoMgVoMi0xNgVoMi0xNQVoMi0xNAhzcGR5LzMuMQZzcGR5LzMIaHR0cC8xLjEACwACAQAAMwAmACQAHQAgB/7oLx9JElIALsLJS91H2QNyU1H0osKwIUelVndsLyIALQACAQEAKwAJCAMEAwMDAgMBAAoACgAIAB0AFwAYABkAFQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" -} diff --git a/mtglib/internal/faketls/testdata/client-hello-ok-19dfe38384b9884b.json b/mtglib/internal/faketls/testdata/client-hello-ok-19dfe38384b9884b.json deleted file mode 100644 index 097df60..0000000 --- a/mtglib/internal/faketls/testdata/client-hello-ok-19dfe38384b9884b.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "time": 1617181365, - "random": "XvCPc3aAbHbhRLv0kUmy6BfPZOGvsused5/HNsKXEPs=", - "sessionId": "St2BZ2uHMFn3B2trD1jfdtpjoJOOg6JBeLhFcyCMCq4=", - "host": "storage.googleapis.com", - "cipherSuite": 4867, - "full": "AQAB/AMDXvCPc3aAbHbhRLv0kUmy6BfPZOGvsused5/HNsKXEPsgSt2BZ2uHMFn3B2trD1jfdtpjoJOOg6JBeLhFcyCMCq4ANBMDEwETAsAswCvAJMAjwArACcypwDDAL8AowCfAFMATzKgAnQCcAD0APAA1AC/ACMASAAoBAAF//wEAAQAAAAAbABkAABZzdG9yYWdlLmdvb2dsZWFwaXMuY29tABcAAAANABgAFgQDCAQEAQUDAgMIBQgFBQEIBgYBAgEABQAFAQAAAAAzdAAAABIAAAAQADAALgJoMgVoMi0xNgVoMi0xNQVoMi0xNAhzcGR5LzMuMQZzcGR5LzMIaHR0cC8xLjEACwACAQAAMwAmACQAHQAgB/7oLx9JElIALsLJS91H2QNyU1H0osKwIUelVndsLyIALQACAQEAKwAJCAMEAwMDAgMBAAoACgAIAB0AFwAYABkAFQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" -} diff --git a/mtglib/internal/faketls/testdata/client-hello-ok-48f8a72a56f3174a.json b/mtglib/internal/faketls/testdata/client-hello-ok-48f8a72a56f3174a.json deleted file mode 100644 index f4fe585..0000000 --- a/mtglib/internal/faketls/testdata/client-hello-ok-48f8a72a56f3174a.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "time": 1617181352, - "random": "oYEu33jl+zQbUKMtQbV1OHB0gXIM2y2aq9iY0QX12os=", - "sessionId": "FGqA3ZFYrSlj//xl7lammNn64K9/MK2mQ3HJUGvP+8g=", - "host": "storage.googleapis.com", - "cipherSuite": 4867, - "full": "AQAB/AMDoYEu33jl+zQbUKMtQbV1OHB0gXIM2y2aq9iY0QX12osgFGqA3ZFYrSlj//xl7lammNn64K9/MK2mQ3HJUGvP+8gANBMDEwETAsAswCvAJMAjwArACcypwDDAL8AowCfAFMATzKgAnQCcAD0APAA1AC/ACMASAAoBAAF//wEAAQAAAAAbABkAABZzdG9yYWdlLmdvb2dsZWFwaXMuY29tABcAAAANABgAFgQDCAQEAQUDAgMIBQgFBQEIBgYBAgEABQAFAQAAAAAzdAAAABIAAAAQADAALgJoMgVoMi0xNgVoMi0xNQVoMi0xNAhzcGR5LzMuMQZzcGR5LzMIaHR0cC8xLjEACwACAQAAMwAmACQAHQAga6CocpFP8Qd4YCFR9pkaCr97po2ALj0P5nI9Nnb3UWMALQACAQEAKwAJCAMEAwMDAgMBAAoACgAIAB0AFwAYABkAFQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" -} diff --git a/mtglib/internal/faketls/testdata/client-hello-ok-651054256093c6cd.json b/mtglib/internal/faketls/testdata/client-hello-ok-651054256093c6cd.json deleted file mode 100644 index 432f170..0000000 --- a/mtglib/internal/faketls/testdata/client-hello-ok-651054256093c6cd.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "time": 1617181352, - "random": "5V5sSprk/tFIgy+x1BeKNGhLlFkqfggLpgN7GYOA1ro=", - "sessionId": "jxr4d6PXPDk+Lwx3WUp9wvj8TGlOxEdrRJ0ydyJ9+H8=", - "host": "storage.googleapis.com", - "cipherSuite": 4867, - "full": "AQAB/AMD5V5sSprk/tFIgy+x1BeKNGhLlFkqfggLpgN7GYOA1rogjxr4d6PXPDk+Lwx3WUp9wvj8TGlOxEdrRJ0ydyJ9+H8ANBMDEwETAsAswCvAJMAjwArACcypwDDAL8AowCfAFMATzKgAnQCcAD0APAA1AC/ACMASAAoBAAF//wEAAQAAAAAbABkAABZzdG9yYWdlLmdvb2dsZWFwaXMuY29tABcAAAANABgAFgQDCAQEAQUDAgMIBQgFBQEIBgYBAgEABQAFAQAAAAAzdAAAABIAAAAQADAALgJoMgVoMi0xNgVoMi0xNQVoMi0xNAhzcGR5LzMuMQZzcGR5LzMIaHR0cC8xLjEACwACAQAAMwAmACQAHQAgrulAaqUdKeVYM0F+pu6on/h6LBpOyzOKG4xFIKcoFk4ALQACAQEAKwAJCAMEAwMDAgMBAAoACgAIAB0AFwAYABkAFQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" -} diff --git a/mtglib/internal/faketls/testdata/client-hello-ok-79d01ef18a9d2621.json b/mtglib/internal/faketls/testdata/client-hello-ok-79d01ef18a9d2621.json deleted file mode 100644 index 0faafd8..0000000 --- a/mtglib/internal/faketls/testdata/client-hello-ok-79d01ef18a9d2621.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "time": 1617181365, - "random": "8xljlOhkDlkafEF5vu3e1r3fWvh8AX548wC3hLZ3szQ=", - "sessionId": "00uvDYKnFyZFKyf3HlLwWGCOyeHsPFiU5UZ+Fs5pDAU=", - "host": "storage.googleapis.com", - "cipherSuite": 4867, - "full": "AQAB/AMD8xljlOhkDlkafEF5vu3e1r3fWvh8AX548wC3hLZ3szQg00uvDYKnFyZFKyf3HlLwWGCOyeHsPFiU5UZ+Fs5pDAUANBMDEwETAsAswCvAJMAjwArACcypwDDAL8AowCfAFMATzKgAnQCcAD0APAA1AC/ACMASAAoBAAF//wEAAQAAAAAbABkAABZzdG9yYWdlLmdvb2dsZWFwaXMuY29tABcAAAANABgAFgQDCAQEAQUDAgMIBQgFBQEIBgYBAgEABQAFAQAAAAAzdAAAABIAAAAQADAALgJoMgVoMi0xNgVoMi0xNQVoMi0xNAhzcGR5LzMuMQZzcGR5LzMIaHR0cC8xLjEACwACAQAAMwAmACQAHQAg/9P7140NtKzjyDwBf99mOy1+FjRPAPHTNQ9WxHOKpV4ALQACAQEAKwAJCAMEAwMDAgMBAAoACgAIAB0AFwAYABkAFQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" -} diff --git a/mtglib/internal/faketls/testdata/client-hello-ok-7a5569f05b118145.json b/mtglib/internal/faketls/testdata/client-hello-ok-7a5569f05b118145.json deleted file mode 100644 index 7bd1122..0000000 --- a/mtglib/internal/faketls/testdata/client-hello-ok-7a5569f05b118145.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "time": 1617181352, - "random": "zja3MLZ8WGSfsQRtPV75+tY6gbK3zKPi1Sy7SBBafg4=", - "sessionId": "qPut2yMqXa9zGLII/872SQ3d4Tfqo0uoDb7tpkRfBnA=", - "host": "storage.googleapis.com", - "cipherSuite": 4867, - "full": "AQAB/AMDzja3MLZ8WGSfsQRtPV75+tY6gbK3zKPi1Sy7SBBafg4gqPut2yMqXa9zGLII/872SQ3d4Tfqo0uoDb7tpkRfBnAANBMDEwETAsAswCvAJMAjwArACcypwDDAL8AowCfAFMATzKgAnQCcAD0APAA1AC/ACMASAAoBAAF//wEAAQAAAAAbABkAABZzdG9yYWdlLmdvb2dsZWFwaXMuY29tABcAAAANABgAFgQDCAQEAQUDAgMIBQgFBQEIBgYBAgEABQAFAQAAAAAzdAAAABIAAAAQADAALgJoMgVoMi0xNgVoMi0xNQVoMi0xNAhzcGR5LzMuMQZzcGR5LzMIaHR0cC8xLjEACwACAQAAMwAmACQAHQAgXviLRAqAYJ8xOLdlcsUhldI4Xl0g/s9+y2Qrd8raPEgALQACAQEAKwAJCAMEAwMDAgMBAAoACgAIAB0AFwAYABkAFQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" -} diff --git a/mtglib/internal/faketls/welcome.go b/mtglib/internal/faketls/welcome.go deleted file mode 100644 index e9fa85b..0000000 --- a/mtglib/internal/faketls/welcome.go +++ /dev/null @@ -1,91 +0,0 @@ -package faketls - -import ( - "bytes" - "crypto/hmac" - "crypto/rand" - "crypto/sha256" - "encoding/binary" - "io" - mrand "math/rand/v2" - - "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record" - "golang.org/x/crypto/curve25519" -) - -func SendWelcomePacket(writer io.Writer, secret []byte, clientHello ClientHello) error { - buf := &bytes.Buffer{} - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - rec.Type = record.TypeHandshake - rec.Version = record.Version12 - - generateServerHello(&rec.Payload, clientHello) - rec.Dump(buf) //nolint: errcheck - rec.Reset() - - rec.Type = record.TypeChangeCipherSpec - rec.Version = record.Version12 - rec.Payload.WriteByte(ChangeCipherValue) - - rec.Dump(buf) //nolint: errcheck - rec.Reset() - - rec.Type = record.TypeApplicationData - rec.Version = record.Version12 - - if _, err := io.CopyN(&rec.Payload, rand.Reader, int64(1024+mrand.IntN(3092))); err != nil { - panic(err) - } - - rec.Dump(buf) //nolint: errcheck - - packet := buf.Bytes() - mac := hmac.New(sha256.New, secret) - - mac.Write(clientHello.Random[:]) - mac.Write(packet) - - copy(packet[WelcomePacketRandomOffset:], mac.Sum(nil)) - - if _, err := writer.Write(packet); err != nil { - return err //nolint: wrapcheck - } - - return nil -} - -func generateServerHello(writer io.Writer, clientHello ClientHello) { - bodyBuf := &bytes.Buffer{} - - sliceBuf := [2]byte{} - digest := [RandomLen]byte{} - - binary.BigEndian.PutUint16(sliceBuf[:], uint16(record.Version12)) - bodyBuf.Write(sliceBuf[:]) - bodyBuf.Write(digest[:]) - bodyBuf.WriteByte(byte(len(clientHello.SessionID))) - bodyBuf.Write(clientHello.SessionID) - - binary.BigEndian.PutUint16(sliceBuf[:], clientHello.CipherSuite) - bodyBuf.Write(sliceBuf[:]) - bodyBuf.Write(serverHelloSuffix) - - scalar := [32]byte{} - - if _, err := rand.Read(scalar[:]); err != nil { - panic(err) - } - - curve, _ := curve25519.X25519(scalar[:], curve25519.Basepoint) - bodyBuf.Write(curve) - - header := [4]byte{0, 0, 0, 0} - binary.BigEndian.PutUint32(header[:], uint32(bodyBuf.Len())) - header[0] = HandshakeTypeServer - - writer.Write(header[:]) //nolint: errcheck - bodyBuf.WriteTo(writer) //nolint: errcheck -} diff --git a/mtglib/internal/faketls/welcome_test.go b/mtglib/internal/faketls/welcome_test.go deleted file mode 100644 index e722007..0000000 --- a/mtglib/internal/faketls/welcome_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package faketls_test - -import ( - "bytes" - "crypto/hmac" - "crypto/rand" - "crypto/sha256" - "testing" - "time" - - "github.com/9seconds/mtg/v2/mtglib" - "github.com/9seconds/mtg/v2/mtglib/internal/faketls" - "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record" - "github.com/stretchr/testify/suite" -) - -type WelcomeTestSuite struct { - suite.Suite - - h *faketls.ClientHello - buf *bytes.Buffer - secret mtglib.Secret -} - -func (suite *WelcomeTestSuite) SetupTest() { - suite.h = &faketls.ClientHello{ - Time: time.Now(), - Host: "google.com", - CipherSuite: 4867, - SessionID: make([]byte, 32), - } - - _, err := rand.Read(suite.h.SessionID) //nolint: staticcheck - suite.NoError(err) - - _, err = rand.Read(suite.h.Random[:]) //nolint: staticcheck - suite.NoError(err) - - suite.buf = &bytes.Buffer{} - - suite.secret = mtglib.GenerateSecret("google.com") -} - -func (suite *WelcomeTestSuite) TestOk() { - suite.NoError(faketls.SendWelcomePacket(suite.buf, suite.secret.Key[:], *suite.h)) - - welcomePacket := []byte{} - welcomePacket = append(welcomePacket, suite.buf.Bytes()...) - - rec := record.AcquireRecord() - defer record.ReleaseRecord(rec) - - suite.NoError(rec.Read(suite.buf)) - suite.Equal(record.TypeHandshake, rec.Type) - suite.Equal(record.Version12, rec.Version) - - suite.NoError(rec.Read(suite.buf)) - suite.Equal(record.TypeChangeCipherSpec, rec.Type) - suite.Equal(record.Version12, rec.Version) - - suite.NoError(rec.Read(suite.buf)) - suite.Equal(record.TypeApplicationData, rec.Type) - suite.Equal(record.Version12, rec.Version) - suite.Empty(suite.buf.Bytes()) - - random := make([]byte, 32) - copy(random, welcomePacket[11:]) - - empty := make([]byte, 32) - copy(welcomePacket[11:], empty) - - mac := hmac.New(sha256.New, suite.secret.Key[:]) - mac.Write(suite.h.Random[:]) - mac.Write(welcomePacket) - - suite.Equal(random, mac.Sum(nil)) -} - -func TestWelcome(t *testing.T) { - t.Parallel() - suite.Run(t, &WelcomeTestSuite{}) -}