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
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

blockcipher.go 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package wrappers
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "errors"
  7. "fmt"
  8. "net"
  9. "time"
  10. "go.uber.org/zap"
  11. )
  12. const blockCipherReadCurrentDataBufferSize = 1024 + 1 // +1 because telegram operates with blocks mod 4
  13. type wrapperBlockCipher struct {
  14. buf bytes.Buffer
  15. parent StreamReadWriteCloser
  16. encryptor cipher.BlockMode
  17. decryptor cipher.BlockMode
  18. }
  19. func (w *wrapperBlockCipher) Write(p []byte) (int, error) {
  20. encrypted, err := w.encrypt(p)
  21. if err != nil {
  22. return 0, err
  23. }
  24. return w.parent.Write(encrypted)
  25. }
  26. func (w *wrapperBlockCipher) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
  27. encrypted, err := w.encrypt(p)
  28. if err != nil {
  29. return 0, err
  30. }
  31. return w.parent.WriteTimeout(encrypted, timeout)
  32. }
  33. func (w *wrapperBlockCipher) Read(p []byte) (int, error) {
  34. return w.read(p, readAll)
  35. }
  36. func (w *wrapperBlockCipher) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
  37. return w.read(p, readAllTimeout(timeout))
  38. }
  39. func (w *wrapperBlockCipher) read(p []byte, reader func(StreamReadWriteCloser) ([]byte, error)) (int, error) {
  40. if w.buf.Len() > 0 {
  41. return w.flush(p)
  42. }
  43. var buf []byte
  44. for len(buf) == 0 || len(buf)%aes.BlockSize != 0 {
  45. rv, err := reader(w.parent)
  46. if err != nil {
  47. return 0, fmt.Errorf("cannot read from socket: %w", err)
  48. }
  49. buf = append(buf, rv...)
  50. }
  51. w.decryptor.CryptBlocks(buf, buf)
  52. w.buf.Write(buf)
  53. return w.flush(p)
  54. }
  55. func (w *wrapperBlockCipher) flush(p []byte) (int, error) {
  56. if w.buf.Len() > len(p) {
  57. return w.buf.Read(p)
  58. }
  59. sizeToReturn := w.buf.Len()
  60. copy(p, w.buf.Bytes())
  61. w.buf.Reset()
  62. return sizeToReturn, nil
  63. }
  64. func (w *wrapperBlockCipher) encrypt(p []byte) ([]byte, error) {
  65. if len(p)%aes.BlockSize > 0 {
  66. return nil, fmt.Errorf("incorrect block size %d", len(p))
  67. }
  68. encrypted := make([]byte, len(p))
  69. w.encryptor.CryptBlocks(encrypted, p)
  70. return encrypted, nil
  71. }
  72. func readAll(src StreamReadWriteCloser) (rv []byte, err error) {
  73. buf := make([]byte, blockCipherReadCurrentDataBufferSize)
  74. n := blockCipherReadCurrentDataBufferSize
  75. for n == len(buf) {
  76. n, err = src.Read(buf)
  77. if err != nil {
  78. return nil, err
  79. }
  80. rv = append(rv, buf[:n]...)
  81. }
  82. return rv, nil
  83. }
  84. func readAllTimeout(timeout time.Duration) func(StreamReadWriteCloser) ([]byte, error) {
  85. return func(src StreamReadWriteCloser) (rv []byte, err error) {
  86. tmo := timeout
  87. buf := make([]byte, blockCipherReadCurrentDataBufferSize)
  88. n := blockCipherReadCurrentDataBufferSize
  89. for n == len(buf) {
  90. if tmo <= 0 {
  91. return nil, errors.New("timeout")
  92. }
  93. startTime := time.Now()
  94. n, err = src.ReadTimeout(buf, tmo)
  95. if err != nil {
  96. return nil, err
  97. }
  98. rv = append(rv, buf[:n]...)
  99. tmo -= time.Since(startTime)
  100. }
  101. return rv, nil
  102. }
  103. }
  104. func (w *wrapperBlockCipher) Close() error {
  105. return w.parent.Close()
  106. }
  107. func (w *wrapperBlockCipher) Conn() net.Conn {
  108. return w.parent.Conn()
  109. }
  110. func (w *wrapperBlockCipher) Logger() *zap.SugaredLogger {
  111. return w.parent.Logger().Named("block-cipher")
  112. }
  113. func (w *wrapperBlockCipher) LocalAddr() *net.TCPAddr {
  114. return w.parent.LocalAddr()
  115. }
  116. func (w *wrapperBlockCipher) RemoteAddr() *net.TCPAddr {
  117. return w.parent.RemoteAddr()
  118. }
  119. func NewBlockCipher(parent StreamReadWriteCloser, encryptor, decryptor cipher.BlockMode) StreamReadWriteCloser {
  120. return &wrapperBlockCipher{
  121. parent: parent,
  122. encryptor: encryptor,
  123. decryptor: decryptor,
  124. }
  125. }