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.

client_hello.go 1.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package tlstypes
  2. import (
  3. "bytes"
  4. "crypto/hmac"
  5. "crypto/sha256"
  6. "fmt"
  7. "github.com/9seconds/mtg/config"
  8. "github.com/9seconds/mtg/utils"
  9. )
  10. type ClientHello struct {
  11. Handshake
  12. }
  13. func (c ClientHello) Digest() []byte {
  14. dirtyDigest := c.Random
  15. c.Random = [32]byte{}
  16. rec := Record{
  17. Type: RecordTypeHandshake,
  18. Version: Version10,
  19. Data: &c,
  20. }
  21. mac := hmac.New(sha256.New, config.C.Secret)
  22. rec.WriteBytes(mac)
  23. computedDigest := mac.Sum(nil)
  24. for i := range computedDigest {
  25. computedDigest[i] ^= dirtyDigest[i]
  26. }
  27. return computedDigest
  28. }
  29. func ParseClientHello(raw []byte) (*ClientHello, error) {
  30. rv := &ClientHello{}
  31. rv.Type = HandshakeType(raw[0])
  32. if rv.Type != HandshakeTypeClient {
  33. return nil, fmt.Errorf("incorrect handshake type %v", rv.Type)
  34. }
  35. raw = raw[1:]
  36. sizeUint24 := utils.Uint24{}
  37. copy(sizeUint24[:], utils.ReverseBytes(raw[:3]))
  38. size := int(utils.FromUint24(sizeUint24))
  39. raw = raw[3:]
  40. if len(raw) != size {
  41. return nil, fmt.Errorf("payload size mismatch (%d != %d)", len(raw), size)
  42. }
  43. versionRaw := raw[:2]
  44. switch {
  45. case bytes.Equal(versionRaw, Version13Bytes):
  46. rv.Version = Version13
  47. case bytes.Equal(versionRaw, Version12Bytes):
  48. rv.Version = Version12
  49. case bytes.Equal(versionRaw, Version11Bytes):
  50. rv.Version = Version11
  51. case bytes.Equal(versionRaw, Version10Bytes):
  52. rv.Version = Version10
  53. default:
  54. return nil, fmt.Errorf("unknown protocol version %v", versionRaw)
  55. }
  56. raw = raw[2:]
  57. copy(rv.Random[:], raw[:32])
  58. raw = raw[32:]
  59. sessionIDLength := int(raw[0])
  60. raw = raw[1:]
  61. rv.SessionID = make([]byte, sessionIDLength)
  62. copy(rv.SessionID, raw)
  63. raw = raw[sessionIDLength:]
  64. tail := make([]byte, len(raw))
  65. copy(tail, raw)
  66. rv.Tail = RawBytes(tail)
  67. return rv, nil
  68. }