ソースを参照

integrate cryptoId into peer and connection lifecycle

zelig 10 年 前
コミット
1803c65e40
2 ファイル変更33 行追加3 行削除
  1. 15 0
      p2p/crypto.go
  2. 18 3
      p2p/peer.go

+ 15 - 0
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)

+ 18 - 3
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() {