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.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. // BlockCipher is a stream writer which encrypts/decrypts blocks of data
  12. // with AES CBC. This also is buffered reader. It means, that block
  13. // reading is transparent for it, you can assume you are working with
  14. // good old io.Reader.
  15. type BlockCipher struct {
  16. buf *bytes.Buffer
  17. logger *zap.SugaredLogger
  18. conn StreamReadWriteCloser
  19. encryptor cipher.BlockMode
  20. decryptor cipher.BlockMode
  21. }
  22. func (b *BlockCipher) Read(p []byte) (int, error) {
  23. if b.buf.Len() > 0 {
  24. return b.flush(p)
  25. }
  26. buf := []byte{}
  27. for len(buf) == 0 || len(buf)%aes.BlockSize != 0 {
  28. rv, err := utils.ReadCurrentData(b.conn)
  29. if err != nil {
  30. return 0, errors.Annotate(err, "Cannot read from socket")
  31. }
  32. buf = append(buf, rv...)
  33. }
  34. b.decryptor.CryptBlocks(buf, buf)
  35. b.buf.Write(buf) // nolint: gosec
  36. return b.flush(p)
  37. }
  38. func (b *BlockCipher) flush(p []byte) (int, error) {
  39. if b.buf.Len() <= len(p) {
  40. sizeToReturn := b.buf.Len()
  41. copy(p, b.buf.Bytes())
  42. b.buf.Reset()
  43. return sizeToReturn, nil
  44. }
  45. return b.buf.Read(p)
  46. }
  47. func (b *BlockCipher) Write(p []byte) (int, error) {
  48. if len(p)%aes.BlockSize > 0 {
  49. return 0, errors.Errorf("Incorrect block size %d", len(p))
  50. }
  51. encrypted := make([]byte, len(p))
  52. b.encryptor.CryptBlocks(encrypted, p)
  53. return b.conn.Write(encrypted)
  54. }
  55. // Logger returns an instance of the logger for this wrapper.
  56. func (b *BlockCipher) Logger() *zap.SugaredLogger {
  57. return b.logger
  58. }
  59. // LocalAddr returns local address of the underlying net.Conn.
  60. func (b *BlockCipher) LocalAddr() *net.TCPAddr {
  61. return b.conn.LocalAddr()
  62. }
  63. // RemoteAddr returns remote address of the underlying net.Conn.
  64. func (b *BlockCipher) RemoteAddr() *net.TCPAddr {
  65. return b.conn.RemoteAddr()
  66. }
  67. // Close closes underlying net.Conn.
  68. func (b *BlockCipher) Close() error {
  69. return b.conn.Close()
  70. }
  71. // NewBlockCipher creates new instance of BlockCipher based on given data.
  72. func NewBlockCipher(conn StreamReadWriteCloser, encryptor, decryptor cipher.BlockMode) StreamReadWriteCloser {
  73. return &BlockCipher{
  74. buf: &bytes.Buffer{},
  75. conn: conn,
  76. logger: conn.Logger().Named("block-cipher"),
  77. encryptor: encryptor,
  78. decryptor: decryptor,
  79. }
  80. }