Эх сурвалжийг харах

key generation abstracted out, for testing with deterministic keys

zelig 10 жил өмнө
parent
commit
2e48d39fc7
2 өөрчлөгдсөн 92 нэмэгдсэн , 12 устгасан
  1. 36 5
      p2p/crypto.go
  2. 56 7
      p2p/crypto_test.go

+ 36 - 5
p2p/crypto.go

@@ -1,6 +1,7 @@
 package p2p
 
 import (
+	// "binary"
 	"crypto/ecdsa"
 	"crypto/rand"
 	"fmt"
@@ -38,6 +39,33 @@ func (self hexkey) String() string {
 	return fmt.Sprintf("(%d) %x", len(self), []byte(self))
 }
 
+var nonceF = func(b []byte) (n int, err error) {
+	return rand.Read(b)
+}
+
+var step = 0
+var detnonceF = func(b []byte) (n int, err error) {
+	step++
+	copy(b, crypto.Sha3([]byte("privacy"+string(step))))
+	fmt.Printf("detkey %v: %v\n", step, hexkey(b))
+	return
+}
+
+var keyF = func() (priv *ecdsa.PrivateKey, err error) {
+	priv, err = ecdsa.GenerateKey(crypto.S256(), rand.Reader)
+	if err != nil {
+		return
+	}
+	return
+}
+
+var detkeyF = func() (priv *ecdsa.PrivateKey, err error) {
+	s := make([]byte, 32)
+	detnonceF(s)
+	priv = crypto.ToECDSA(s)
+	return
+}
+
 /*
 NewSecureSession(connection, privateKey, remotePublicKey, sessionToken, initiator) is called when the peer connection starts to set up a secure session by performing a crypto handshake.
 
@@ -53,7 +81,6 @@ NewSecureSession(connection, privateKey, remotePublicKey, sessionToken, initiato
 
  It returns a secretRW which implements the MsgReadWriter interface.
 */
-
 func NewSecureSession(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, remotePubKeyS []byte, sessionToken []byte, initiator bool) (token []byte, rw *secretRW, err error) {
 	var auth, initNonce, recNonce []byte
 	var read int
@@ -178,7 +205,8 @@ func startHandshake(prvKey *ecdsa.PrivateKey, remotePubKeyS, sessionToken []byte
 	// allocate msgLen long message,
 	var msg []byte = make([]byte, msgLen)
 	initNonce = msg[msgLen-shaLen-1 : msgLen-1]
-	if _, err = rand.Read(initNonce); err != nil {
+	fmt.Printf("init-nonce: ")
+	if _, err = nonceF(initNonce); err != nil {
 		return
 	}
 	// create known message
@@ -187,7 +215,8 @@ func startHandshake(prvKey *ecdsa.PrivateKey, remotePubKeyS, sessionToken []byte
 	var sharedSecret = Xor(sessionToken, initNonce)
 
 	// generate random keypair to use for signing
-	if randomPrvKey, err = crypto.GenerateKey(); err != nil {
+	fmt.Printf("init-random-ecdhe-private-key: ")
+	if randomPrvKey, err = keyF(); err != nil {
 		return
 	}
 	// sign shared secret (message known to both parties): shared-secret
@@ -278,11 +307,13 @@ func respondToHandshake(auth []byte, prvKey *ecdsa.PrivateKey, remotePubKeyS, se
 	var resp = make([]byte, resLen)
 	// generate shaLen long nonce
 	respNonce = resp[pubLen : pubLen+shaLen]
-	if _, err = rand.Read(respNonce); err != nil {
+	fmt.Printf("rec-nonce: ")
+	if _, err = nonceF(respNonce); err != nil {
 		return
 	}
 	// generate random keypair for session
-	if randomPrivKey, err = crypto.GenerateKey(); err != nil {
+	fmt.Printf("rec-random-ecdhe-private-key: ")
+	if randomPrivKey, err = keyF(); err != nil {
 		return
 	}
 	// responder auth message

+ 56 - 7
p2p/crypto_test.go

@@ -2,9 +2,7 @@ package p2p
 
 import (
 	"bytes"
-	// "crypto/ecdsa"
-	// "crypto/elliptic"
-	// "crypto/rand"
+	"crypto/ecdsa"
 	"fmt"
 	"net"
 	"testing"
@@ -71,11 +69,60 @@ func TestSharedSecret(t *testing.T) {
 }
 
 func TestCryptoHandshake(t *testing.T) {
+	testCryptoHandshakeWithGen(false, t)
+}
+
+func TestTokenCryptoHandshake(t *testing.T) {
+	testCryptoHandshakeWithGen(true, t)
+}
+
+func TestDetCryptoHandshake(t *testing.T) {
+	defer testlog(t).detach()
+	tmpkeyF := keyF
+	keyF = detkeyF
+	tmpnonceF := nonceF
+	nonceF = detnonceF
+	testCryptoHandshakeWithGen(false, t)
+	keyF = tmpkeyF
+	nonceF = tmpnonceF
+}
+
+func TestDetTokenCryptoHandshake(t *testing.T) {
+	defer testlog(t).detach()
+	tmpkeyF := keyF
+	keyF = detkeyF
+	tmpnonceF := nonceF
+	nonceF = detnonceF
+	testCryptoHandshakeWithGen(true, t)
+	keyF = tmpkeyF
+	nonceF = tmpnonceF
+}
+
+func testCryptoHandshakeWithGen(token bool, t *testing.T) {
+	fmt.Printf("init-private-key: ")
+	prv0, err := keyF()
+	if err != nil {
+		t.Errorf("%v", err)
+		return
+	}
+	fmt.Printf("rec-private-key: ")
+	prv1, err := keyF()
+	if err != nil {
+		t.Errorf("%v", err)
+		return
+	}
+	var nonce []byte
+	if token {
+		fmt.Printf("session-token: ")
+		nonce = make([]byte, shaLen)
+		nonceF(nonce)
+	}
+	testCryptoHandshake(prv0, prv1, nonce, t)
+}
+
+func testCryptoHandshake(prv0, prv1 *ecdsa.PrivateKey, sessionToken []byte, t *testing.T) {
 	var err error
-	var sessionToken []byte
-	prv0, _ := crypto.GenerateKey() // = ecdsa.GenerateKey(crypto.S256(), rand.Reader)
 	pub0 := &prv0.PublicKey
-	prv1, _ := crypto.GenerateKey()
 	pub1 := &prv1.PublicKey
 
 	pub0s := crypto.FromECDSAPub(pub0)
@@ -87,12 +134,14 @@ func TestCryptoHandshake(t *testing.T) {
 	if err != nil {
 		t.Errorf("%v", err)
 	}
+	fmt.Printf("-> %v\n", hexkey(auth))
 
 	// receiver reads auth and responds with response
 	response, remoteRecNonce, remoteInitNonce, remoteRandomPrivKey, remoteInitRandomPubKey, err := respondToHandshake(auth, prv1, pub0s, sessionToken)
 	if err != nil {
 		t.Errorf("%v", err)
 	}
+	fmt.Printf("<- %v\n", hexkey(response))
 
 	// initiator reads receiver's response and the key exchange completes
 	recNonce, remoteRandomPubKey, _, err := completeHandshake(response, prv0)
@@ -111,7 +160,7 @@ func TestCryptoHandshake(t *testing.T) {
 		t.Errorf("%v", err)
 	}
 
-	fmt.Printf("\nauth (%v) %x\n\nresp (%v) %x\n\n", len(auth), auth, len(response), response)
+	// fmt.Printf("\nauth (%v) %x\n\nresp (%v) %x\n\n", len(auth), auth, len(response), response)
 
 	// fmt.Printf("\nauth %x\ninitNonce %x\nresponse%x\nremoteRecNonce %x\nremoteInitNonce %x\nremoteRandomPubKey %x\nrecNonce %x\nremoteInitRandomPubKey %x\ninitSessionToken %x\n\n", auth, initNonce, response, remoteRecNonce, remoteInitNonce, remoteRandomPubKey, recNonce, remoteInitRandomPubKey, initSessionToken)