[Pkg-privacy-commits] [obfs4proxy] 57/151: Move utils.go to csrand/csrand.go, and clean up the interface.

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 12:59:38 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository obfs4proxy.

commit b3f0f51775ae2e19c62c70e15f77ef991ad4bb49
Author: Yawning Angel <yawning at schwanenlied.me>
Date:   Sat May 24 04:47:10 2014 +0000

    Move utils.go to csrand/csrand.go, and clean up the interface.
    
    All of the obfs4 code except unit tests now uses the csrand wrapper
    routines.
---
 utils.go => csrand/csrand.go | 42 +++++++++++++++++++++++++++++++++++-------
 handshake_ntor.go            |  8 ++++----
 ntor/ntor.go                 |  5 +++--
 obfs4.go                     |  6 +++---
 replay_filter.go             |  5 +++--
 weighted_dist.go             |  7 ++++---
 6 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/utils.go b/csrand/csrand.go
similarity index 59%
rename from utils.go
rename to csrand/csrand.go
index 51d99d8..1700b02 100644
--- a/utils.go
+++ b/csrand/csrand.go
@@ -25,10 +25,16 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-package obfs4
+// Package csrand implements the math/rand interface over crypto/rand, along
+// with some utility functions for common random number/byte related tasks.
+//
+// Not all of the convinience routines are replicated, only those that are
+// useful for obfs4.  The CsRand variable provides access to the full math/rand
+// API.
+package csrand
 
 import (
-	csrand "crypto/rand"
+	cryptRand "crypto/rand"
 	"fmt"
 	"math/big"
 	"math/rand"
@@ -36,7 +42,9 @@ import (
 
 var (
 	csRandSourceInstance csRandSource
-	csRandInstance       = rand.New(csRandSourceInstance)
+
+	// CsRand is a math/rand instance backed by crypto/rand CSPRNG.
+	CsRand       = rand.New(csRandSourceInstance)
 )
 
 type csRandSource struct {
@@ -44,7 +52,7 @@ type csRandSource struct {
 }
 
 func (r csRandSource) Int63() int64 {
-	ret, err := csrand.Int(csrand.Reader, big.NewInt(int64((1<<63)-1)))
+	ret, err := cryptRand.Int(cryptRand.Reader, big.NewInt(int64((1<<63)-1)))
 	if err != nil {
 		panic(err)
 	}
@@ -56,14 +64,34 @@ func (r csRandSource) Seed(seed int64) {
 	// No-op.
 }
 
-func randRange(min, max int) int {
+// Float64 returns, as a float 64, a pesudo random number in [0.0,1.0).
+func Float64() float64 {
+	return CsRand.Float64()
+}
+
+// IntRange returns a uniformly distributed int [min, max].
+func IntRange(min, max int) int {
 	if max < min {
-		panic(fmt.Sprintf("randRange: min > max (%d, %d)", min, max))
+		panic(fmt.Sprintf("IntRange: min > max (%d, %d)", min, max))
 	}
 
 	r := (max + 1) - min
-	ret := csRandInstance.Intn(r)
+	ret := CsRand.Intn(r)
 	return ret + min
 }
 
+// Bytes fills the slice with random data.
+func Bytes(buf []byte) error {
+	n, err := cryptRand.Read(buf)
+	if err != nil {
+		// Yes, the go idiom is to check the length, but we panic() when it
+		// does not match because the system is screwed at that point.
+		return err
+	} else if n != len(buf) {
+		panic(fmt.Sprintf("Bytes: truncated rand.Read (%d, %d)", n, len(buf)))
+	}
+
+	return nil
+}
+
 /* vim :set ts=4 sw=4 sts=4 noet : */
diff --git a/handshake_ntor.go b/handshake_ntor.go
index 8baa382..fc107c2 100644
--- a/handshake_ntor.go
+++ b/handshake_ntor.go
@@ -30,7 +30,6 @@ package obfs4
 import (
 	"bytes"
 	"crypto/hmac"
-	"crypto/rand"
 	"crypto/sha256"
 	"encoding/hex"
 	"errors"
@@ -39,6 +38,7 @@ import (
 	"strconv"
 	"time"
 
+	"github.com/yawning/obfs4/csrand"
 	"github.com/yawning/obfs4/framing"
 	"github.com/yawning/obfs4/ntor"
 )
@@ -131,7 +131,7 @@ func newClientHandshake(nodeID *ntor.NodeID, serverIdentity *ntor.PublicKey) (*c
 	}
 	hs.nodeID = nodeID
 	hs.serverIdentity = serverIdentity
-	hs.padLen = randRange(clientMinPadLength, clientMaxPadLength)
+	hs.padLen = csrand.IntRange(clientMinPadLength, clientMaxPadLength)
 	hs.mac = hmac.New(sha256.New, append(hs.serverIdentity.Bytes()[:], hs.nodeID.Bytes()[:]...))
 
 	return hs, nil
@@ -245,7 +245,7 @@ func newServerHandshake(nodeID *ntor.NodeID, serverIdentity *ntor.Keypair) *serv
 	hs := new(serverHandshake)
 	hs.nodeID = nodeID
 	hs.serverIdentity = serverIdentity
-	hs.padLen = randRange(serverMinPadLength, serverMaxPadLength)
+	hs.padLen = csrand.IntRange(serverMinPadLength, serverMaxPadLength)
 	hs.mac = hmac.New(sha256.New, append(hs.serverIdentity.Public().Bytes()[:], hs.nodeID.Bytes()[:]...))
 
 	return hs
@@ -428,7 +428,7 @@ func findMarkMac(mark, buf []byte, startPos, maxPos int, fromTail bool) (pos int
 
 func makePad(padLen int) ([]byte, error) {
 	pad := make([]byte, padLen)
-	_, err := rand.Read(pad)
+	err := csrand.Bytes(pad)
 	if err != nil {
 		return nil, err
 	}
diff --git a/ntor/ntor.go b/ntor/ntor.go
index eecf038..4483a6b 100644
--- a/ntor/ntor.go
+++ b/ntor/ntor.go
@@ -39,7 +39,6 @@ package ntor
 import (
 	"bytes"
 	"crypto/hmac"
-	"crypto/rand"
 	"crypto/sha256"
 	"crypto/subtle"
 	"encoding/base64"
@@ -50,6 +49,8 @@ import (
 	"code.google.com/p/go.crypto/hkdf"
 
 	"github.com/agl/ed25519/extra25519"
+
+	"github.com/yawning/obfs4/csrand"
 )
 
 const (
@@ -266,7 +267,7 @@ func NewKeypair(elligator bool) (*Keypair, error) {
 		// Generate a Curve25519 private key.  Like everyone who does this,
 		// run the CSPRNG output through SHA256 for extra tinfoil hattery.
 		priv := keypair.private.Bytes()[:]
-		_, err := rand.Read(priv)
+		err := csrand.Bytes(priv)
 		if err != nil {
 			return nil, err
 		}
diff --git a/obfs4.go b/obfs4.go
index 3bbccb3..6978a97 100644
--- a/obfs4.go
+++ b/obfs4.go
@@ -51,7 +51,7 @@ const (
 	maxCloseDelayBytes = maxHandshakeLength
 	maxCloseDelay      = 60
 
-	maxIatDelay        = 100
+	maxIatDelay = 100
 )
 
 type connState int
@@ -472,7 +472,7 @@ func (c *Obfs4Conn) Write(b []byte) (n int, err error) {
 			if err != nil {
 				return 0, err
 			}
-		    time.Sleep(iatDelta * time.Microsecond)
+			time.Sleep(iatDelta * time.Microsecond)
 		}
 	} else {
 		_, err = c.conn.Write(frameBuf.Bytes())
@@ -584,7 +584,7 @@ type Obfs4Listener struct {
 	keyPair *ntor.Keypair
 	nodeID  *ntor.NodeID
 
-	seed *DrbgSeed
+	seed           *DrbgSeed
 	iatObfuscation bool
 
 	closeDelayBytes int
diff --git a/replay_filter.go b/replay_filter.go
index 5e98b89..9556ef4 100644
--- a/replay_filter.go
+++ b/replay_filter.go
@@ -29,11 +29,12 @@ package obfs4
 
 import (
 	"container/list"
-	"crypto/rand"
 	"encoding/binary"
 	"sync"
 
 	"github.com/dchest/siphash"
+
+	"github.com/yawning/obfs4/csrand"
 )
 
 // maxFilterSize is the maximum capacity of the replay filter.  The busiest
@@ -63,7 +64,7 @@ type filterEntry struct {
 func newReplayFilter() (filter *replayFilter, err error) {
 	// Initialize the SipHash-2-4 instance with a random key.
 	var key [16]byte
-	_, err = rand.Read(key[:])
+	err = csrand.Bytes(key[:])
 	if err != nil {
 		return
 	}
diff --git a/weighted_dist.go b/weighted_dist.go
index af0fa7d..04b0d2d 100644
--- a/weighted_dist.go
+++ b/weighted_dist.go
@@ -28,7 +28,6 @@
 package obfs4
 
 import (
-	csrand "crypto/rand"
 	"encoding/base64"
 	"encoding/binary"
 	"fmt"
@@ -36,6 +35,8 @@ import (
 	"math/rand"
 
 	"github.com/dchest/siphash"
+
+	"github.com/yawning/obfs4/csrand"
 )
 
 // DrbgSeedLength is the length of the hashDrbg seed.
@@ -58,7 +59,7 @@ func (seed *DrbgSeed) Base64() string {
 // NewDrbgSeed returns a DrbgSeed initialized with the runtime CSPRNG.
 func NewDrbgSeed() (seed *DrbgSeed, err error) {
 	seed = new(DrbgSeed)
-	_, err = csrand.Read(seed.Bytes()[:])
+	err = csrand.Bytes(seed.Bytes()[:])
 	if err != nil {
 		return nil, err
 	}
@@ -160,7 +161,7 @@ func newWDist(seed *DrbgSeed, min, max int) (w *wDist) {
 func (w *wDist) sample() int {
 	retIdx := 0
 	totalProb := 0.0
-	prob := csRandInstance.Float64()
+	prob := csrand.Float64()
 	for i, bucketProb := range w.buckets {
 		totalProb += bucketProb
 		if prob <= totalProb {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/obfs4proxy.git



More information about the Pkg-privacy-commits mailing list