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 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package stream
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "fmt"
  7. "net"
  8. "time"
  9. "go.uber.org/zap"
  10. "github.com/9seconds/mtg/conntypes"
  11. "github.com/9seconds/mtg/utils"
  12. )
  13. type wrapperBlockCipher struct {
  14. buf bytes.Buffer
  15. parent conntypes.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. if w.buf.Len() > 0 {
  35. return w.flush(p)
  36. }
  37. var currentBuffer []byte
  38. for len(currentBuffer) == 0 || len(currentBuffer)%aes.BlockSize != 0 {
  39. rv, err := utils.ReadFull(w.parent)
  40. if err != nil {
  41. return 0, fmt.Errorf("cannot read data: %w", err)
  42. }
  43. currentBuffer = append(currentBuffer, rv...)
  44. }
  45. w.decryptor.CryptBlocks(currentBuffer, currentBuffer)
  46. w.buf.Write(currentBuffer)
  47. return w.flush(p)
  48. }
  49. func (w *wrapperBlockCipher) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
  50. return w.Read(p)
  51. }
  52. func (w *wrapperBlockCipher) flush(p []byte) (int, error) {
  53. if w.buf.Len() > len(p) {
  54. return w.buf.Read(p)
  55. }
  56. sizeToReturn := w.buf.Len()
  57. copy(p, w.buf.Bytes())
  58. w.buf.Reset()
  59. return sizeToReturn, nil
  60. }
  61. func (w *wrapperBlockCipher) encrypt(p []byte) ([]byte, error) {
  62. if len(p)%aes.BlockSize > 0 {
  63. return nil, fmt.Errorf("incorrect block size %d", len(p))
  64. }
  65. encrypted := make([]byte, len(p))
  66. w.encryptor.CryptBlocks(encrypted, p)
  67. return encrypted, nil
  68. }
  69. func (w *wrapperBlockCipher) Close() error {
  70. return w.parent.Close()
  71. }
  72. func (w *wrapperBlockCipher) Conn() net.Conn {
  73. return w.parent.Conn()
  74. }
  75. func (w *wrapperBlockCipher) Logger() *zap.SugaredLogger {
  76. return w.parent.Logger().Named("block-cipher")
  77. }
  78. func (w *wrapperBlockCipher) LocalAddr() *net.TCPAddr {
  79. return w.parent.LocalAddr()
  80. }
  81. func (w *wrapperBlockCipher) RemoteAddr() *net.TCPAddr {
  82. return w.parent.RemoteAddr()
  83. }
  84. func newBlockCipher(parent conntypes.StreamReadWriteCloser,
  85. encryptor, decryptor cipher.BlockMode) conntypes.StreamReadWriteCloser {
  86. return &wrapperBlockCipher{
  87. parent: parent,
  88. encryptor: encryptor,
  89. decryptor: decryptor,
  90. }
  91. }