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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

streamcipherrwc.go 1.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package wrappers
  2. import (
  3. "crypto/cipher"
  4. "io"
  5. )
  6. // StreamCipherReadWriteCloser is a ReadWriteCloser which ciphers
  7. // incoming and outgoing data with givem cipher.Stream instances.
  8. type StreamCipherReadWriteCloser struct {
  9. encryptor cipher.Stream
  10. decryptor cipher.Stream
  11. conn io.ReadWriteCloser
  12. }
  13. // Read reads from connection
  14. func (c *StreamCipherReadWriteCloser) Read(p []byte) (n int, err error) {
  15. n, err = c.conn.Read(p)
  16. c.decryptor.XORKeyStream(p, p[:n])
  17. return
  18. }
  19. // Write writes into connection.
  20. func (c *StreamCipherReadWriteCloser) Write(p []byte) (int, error) {
  21. encrypted := make([]byte, len(p))
  22. c.encryptor.XORKeyStream(encrypted, p)
  23. allWritten := 0
  24. for len(encrypted) > 0 {
  25. n, err := c.conn.Write(encrypted)
  26. allWritten += n
  27. if err != nil {
  28. return allWritten, err
  29. }
  30. encrypted = encrypted[n:]
  31. }
  32. return allWritten, nil
  33. }
  34. // Close closes underlying connection.
  35. func (c *StreamCipherReadWriteCloser) Close() error {
  36. return c.conn.Close()
  37. }
  38. // NewStreamCipherRWC returns wrapper which transparently
  39. // encrypts/decrypts traffic with obfuscated2 protocol.
  40. func NewStreamCipherRWC(conn io.ReadWriteCloser, encryptor, decryptor cipher.Stream) io.ReadWriteCloser {
  41. return &StreamCipherReadWriteCloser{
  42. conn: conn,
  43. encryptor: encryptor,
  44. decryptor: decryptor,
  45. }
  46. }