github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/libs/niaucchi4/obfsstream.go (about) 1 package niaucchi4 2 3 import ( 4 "net" 5 "time" 6 7 "golang.org/x/crypto/chacha20" 8 ) 9 10 type ObfsStream struct { 11 readCrypt *chacha20.Cipher 12 writeCrypt *chacha20.Cipher 13 wbuf []byte 14 wire net.Conn 15 } 16 17 func NewObfsStream(wire net.Conn, key []byte, isServ bool) *ObfsStream { 18 os := &ObfsStream{} 19 downNonce := make([]byte, 12) 20 upNonce := make([]byte, 12) 21 downNonce[0] = 1 22 var err error 23 24 os.readCrypt, err = chacha20.NewUnauthenticatedCipher(key, downNonce) 25 if err != nil { 26 panic(err) 27 } 28 os.writeCrypt, err = chacha20.NewUnauthenticatedCipher(key, upNonce) 29 if err != nil { 30 panic(err) 31 } 32 if isServ { 33 tmp := os.readCrypt 34 os.readCrypt = os.writeCrypt 35 os.writeCrypt = tmp 36 } 37 os.wire = wire 38 return os 39 } 40 41 func (os *ObfsStream) Write(p []byte) (n int, err error) { 42 if len(os.wbuf) < len(p) { 43 os.wbuf = make([]byte, len(p)) 44 } 45 os.writeCrypt.XORKeyStream(os.wbuf[:len(p)], p) 46 n, err = os.wire.Write(os.wbuf[:len(p)]) 47 return 48 } 49 50 func (os *ObfsStream) Read(p []byte) (n int, err error) { 51 n, err = os.wire.Read(p) 52 if err != nil { 53 return 54 } 55 os.readCrypt.XORKeyStream(p[:n], p[:n]) 56 return 57 } 58 59 func (os *ObfsStream) Close() error { 60 return os.wire.Close() 61 } 62 63 func (os *ObfsStream) LocalAddr() net.Addr { 64 return os.wire.LocalAddr() 65 } 66 67 func (os *ObfsStream) RemoteAddr() net.Addr { 68 return os.wire.RemoteAddr() 69 } 70 71 func (os *ObfsStream) SetDeadline(t time.Time) error { 72 return os.wire.SetDeadline(t) 73 } 74 75 func (os *ObfsStream) SetReadDeadline(t time.Time) error { 76 return os.wire.SetReadDeadline(t) 77 } 78 79 func (os *ObfsStream) SetWriteDeadline(t time.Time) error { 80 return os.wire.SetWriteDeadline(t) 81 }