forked from cerc-io/plugeth
key generation abstracted out, for testing with deterministic keys
This commit is contained in:
parent
488a042736
commit
2e48d39fc7
@ -1,6 +1,7 @@
|
|||||||
package p2p
|
package p2p
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
// "binary"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -38,6 +39,33 @@ func (self hexkey) String() string {
|
|||||||
return fmt.Sprintf("(%d) %x", len(self), []byte(self))
|
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.
|
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.
|
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) {
|
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 auth, initNonce, recNonce []byte
|
||||||
var read int
|
var read int
|
||||||
@ -178,7 +205,8 @@ func startHandshake(prvKey *ecdsa.PrivateKey, remotePubKeyS, sessionToken []byte
|
|||||||
// allocate msgLen long message,
|
// allocate msgLen long message,
|
||||||
var msg []byte = make([]byte, msgLen)
|
var msg []byte = make([]byte, msgLen)
|
||||||
initNonce = msg[msgLen-shaLen-1 : msgLen-1]
|
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
|
return
|
||||||
}
|
}
|
||||||
// create known message
|
// create known message
|
||||||
@ -187,7 +215,8 @@ func startHandshake(prvKey *ecdsa.PrivateKey, remotePubKeyS, sessionToken []byte
|
|||||||
var sharedSecret = Xor(sessionToken, initNonce)
|
var sharedSecret = Xor(sessionToken, initNonce)
|
||||||
|
|
||||||
// generate random keypair to use for signing
|
// 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
|
return
|
||||||
}
|
}
|
||||||
// sign shared secret (message known to both parties): shared-secret
|
// 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)
|
var resp = make([]byte, resLen)
|
||||||
// generate shaLen long nonce
|
// generate shaLen long nonce
|
||||||
respNonce = resp[pubLen : pubLen+shaLen]
|
respNonce = resp[pubLen : pubLen+shaLen]
|
||||||
if _, err = rand.Read(respNonce); err != nil {
|
fmt.Printf("rec-nonce: ")
|
||||||
|
if _, err = nonceF(respNonce); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// generate random keypair for session
|
// 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
|
return
|
||||||
}
|
}
|
||||||
// responder auth message
|
// responder auth message
|
||||||
|
@ -2,9 +2,7 @@ package p2p
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
// "crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
// "crypto/elliptic"
|
|
||||||
// "crypto/rand"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
@ -71,11 +69,60 @@ func TestSharedSecret(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCryptoHandshake(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 err error
|
||||||
var sessionToken []byte
|
|
||||||
prv0, _ := crypto.GenerateKey() // = ecdsa.GenerateKey(crypto.S256(), rand.Reader)
|
|
||||||
pub0 := &prv0.PublicKey
|
pub0 := &prv0.PublicKey
|
||||||
prv1, _ := crypto.GenerateKey()
|
|
||||||
pub1 := &prv1.PublicKey
|
pub1 := &prv1.PublicKey
|
||||||
|
|
||||||
pub0s := crypto.FromECDSAPub(pub0)
|
pub0s := crypto.FromECDSAPub(pub0)
|
||||||
@ -87,12 +134,14 @@ func TestCryptoHandshake(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%v", err)
|
t.Errorf("%v", err)
|
||||||
}
|
}
|
||||||
|
fmt.Printf("-> %v\n", hexkey(auth))
|
||||||
|
|
||||||
// receiver reads auth and responds with response
|
// receiver reads auth and responds with response
|
||||||
response, remoteRecNonce, remoteInitNonce, remoteRandomPrivKey, remoteInitRandomPubKey, err := respondToHandshake(auth, prv1, pub0s, sessionToken)
|
response, remoteRecNonce, remoteInitNonce, remoteRandomPrivKey, remoteInitRandomPubKey, err := respondToHandshake(auth, prv1, pub0s, sessionToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%v", err)
|
t.Errorf("%v", err)
|
||||||
}
|
}
|
||||||
|
fmt.Printf("<- %v\n", hexkey(response))
|
||||||
|
|
||||||
// initiator reads receiver's response and the key exchange completes
|
// initiator reads receiver's response and the key exchange completes
|
||||||
recNonce, remoteRandomPubKey, _, err := completeHandshake(response, prv0)
|
recNonce, remoteRandomPubKey, _, err := completeHandshake(response, prv0)
|
||||||
@ -111,7 +160,7 @@ func TestCryptoHandshake(t *testing.T) {
|
|||||||
t.Errorf("%v", err)
|
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)
|
// 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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user