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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package wrappers
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "net"
  7. "go.uber.org/zap"
  8. "github.com/9seconds/mtg/utils"
  9. "github.com/juju/errors"
  10. )
  11. type BlockCipher struct {
  12. buf *bytes.Buffer
  13. logger *zap.SugaredLogger
  14. conn StreamReadWriteCloser
  15. encryptor cipher.BlockMode
  16. decryptor cipher.BlockMode
  17. }
  18. func (b *BlockCipher) Read(p []byte) (int, error) {
  19. if b.buf.Len() > 0 {
  20. return b.flush(p)
  21. }
  22. buf := []byte{}
  23. for len(buf) == 0 || len(buf)%aes.BlockSize != 0 {
  24. rv, err := utils.ReadCurrentData(b.conn)
  25. if err != nil {
  26. return 0, errors.Annotate(err, "Cannot read from socket")
  27. }
  28. buf = append(buf, rv...)
  29. }
  30. b.decryptor.CryptBlocks(buf, buf)
  31. b.buf.Write(buf)
  32. return b.flush(p)
  33. }
  34. func (b *BlockCipher) flush(p []byte) (int, error) {
  35. if b.buf.Len() <= len(p) {
  36. sizeToReturn := b.buf.Len()
  37. copy(p, b.buf.Bytes())
  38. b.buf.Reset()
  39. return sizeToReturn, nil
  40. }
  41. return b.buf.Read(p)
  42. }
  43. func (b *BlockCipher) Write(p []byte) (int, error) {
  44. if len(p)%aes.BlockSize > 0 {
  45. return 0, errors.Errorf("Incorrect block size %d", len(p))
  46. }
  47. encrypted := make([]byte, len(p))
  48. b.encryptor.CryptBlocks(encrypted, p)
  49. return b.conn.Write(encrypted)
  50. }
  51. func (b *BlockCipher) Logger() *zap.SugaredLogger {
  52. return b.logger
  53. }
  54. func (b *BlockCipher) LocalAddr() *net.TCPAddr {
  55. return b.conn.LocalAddr()
  56. }
  57. func (b *BlockCipher) RemoteAddr() *net.TCPAddr {
  58. return b.conn.RemoteAddr()
  59. }
  60. func (b *BlockCipher) Close() error {
  61. return b.conn.Close()
  62. }
  63. func NewBlockCipher(conn StreamReadWriteCloser, encryptor, decryptor cipher.BlockMode) StreamReadWriteCloser {
  64. return &BlockCipher{
  65. buf: &bytes.Buffer{},
  66. conn: conn,
  67. logger: conn.Logger().Named("block-cipher"),
  68. encryptor: encryptor,
  69. decryptor: decryptor,
  70. }
  71. }