diff options
| -rw-r--r-- | transports/obfs2/obfs2.go | 70 | ||||
| -rw-r--r-- | transports/obfs3/obfs3.go | 54 | ||||
| -rw-r--r-- | transports/obfs4/handshake_ntor.go | 5 | ||||
| -rw-r--r-- | transports/obfs4/obfs4.go | 63 | ||||
| -rw-r--r-- | transports/obfs4/packet.go | 17 | ||||
| -rw-r--r-- | transports/obfs4/statefile.go | 6 | ||||
| -rw-r--r-- | transports/scramblesuit/conn.go | 32 | 
7 files changed, 118 insertions, 129 deletions
diff --git a/transports/obfs2/obfs2.go b/transports/obfs2/obfs2.go index f8efac1..bc2532b 100644 --- a/transports/obfs2/obfs2.go +++ b/transports/obfs2/obfs2.go @@ -187,7 +187,7 @@ func newObfs2ServerConn(conn net.Conn) (c *obfs2Conn, err error) {  	return  } -func (conn *obfs2Conn) handshake() (err error) { +func (conn *obfs2Conn) handshake() error {  	// Each begins by generating a seed and a padding key as follows.  	// The initiator generates:  	// @@ -202,8 +202,8 @@ func (conn *obfs2Conn) handshake() (err error) {  	// Each then generates a random number PADLEN in range from 0 through  	// MAX_PADDING (inclusive).  	var seed [seedLen]byte -	if err = csrand.Bytes(seed[:]); err != nil { -		return +	if err := csrand.Bytes(seed[:]); err != nil { +		return err  	}  	var padMagic []byte  	if conn.isInitiator { @@ -218,8 +218,8 @@ func (conn *obfs2Conn) handshake() (err error) {  	binary.BigEndian.PutUint32(hsBlob[0:4], magicValue)  	binary.BigEndian.PutUint32(hsBlob[4:8], padLen)  	if padLen > 0 { -		if err = csrand.Bytes(hsBlob[8:]); err != nil { -			return +		if err := csrand.Bytes(hsBlob[8:]); err != nil { +			return err  		}  	} @@ -230,25 +230,25 @@ func (conn *obfs2Conn) handshake() (err error) {  	// and the responder sends:  	//  	//  RESP_SEED | E(RESP_PAD_KEY, UINT32(MAGIC_VALUE) | UINT32(PADLEN) | WR(PADLEN)) -	var txBlock cipher.Block -	if txBlock, err = aes.NewCipher(padKey); err != nil { -		return +	txBlock, err := aes.NewCipher(padKey) +	if err != nil { +		return err  	}  	txStream := cipher.NewCTR(txBlock, padIV)  	conn.tx = &cipher.StreamWriter{S: txStream, W: conn.Conn} -	if _, err = conn.Conn.Write(seed[:]); err != nil { -		return +	if _, err := conn.Conn.Write(seed[:]); err != nil { +		return err  	} -	if _, err = conn.Write(hsBlob); err != nil { -		return +	if _, err := conn.Write(hsBlob); err != nil { +		return err  	}  	// Upon receiving the SEED from the other party, each party derives  	// the other party's padding key value as above, and decrypts the next  	// 8 bytes of the key establishment message.  	var peerSeed [seedLen]byte -	if _, err = io.ReadFull(conn.Conn, peerSeed[:]); err != nil { -		return +	if _, err := io.ReadFull(conn.Conn, peerSeed[:]); err != nil { +		return err  	}  	var peerPadMagic []byte  	if conn.isInitiator { @@ -257,46 +257,44 @@ func (conn *obfs2Conn) handshake() (err error) {  		peerPadMagic = []byte(initiatorPadString)  	}  	peerKey, peerIV := hsKdf(peerPadMagic, peerSeed[:], !conn.isInitiator) -	var rxBlock cipher.Block -	if rxBlock, err = aes.NewCipher(peerKey); err != nil { -		return +	rxBlock, err := aes.NewCipher(peerKey) +	if err != nil { +		return err  	}  	rxStream := cipher.NewCTR(rxBlock, peerIV)  	conn.rx = &cipher.StreamReader{S: rxStream, R: conn.Conn}  	hsHdr := make([]byte, hsLen) -	if _, err = io.ReadFull(conn, hsHdr[:]); err != nil { -		return +	if _, err := io.ReadFull(conn, hsHdr[:]); err != nil { +		return err  	}  	// If the MAGIC_VALUE does not match, or the PADLEN value is greater than  	// MAX_PADDING, the party receiving it should close the connection  	// immediately.  	if peerMagic := binary.BigEndian.Uint32(hsHdr[0:4]); peerMagic != magicValue { -		err = fmt.Errorf("invalid magic value: %x", peerMagic) -		return +		return fmt.Errorf("invalid magic value: %x", peerMagic)  	}  	padLen = binary.BigEndian.Uint32(hsHdr[4:8])  	if padLen > maxPadding { -		err = fmt.Errorf("padlen too long: %d", padLen) -		return +		return fmt.Errorf("padlen too long: %d", padLen)  	}  	// Otherwise, it should read the remaining PADLEN bytes of padding data  	// and discard them.  	tmp := make([]byte, padLen) -	if _, err = io.ReadFull(conn.Conn, tmp); err != nil { // Note: Skips AES. -		return +	if _, err := io.ReadFull(conn.Conn, tmp); err != nil { // Note: Skips AES. +		return err  	}  	// Derive the actual keys. -	if err = conn.kdf(seed[:], peerSeed[:]); err != nil { -		return +	if err := conn.kdf(seed[:], peerSeed[:]); err != nil { +		return err  	} -	return +	return nil  } -func (conn *obfs2Conn) kdf(seed, peerSeed []byte) (err error) { +func (conn *obfs2Conn) kdf(seed, peerSeed []byte) error {  	// Additional keys are then derived as:  	//  	//  INIT_SECRET = MAC("Initiator obfuscated data", INIT_SEED|RESP_SEED) @@ -315,16 +313,16 @@ func (conn *obfs2Conn) kdf(seed, peerSeed []byte) (err error) {  	}  	initKey, initIV := hsKdf([]byte(initiatorKdfString), combSeed, true) -	var initBlock cipher.Block -	if initBlock, err = aes.NewCipher(initKey); err != nil { -		return +	initBlock, err := aes.NewCipher(initKey) +	if err != nil { +		return err  	}  	initStream := cipher.NewCTR(initBlock, initIV)  	respKey, respIV := hsKdf([]byte(responderKdfString), combSeed, false) -	var respBlock cipher.Block -	if respBlock, err = aes.NewCipher(respKey); err != nil { -		return +	respBlock, err := aes.NewCipher(respKey) +	if err != nil { +		return err  	}  	respStream := cipher.NewCTR(respBlock, respIV) @@ -336,7 +334,7 @@ func (conn *obfs2Conn) kdf(seed, peerSeed []byte) (err error) {  		conn.rx.S = initStream  	} -	return +	return nil  }  func hsKdf(magic, seed []byte, isInitiator bool) (padKey, padIV []byte) { diff --git a/transports/obfs3/obfs3.go b/transports/obfs3/obfs3.go index 53409db..d215c49 100644 --- a/transports/obfs3/obfs3.go +++ b/transports/obfs3/obfs3.go @@ -166,56 +166,56 @@ func newObfs3ServerConn(conn net.Conn) (c *obfs3Conn, err error) {  	return  } -func (conn *obfs3Conn) handshake() (err error) { +func (conn *obfs3Conn) handshake() error {  	// The party who opens the connection is the 'initiator'; the one who  	// accepts it is the 'responder'.  Each begins by generating a  	// UniformDH keypair, and a random number PADLEN in [0, MAX_PADDING/2].  	// Both parties then send:  	//  	//  PUB_KEY | WR(PADLEN) -	var privateKey *uniformdh.PrivateKey -	if privateKey, err = uniformdh.GenerateKey(csrand.Reader); err != nil { -		return +	privateKey, err := uniformdh.GenerateKey(csrand.Reader) +	if err != nil { +		return err  	}  	padLen := csrand.IntRange(0, maxPadding/2)  	blob := make([]byte, uniformdh.Size+padLen) -	var publicKey []byte -	if publicKey, err = privateKey.PublicKey.Bytes(); err != nil { -		return +	publicKey, err := privateKey.PublicKey.Bytes() +	if err != nil { +		return err  	}  	copy(blob[0:], publicKey) -	if err = csrand.Bytes(blob[uniformdh.Size:]); err != nil { -		return +	if err := csrand.Bytes(blob[uniformdh.Size:]); err != nil { +		return err  	} -	if _, err = conn.Conn.Write(blob); err != nil { -		return +	if _, err := conn.Conn.Write(blob); err != nil { +		return err  	}  	// Read the public key from the peer.  	rawPeerPublicKey := make([]byte, uniformdh.Size) -	if _, err = io.ReadFull(conn.Conn, rawPeerPublicKey); err != nil { -		return +	if _, err := io.ReadFull(conn.Conn, rawPeerPublicKey); err != nil { +		return err  	}  	var peerPublicKey uniformdh.PublicKey -	if err = peerPublicKey.SetBytes(rawPeerPublicKey); err != nil { -		return +	if err := peerPublicKey.SetBytes(rawPeerPublicKey); err != nil { +		return err  	}  	// After retrieving the public key of the other end, each party  	// completes the DH key exchange and generates a shared-secret for the  	// session (named SHARED_SECRET). -	var sharedSecret []byte -	if sharedSecret, err = uniformdh.Handshake(privateKey, &peerPublicKey); err != nil { -		return +	sharedSecret, err := uniformdh.Handshake(privateKey, &peerPublicKey) +	if err != nil { +		return err  	} -	if err = conn.kdf(sharedSecret); err != nil { -		return +	if err := conn.kdf(sharedSecret); err != nil { +		return err  	} -	return +	return nil  } -func (conn *obfs3Conn) kdf(sharedSecret []byte) (err error) { +func (conn *obfs3Conn) kdf(sharedSecret []byte) error {  	// Using that shared-secret each party derives its encryption keys as  	// follows:  	// @@ -248,14 +248,14 @@ func (conn *obfs3Conn) kdf(sharedSecret []byte) (err error) {  	//  	// Note: To have this be the last place where the shared secret is used,  	// also generate the magic value to send/scan for here. -	var initBlock cipher.Block -	if initBlock, err = aes.NewCipher(initSecret[:keyLen]); err != nil { +	initBlock, err := aes.NewCipher(initSecret[:keyLen]) +	if err != nil {  		return err  	}  	initStream := cipher.NewCTR(initBlock, initSecret[keyLen:]) -	var respBlock cipher.Block -	if respBlock, err = aes.NewCipher(respSecret[:keyLen]); err != nil { +	respBlock, err := aes.NewCipher(respSecret[:keyLen]) +	if err != nil {  		return err  	}  	respStream := cipher.NewCTR(respBlock, respSecret[keyLen:]) @@ -272,7 +272,7 @@ func (conn *obfs3Conn) kdf(sharedSecret []byte) (err error) {  		conn.rxMagic = initMagic  	} -	return +	return nil  }  func (conn *obfs3Conn) findPeerMagic() error { diff --git a/transports/obfs4/handshake_ntor.go b/transports/obfs4/handshake_ntor.go index 8dcf0c8..57de460 100644 --- a/transports/obfs4/handshake_ntor.go +++ b/transports/obfs4/handshake_ntor.go @@ -417,10 +417,9 @@ func findMarkMac(mark, buf []byte, startPos, maxPos int, fromTail bool) (pos int  func makePad(padLen int) ([]byte, error) {  	pad := make([]byte, padLen) -	err := csrand.Bytes(pad) -	if err != nil { +	if err := csrand.Bytes(pad); err != nil {  		return nil, err  	} -	return pad, err +	return pad, nil  } diff --git a/transports/obfs4/obfs4.go b/transports/obfs4/obfs4.go index 256f549..07af9ab 100644 --- a/transports/obfs4/obfs4.go +++ b/transports/obfs4/obfs4.go @@ -105,16 +105,15 @@ func (t *Transport) ClientFactory(stateDir string) (base.ClientFactory, error) {  // ServerFactory returns a new obfs4ServerFactory instance.  func (t *Transport) ServerFactory(stateDir string, args *pt.Args) (base.ServerFactory, error) { -	var err error - -	var st *obfs4ServerState -	if st, err = serverStateFromArgs(stateDir, args); err != nil { +	st, err := serverStateFromArgs(stateDir, args) +	if err != nil {  		return nil, err  	}  	var iatSeed *drbg.Seed  	if st.iatMode != iatNone {  		iatSeedSrc := sha256.Sum256(st.drbgSeed.Bytes()[:]) +		var err error  		iatSeed, err = drbg.SeedFromBytes(iatSeedSrc[:])  		if err != nil {  			return nil, err @@ -152,8 +151,6 @@ func (cf *obfs4ClientFactory) Transport() base.Transport {  }  func (cf *obfs4ClientFactory) ParseArgs(args *pt.Args) (interface{}, error) { -	var err error -  	var nodeID *ntor.NodeID  	var publicKey *ntor.PublicKey @@ -161,8 +158,8 @@ func (cf *obfs4ClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {  	// for the Node ID and Public Key.  	certStr, ok := args.Get(certArg)  	if ok { -		var cert *obfs4ServerCert -		if cert, err = serverCertFromString(certStr); err != nil { +		cert, err := serverCertFromString(certStr) +		if err != nil {  			return nil, err  		}  		nodeID, publicKey = cert.unpack() @@ -173,6 +170,7 @@ func (cf *obfs4ClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {  		if !ok {  			return nil, fmt.Errorf("missing argument '%s'", nodeIDArg)  		} +		var err error  		if nodeID, err = ntor.NodeIDFromHex(nodeIDStr); err != nil {  			return nil, err  		} @@ -191,8 +189,7 @@ func (cf *obfs4ClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {  	if !ok {  		return nil, fmt.Errorf("missing argument '%s'", iatArg)  	} -	var iatMode int -	iatMode, err = strconv.Atoi(iatStr) +	iatMode, err := strconv.Atoi(iatStr)  	if err != nil || iatMode < iatNone || iatMode > iatParanoid {  		return nil, fmt.Errorf("invalid iat-mode '%d'", iatMode)  	} @@ -343,16 +340,15 @@ func (conn *obfs4Conn) clientHandshake(nodeID *ntor.NodeID, peerIdentityKey *nto  	// Consume the server handshake.  	var hsBuf [maxHandshakeLength]byte  	for { -		var n int -		if n, err = conn.Conn.Read(hsBuf[:]); err != nil { +		n, err := conn.Conn.Read(hsBuf[:]) +		if err != nil {  			// The Read() could have returned data and an error, but there is  			// no point in continuing on an EOF or whatever.  			return err  		}  		conn.receiveBuffer.Write(hsBuf[:n]) -		var seed []byte -		n, seed, err = hs.parseServerHandshake(conn.receiveBuffer.Bytes()) +		n, seed, err := hs.parseServerHandshake(conn.receiveBuffer.Bytes())  		if err == ErrMarkNotFoundYet {  			continue  		} else if err != nil { @@ -369,39 +365,38 @@ func (conn *obfs4Conn) clientHandshake(nodeID *ntor.NodeID, peerIdentityKey *nto  	}  } -func (conn *obfs4Conn) serverHandshake(sf *obfs4ServerFactory, sessionKey *ntor.Keypair) (err error) { +func (conn *obfs4Conn) serverHandshake(sf *obfs4ServerFactory, sessionKey *ntor.Keypair) error {  	if !conn.isServer {  		return fmt.Errorf("serverHandshake called on client connection")  	}  	// Generate the server handshake, and arm the base timeout.  	hs := newServerHandshake(sf.nodeID, sf.identityKey, sessionKey) -	if err = conn.Conn.SetDeadline(time.Now().Add(serverHandshakeTimeout)); err != nil { -		return +	if err := conn.Conn.SetDeadline(time.Now().Add(serverHandshakeTimeout)); err != nil { +		return err  	}  	// Consume the client handshake.  	var hsBuf [maxHandshakeLength]byte  	for { -		var n int -		if n, err = conn.Conn.Read(hsBuf[:]); err != nil { +		n, err := conn.Conn.Read(hsBuf[:]) +		if err != nil {  			// The Read() could have returned data and an error, but there is  			// no point in continuing on an EOF or whatever. -			return +			return err  		}  		conn.receiveBuffer.Write(hsBuf[:n]) -		var seed []byte -		seed, err = hs.parseClientHandshake(sf.replayFilter, conn.receiveBuffer.Bytes()) +		seed, err := hs.parseClientHandshake(sf.replayFilter, conn.receiveBuffer.Bytes())  		if err == ErrMarkNotFoundYet {  			continue  		} else if err != nil { -			return +			return err  		}  		conn.receiveBuffer.Reset() -		if err = conn.Conn.SetDeadline(time.Time{}); err != nil { -			return +		if err := conn.Conn.SetDeadline(time.Time{}); err != nil { +			return nil  		}  		// Use the derived key material to intialize the link crypto. @@ -422,26 +417,24 @@ func (conn *obfs4Conn) serverHandshake(sf *obfs4ServerFactory, sessionKey *ntor.  	// handshake_ntor.go.  	// Generate/send the response. -	var blob []byte -	blob, err = hs.generateHandshake() +	blob, err := hs.generateHandshake()  	if err != nil { -		return +		return err  	}  	var frameBuf bytes.Buffer -	_, err = frameBuf.Write(blob) -	if err != nil { -		return +	if _, err = frameBuf.Write(blob); err != nil { +		return err  	}  	// Send the PRNG seed as the first packet. -	if err = conn.makePacket(&frameBuf, packetTypePrngSeed, sf.lenSeed.Bytes()[:], 0); err != nil { -		return +	if err := conn.makePacket(&frameBuf, packetTypePrngSeed, sf.lenSeed.Bytes()[:], 0); err != nil { +		return err  	}  	if _, err = conn.Conn.Write(frameBuf.Bytes()); err != nil { -		return +		return err  	} -	return +	return nil  }  func (conn *obfs4Conn) Read(b []byte) (n int, err error) { diff --git a/transports/obfs4/packet.go b/transports/obfs4/packet.go index 9865c82..461ad54 100644 --- a/transports/obfs4/packet.go +++ b/transports/obfs4/packet.go @@ -69,7 +69,7 @@ func (e InvalidPayloadLengthError) Error() string {  var zeroPadBytes [maxPacketPaddingLength]byte -func (conn *obfs4Conn) makePacket(w io.Writer, pktType uint8, data []byte, padLen uint16) (err error) { +func (conn *obfs4Conn) makePacket(w io.Writer, pktType uint8, data []byte, padLen uint16) error {  	var pkt [framing.MaximumFramePayloadLength]byte  	if len(data)+int(padLen) > maxPacketPayloadLength { @@ -93,22 +93,19 @@ func (conn *obfs4Conn) makePacket(w io.Writer, pktType uint8, data []byte, padLe  	// Encode the packet in an AEAD frame.  	var frame [framing.MaximumSegmentLength]byte -	frameLen := 0 -	frameLen, err = conn.encoder.Encode(frame[:], pkt[:pktLen]) +	frameLen, err := conn.encoder.Encode(frame[:], pkt[:pktLen])  	if err != nil {  		// All encoder errors are fatal. -		return +		return err  	} -	var wrLen int -	wrLen, err = w.Write(frame[:frameLen]) +	wrLen, err := w.Write(frame[:frameLen])  	if err != nil { -		return +		return err  	} else if wrLen < frameLen { -		err = io.ErrShortWrite -		return +		return io.ErrShortWrite  	} -	return +	return nil  }  func (conn *obfs4Conn) readPackets() (err error) { diff --git a/transports/obfs4/statefile.go b/transports/obfs4/statefile.go index 0838180..6c34f35 100644 --- a/transports/obfs4/statefile.go +++ b/transports/obfs4/statefile.go @@ -183,7 +183,7 @@ func jsonServerStateFromFile(stateDir string, js *jsonServerState) error {  		return err  	} -	if err = json.Unmarshal(f, js); err != nil { +	if err := json.Unmarshal(f, js); err != nil {  		return fmt.Errorf("failed to load statefile '%s': %s", fPath, err)  	} @@ -227,7 +227,7 @@ func newJSONServerState(stateDir string, js *jsonServerState) (err error) {  	return nil  } -func newBridgeFile(stateDir string, st *obfs4ServerState) (err error) { +func newBridgeFile(stateDir string, st *obfs4ServerState) error {  	const prefix = "# obfs4 torrc client bridge line\n" +  		"#\n" +  		"# This file is an automatically generated bridge line based on\n" + @@ -244,7 +244,7 @@ func newBridgeFile(stateDir string, st *obfs4ServerState) (err error) {  		st.clientString())  	tmp := []byte(prefix + bridgeLine) -	if err = ioutil.WriteFile(path.Join(stateDir, bridgeFile), tmp, 0600); err != nil { +	if err := ioutil.WriteFile(path.Join(stateDir, bridgeFile), tmp, 0600); err != nil {  		return err  	} diff --git a/transports/scramblesuit/conn.go b/transports/scramblesuit/conn.go index b77bc5f..b8a27c7 100644 --- a/transports/scramblesuit/conn.go +++ b/transports/scramblesuit/conn.go @@ -441,20 +441,23 @@ handshakeUDH:  	}  } -func (conn *ssConn) initCrypto(seed []byte) (err error) { +func (conn *ssConn) initCrypto(seed []byte) error {  	// Use HKDF-SHA256 (Expand only, no Extract) to generate session keys from  	// initial keying material.  	okm := hkdfExpand(sha256.New, seed, nil, kdfSecretLength) -	if conn.txCrypto, err = newCryptoState(okm[0:32], okm[32:40], okm[80:112]); err != nil { -		return +	var err error +	conn.txCrypto, err = newCryptoState(okm[0:32], okm[32:40], okm[80:112]) +	if err != nil { +		return err  	} -	if conn.rxCrypto, err = newCryptoState(okm[40:72], okm[72:80], okm[112:144]); err != nil { -		return +	conn.rxCrypto, err = newCryptoState(okm[40:72], okm[72:80], okm[112:144]) +	if err != nil { +		return err  	} -	return +	return nil  } -func (conn *ssConn) padBurst(burst *bytes.Buffer, sampleLen int) (err error) { +func (conn *ssConn) padBurst(burst *bytes.Buffer, sampleLen int) error {  	// Burst contains the fully encrypted+MACed outgoing payload that will be  	// written to the network.  Pad it out so that the last segment (based on  	// the ScrambleSuit MTU) is sampleLen bytes. @@ -473,18 +476,17 @@ func (conn *ssConn) padBurst(burst *bytes.Buffer, sampleLen int) (err error) {  	}  	if padLen == 0 { -		return -	} else if padLen > maxSegmentLength { +		return nil +	} +	if padLen > maxSegmentLength {  		// Note: packetmorpher.py: getPadding is slightly wrong and only  		// accounts for one of the two packet headers. -		if err = conn.makePacket(burst, pktPayload, nil, 700-pktOverhead); err != nil { -			return +		if err := conn.makePacket(burst, pktPayload, nil, 700-pktOverhead); err != nil { +			return err  		} -		err = conn.makePacket(burst, pktPayload, nil, padLen-(700+2*pktOverhead)) -	} else { -		err = conn.makePacket(burst, pktPayload, nil, padLen-pktOverhead) +		return conn.makePacket(burst, pktPayload, nil, padLen-(700+2*pktOverhead))  	} -	return +	return conn.makePacket(burst, pktPayload, nil, padLen-pktOverhead)  }  func newScrambleSuitClientConn(conn net.Conn, tStore *ssTicketStore, ca *ssClientArgs) (net.Conn, error) {  | 
