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  }