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
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

welcome.go 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package faketls
  2. import (
  3. "bytes"
  4. "crypto/hmac"
  5. "crypto/rand"
  6. "crypto/sha256"
  7. "encoding/binary"
  8. "io"
  9. mrand "math/rand/v2"
  10. "github.com/9seconds/mtg/v2/mtglib/internal/faketls/record"
  11. "golang.org/x/crypto/curve25519"
  12. )
  13. func SendWelcomePacket(writer io.Writer, secret []byte, clientHello ClientHello) error {
  14. buf := &bytes.Buffer{}
  15. rec := record.AcquireRecord()
  16. defer record.ReleaseRecord(rec)
  17. rec.Type = record.TypeHandshake
  18. rec.Version = record.Version12
  19. generateServerHello(&rec.Payload, clientHello)
  20. rec.Dump(buf) //nolint: errcheck
  21. rec.Reset()
  22. rec.Type = record.TypeChangeCipherSpec
  23. rec.Version = record.Version12
  24. rec.Payload.WriteByte(ChangeCipherValue)
  25. rec.Dump(buf) //nolint: errcheck
  26. rec.Reset()
  27. rec.Type = record.TypeApplicationData
  28. rec.Version = record.Version12
  29. if _, err := io.CopyN(&rec.Payload, rand.Reader, int64(1024+mrand.IntN(3092))); err != nil {
  30. panic(err)
  31. }
  32. rec.Dump(buf) //nolint: errcheck
  33. packet := buf.Bytes()
  34. mac := hmac.New(sha256.New, secret)
  35. mac.Write(clientHello.Random[:])
  36. mac.Write(packet)
  37. copy(packet[WelcomePacketRandomOffset:], mac.Sum(nil))
  38. if _, err := writer.Write(packet); err != nil {
  39. return err //nolint: wrapcheck
  40. }
  41. return nil
  42. }
  43. func generateServerHello(writer io.Writer, clientHello ClientHello) {
  44. bodyBuf := &bytes.Buffer{}
  45. sliceBuf := [2]byte{}
  46. digest := [RandomLen]byte{}
  47. binary.BigEndian.PutUint16(sliceBuf[:], uint16(record.Version12))
  48. bodyBuf.Write(sliceBuf[:])
  49. bodyBuf.Write(digest[:])
  50. bodyBuf.WriteByte(byte(len(clientHello.SessionID)))
  51. bodyBuf.Write(clientHello.SessionID)
  52. binary.BigEndian.PutUint16(sliceBuf[:], clientHello.CipherSuite)
  53. bodyBuf.Write(sliceBuf[:])
  54. bodyBuf.Write(serverHelloSuffix)
  55. scalar := [32]byte{}
  56. if _, err := rand.Read(scalar[:]); err != nil {
  57. panic(err)
  58. }
  59. curve, _ := curve25519.X25519(scalar[:], curve25519.Basepoint)
  60. bodyBuf.Write(curve)
  61. header := [4]byte{0, 0, 0, 0}
  62. binary.BigEndian.PutUint32(header[:], uint32(bodyBuf.Len()))
  63. header[0] = HandshakeTypeServer
  64. writer.Write(header[:]) //nolint: errcheck
  65. bodyBuf.WriteTo(writer) //nolint: errcheck
  66. }