aboutsummaryrefslogtreecommitdiffstats
path: root/p2p
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2015-01-19 08:55:24 +0800
committerFelix Lange <fjl@twurst.com>2015-02-06 07:00:34 +0800
commit714b955d6e03a822af80b566b0fa73098761f57a (patch)
treef0fcfdfc7ca66fa415e5753cd73a768f636a8fcd /p2p
parentb855f671a508a7e8160cbdd27197ba83310b264c (diff)
downloaddexon-714b955d6e03a822af80b566b0fa73098761f57a.tar.gz
dexon-714b955d6e03a822af80b566b0fa73098761f57a.tar.zst
dexon-714b955d6e03a822af80b566b0fa73098761f57a.zip
fix crash
- add session token check and fallback to shared secret in responder call too - use explicit length for the types of new messages - fix typo resp[resLen-1] = tokenFlag
Diffstat (limited to 'p2p')
-rw-r--r--p2p/crypto.go51
1 files changed, 29 insertions, 22 deletions
diff --git a/p2p/crypto.go b/p2p/crypto.go
index 6e3f360d9..643bd431e 100644
--- a/p2p/crypto.go
+++ b/p2p/crypto.go
@@ -17,7 +17,7 @@ var (
sigLen int = 65 // elliptic S256
keyLen int = 32 // ECDSA
msgLen int = sigLen + 3*keyLen + 1 // 162
- resLen int = 65
+ resLen int = 65 //
)
// aesSecret, macSecret, egressMac, ingress
@@ -133,7 +133,7 @@ func (self *cryptoId) initAuth(remotePubKeyDER, sessionToken []byte) (auth []byt
}
// verifyAuth is called by peer if it accepted (but not initiated) the connection
-func (self *cryptoId) verifyAuth(auth, sharedSecret []byte, remotePubKey *ecdsa.PublicKey) (authResp []byte, respNonce []byte, initNonce []byte, remoteRandomPubKey *ecdsa.PublicKey, err error) {
+func (self *cryptoId) verifyAuth(auth, sessionToken []byte, remotePubKey *ecdsa.PublicKey) (authResp []byte, respNonce []byte, initNonce []byte, remoteRandomPubKey *ecdsa.PublicKey, err error) {
var msg []byte
fmt.Printf("encrypted message received: %v %x\n used pubkey: %x\n", len(auth), auth, crypto.FromECDSAPub(self.pubKey))
// they prove that msg is meant for me,
@@ -141,50 +141,57 @@ func (self *cryptoId) verifyAuth(auth, sharedSecret []byte, remotePubKey *ecdsa.
if msg, err = crypto.Decrypt(self.prvKey, auth); err != nil {
return
}
+ fmt.Printf("\nplaintext message retrieved: %v %x\n", len(msg), msg)
- // var remoteNonce []byte = msg[msgLen-skLen-1 : msgLen-1]
+ var tokenFlag byte
+ if sessionToken == nil {
+ // no session token found means we need to generate shared secret.
+ // ecies shared secret is used as initial session token for new peers
+ // generate shared key from prv and remote pubkey
+ if sessionToken, err = ecies.ImportECDSA(self.prvKey).GenerateShared(ecies.ImportECDSAPublic(remotePubKey), sskLen, sskLen); err != nil {
+ return
+ }
+ fmt.Printf("secret generated: %v %x", len(sessionToken), sessionToken)
+ // tokenFlag = 0x00 // redundant
+ } else {
+ // for known peers, we use stored token from the previous session
+ tokenFlag = 0x01
+ }
+
+ // the initiator nonce is read off the end of the message
initNonce = msg[msgLen-keyLen-1 : msgLen-1]
// I prove that i own prv key (to derive shared secret, and read nonce off encrypted msg) and that I own shared secret
// they prove they own the private key belonging to ecdhe-random-pubk
- var signedMsg = Xor(sharedSecret, initNonce)
+ // we can now reconstruct the signed message and recover the peers pubkey
+ var signedMsg = Xor(sessionToken, initNonce)
var remoteRandomPubKeyDER []byte
if remoteRandomPubKeyDER, err = secp256k1.RecoverPubkey(signedMsg, msg[:sigLen]); err != nil {
return
}
+ // convert to ECDSA standard
remoteRandomPubKey = crypto.ToECDSAPub(remoteRandomPubKeyDER)
if remoteRandomPubKey == nil {
err = fmt.Errorf("invalid remote public key")
return
}
- var resp = make([]byte, 2*keyLen+1)
- // generate sskLen long nonce
- respNonce = msg[msgLen-keyLen-1 : msgLen-1]
+ // now we find ourselves a long task too, fill it random
+ var resp = make([]byte, resLen)
+ // generate keyLen long nonce
+ respNonce = msg[resLen-keyLen-1 : msgLen-1]
if _, err = rand.Read(respNonce); err != nil {
return
}
- // generate random keypair
+ // generate random keypair for session
var ecdsaRandomPrvKey *ecdsa.PrivateKey
if ecdsaRandomPrvKey, err = crypto.GenerateKey(); err != nil {
return
}
- // var ecdsaRandomPubKey *ecdsa.PublicKey
- // ecdsaRandomPubKey= &ecdsaRandomPrvKey.PublicKey
-
- // message
+ // responder auth message
// E(remote-pubk, ecdhe-random-pubk || nonce || 0x0)
copy(resp[:keyLen], crypto.FromECDSAPub(&ecdsaRandomPrvKey.PublicKey))
- // pubkey copied to the correct segment.
- copy(resp[keyLen:2*keyLen], self.pubKeyDER)
// nonce is already in the slice
- // stick tokenFlag byte to the end
- var tokenFlag byte
- if sharedSecret == nil {
- } else {
- // for known peers, we use stored token from the previous session
- tokenFlag = 0x01
- }
- resp[resLen] = tokenFlag
+ resp[resLen-1] = tokenFlag
// encrypt using remote-pubk
// auth = eciesEncrypt(remote-pubk, msg)