From 1803c65e4097b9d6cb83f72a8a09aeddcc01f685 Mon Sep 17 00:00:00 2001
From: zelig <viktor.tron@gmail.com>
Date: Mon, 19 Jan 2015 11:21:13 +0000
Subject: [PATCH] integrate cryptoId into peer and connection lifecycle

---
 p2p/crypto.go | 15 +++++++++++++++
 p2p/peer.go   | 21 ++++++++++++++++++---
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/p2p/crypto.go b/p2p/crypto.go
index 37c6e1fc9..728b8e884 100644
--- a/p2p/crypto.go
+++ b/p2p/crypto.go
@@ -53,6 +53,21 @@ func newCryptoId(id ClientIdentity) (self *cryptoId, err error) {
 	return
 }
 
+func (self *cryptoId) Run(remotePubKeyDER []byte) (rw *secretRW) {
+	if self.initiator {
+		auth, initNonce, randomPrvKey, randomPubKey, err := initiator.initAuth(remotePubKeyDER, sessionToken)
+
+		respNonce, remoteRandomPubKey, _, _ := initiator.verifyAuthResp(response)
+	} else {
+		// we are listening connection. we are responders in the haandshake.
+		// Extract info from the authentication. The initiator starts by sending us a handshake that we need to respond to.
+		response, remoteRespNonce, remoteInitNonce, remoteRandomPrivKey, _ := responder.verifyAuth(auth, sessionToken, pubInit)
+
+	}
+	initSessionToken, initSecretRW, _ := initiator.newSession(initNonce, respNonce, auth, randomPrvKey, remoteRandomPubKey)
+	respSessionToken, respSecretRW, _ := responder.newSession(remoteInitNonce, remoteRespNonce, auth, remoteRandomPrivKey, randomPubKey)
+}
+
 /* startHandshake is called by peer if it initiated the connection.
  By protocol spec, the party who initiates the connection (initiator) will send an 'auth' packet
 New: authInitiator -> E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0)
diff --git a/p2p/peer.go b/p2p/peer.go
index 886b95a80..e98c3d560 100644
--- a/p2p/peer.go
+++ b/p2p/peer.go
@@ -222,10 +222,14 @@ func (p *Peer) loop() (reason DiscReason, err error) {
 	defer close(p.closed)
 	defer p.conn.Close()
 
+	var readLoop func(chan Msg, chan error, chan bool)
 	if p.cryptoHandshake {
-		if err := p.handleCryptoHandshake(); err != nil {
+		if readLoop, err := p.handleCryptoHandshake(); err != nil {
+			// from here on everything can be encrypted, authenticated
 			return DiscProtocolError, err // no graceful disconnect
 		}
+	} else {
+		readLoop = p.readLoop
 	}
 
 	// read loop
@@ -233,7 +237,7 @@ func (p *Peer) loop() (reason DiscReason, err error) {
 	readErr := make(chan error)
 	readNext := make(chan bool, 1)
 	protoDone := make(chan struct{}, 1)
-	go p.readLoop(readMsg, readErr, readNext)
+	go readLoop(readMsg, readErr, readNext)
 	readNext <- true
 
 	if p.runBaseProtocol {
@@ -329,8 +333,19 @@ func (p *Peer) dispatch(msg Msg, protoDone chan struct{}) (wait bool, err error)
 }
 
 func (p *Peer) handleCryptoHandshake() (err error) {
+	// cryptoId is just created for the lifecycle of the handshake
+	// it is survived by an encrypted readwriter
+	if p.dialAddr != 0 { // this should have its own method Outgoing() bool
+		initiator = true
+	}
+	// create crypto layer
+	cryptoId := newCryptoId(p.identity, initiator, sessionToken)
+	// run on peer
+	if rw, err := cryptoId.Run(p.Pubkey()); err != nil {
+		return err
+	}
+	p.conn = rw.Run(p.conn)
 
-	return nil
 }
 
 func (p *Peer) startBaseProtocol() {
-- 
GitLab