Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server_side_test.go 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package fake_test
  2. import (
  3. "bytes"
  4. "crypto/hmac"
  5. "crypto/rand"
  6. "crypto/sha256"
  7. "testing"
  8. "github.com/9seconds/mtg/v2/mtglib"
  9. "github.com/9seconds/mtg/v2/mtglib/internal/tls"
  10. "github.com/9seconds/mtg/v2/mtglib/internal/tls/fake"
  11. "github.com/stretchr/testify/suite"
  12. )
  13. type SendServerHelloTestSuite struct {
  14. suite.Suite
  15. hello *fake.ClientHello
  16. buf *bytes.Buffer
  17. secret mtglib.Secret
  18. }
  19. func (suite *SendServerHelloTestSuite) SetupTest() {
  20. suite.hello = &fake.ClientHello{
  21. CipherSuite: 4867,
  22. SessionID: make([]byte, 32),
  23. }
  24. _, err := rand.Read(suite.hello.SessionID)
  25. suite.NoError(err)
  26. _, err = rand.Read(suite.hello.Random[:])
  27. suite.NoError(err)
  28. suite.buf = &bytes.Buffer{}
  29. suite.secret = mtglib.GenerateSecret("google.com")
  30. }
  31. func (suite *SendServerHelloTestSuite) TestRecordStructure() {
  32. noise, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
  33. suite.NoError(err)
  34. var rec bytes.Buffer
  35. recordType, _, err := tls.ReadRecord(suite.buf, &rec)
  36. suite.NoError(err)
  37. suite.Equal(byte(tls.TypeHandshake), recordType)
  38. rec.Reset()
  39. recordType, _, err = tls.ReadRecord(suite.buf, &rec)
  40. suite.NoError(err)
  41. suite.Equal(byte(tls.TypeChangeCipherSpec), recordType)
  42. suite.Empty(suite.buf.Bytes())
  43. // noise is raw payload without TLS record header
  44. suite.Len(noise, 1369)
  45. }
  46. func (suite *SendServerHelloTestSuite) TestHMAC() {
  47. noise, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
  48. suite.NoError(err)
  49. packet := make([]byte, suite.buf.Len())
  50. copy(packet, suite.buf.Bytes())
  51. random := make([]byte, fake.RandomLen)
  52. copy(random, packet[fake.RandomOffset:])
  53. copy(packet[fake.RandomOffset:], make([]byte, fake.RandomLen))
  54. mac := hmac.New(sha256.New, suite.secret.Key[:])
  55. mac.Write(suite.hello.Random[:])
  56. mac.Write(packet)
  57. // HMAC is computed over the full noise TLS record (with header),
  58. // but SendServerHello returns noise without the header,
  59. // so we reconstruct the full record.
  60. var fullNoise bytes.Buffer
  61. tls.WriteRecord(&fullNoise, noise) //nolint: errcheck
  62. mac.Write(fullNoise.Bytes())
  63. suite.Equal(random, mac.Sum(nil))
  64. }
  65. func (suite *SendServerHelloTestSuite) TestHandshakePayload() {
  66. _, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
  67. suite.NoError(err)
  68. packet := suite.buf.Bytes()
  69. // TLS record header: type(1) + version(2) + length(2)
  70. suite.Equal(byte(tls.TypeHandshake), packet[0])
  71. suite.Equal([]byte{3, 3}, packet[1:3])
  72. // Handshake header: type(1) + uint24_length(3)
  73. suite.Equal(byte(fake.TypeHandshakeServer), packet[5])
  74. // ServerHello version
  75. suite.Equal([]byte{3, 3}, packet[9:11])
  76. // Session ID
  77. sessionIDOffset := fake.RandomOffset + fake.RandomLen
  78. suite.Equal(byte(len(suite.hello.SessionID)), packet[sessionIDOffset])
  79. suite.Equal(suite.hello.SessionID, packet[sessionIDOffset+1:sessionIDOffset+1+len(suite.hello.SessionID)])
  80. }
  81. func (suite *SendServerHelloTestSuite) TestChangeCipherSpec() {
  82. _, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
  83. suite.NoError(err)
  84. // Skip first record
  85. var rec bytes.Buffer
  86. _, _, err = tls.ReadRecord(suite.buf, &rec)
  87. suite.NoError(err)
  88. // Read ChangeCipherSpec record
  89. rec.Reset()
  90. recordType, length, err := tls.ReadRecord(suite.buf, &rec)
  91. suite.NoError(err)
  92. suite.Equal(byte(tls.TypeChangeCipherSpec), recordType)
  93. suite.Equal(int64(1), length)
  94. suite.Equal([]byte{fake.ChangeCipherValue}, rec.Bytes())
  95. }
  96. func TestSendServerHello(t *testing.T) {
  97. t.Parallel()
  98. suite.Run(t, &SendServerHelloTestSuite{})
  99. }