Skip to content

Commit

Permalink
Merge pull request #9 from libp2p/fix/noise-pipes
Browse files Browse the repository at this point in the history
Fix noise pipes support
  • Loading branch information
yusefnapora authored Dec 6, 2019
2 parents ace277e + c3157aa commit 8f13aa4
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 29 deletions.
4 changes: 2 additions & 2 deletions p2p/security/noise/ik/IK.noise.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ func initializeInitiator(prologue []byte, s Keypair, rs [32]byte, psk [32]byte)
var ss symmetricstate
var e Keypair
var re [32]byte
name := []byte("Noise_IK_25519_ChaChaPoly_BLAKE2s")
name := []byte("Noise_IK_25519_ChaChaPoly_SHA256")
ss = initializeSymmetric(name)
mixHash(&ss, prologue)
mixHash(&ss, rs[:])
Expand All @@ -420,7 +420,7 @@ func initializeResponder(prologue []byte, s Keypair, rs [32]byte, psk [32]byte)
var ss symmetricstate
var e Keypair
var re [32]byte
name := []byte("Noise_IK_25519_ChaChaPoly_BLAKE2s")
name := []byte("Noise_IK_25519_ChaChaPoly_SHA256")
ss = initializeSymmetric(name)
mixHash(&ss, prologue)
mixHash(&ss, s.public_key[:])
Expand Down
4 changes: 2 additions & 2 deletions p2p/security/noise/ik_handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ func (s *secureSession) ik_recvHandshakeMessage(initial_stage bool) (buf []byte,
log.Debugf("ik_recvHandshakeMessage initiator=%v msgbuf=%v", s.initiator, msgbuf)

if err != nil {
log.Error("ik_recvHandshakeMessage initiator=%v decode err=%s", s.initiator, err)
log.Errorf("ik_recvHandshakeMessage initiator=%v decode err=%s", s.initiator, err)
return buf, nil, false, fmt.Errorf("ik_recvHandshakeMessage decode msg fail: %s", err)
}

s.ik_ns, plaintext, valid = ik.RecvMessage(s.ik_ns, msgbuf)
if !valid {
log.Error("ik_recvHandshakeMessage initiator=%v err=%s", s.initiator, "validation fail")
log.Errorf("ik_recvHandshakeMessage initiator=%v err=%s", s.initiator, "validation fail")
return buf, nil, false, fmt.Errorf("ik_recvHandshakeMessage validation fail")
}

Expand Down
19 changes: 11 additions & 8 deletions p2p/security/noise/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,15 @@ func (s *secureSession) runHandshake(ctx context.Context) error {
return fmt.Errorf("runHandshake proto marshal payload err=%s", err)
}

// if we have the peer's noise static key (and we're the initiator,) and we support noise pipes,
// we can try IK first. if we support noise pipes and we're not the initiator, try IK first
// otherwise, default to XX
if (!s.initiator && s.noiseStaticKeyCache[s.remotePeer] != [32]byte{}) && s.noisePipesSupport {
// known static key for peer, try IK
// If we support Noise pipes, we try IK first, falling back to XX if IK fails.
// The exception is when we're the initiator and don't know the other party's
// static Noise key. Then IK will always fail, so we go straight to XX.
tryIK := s.noisePipesSupport
if s.initiator && s.noiseStaticKeyCache[s.remotePeer] == [32]byte{} {
tryIK = false
}
if tryIK {
// we're either a responder or an initiator with a known static key for the remote peer, try IK
buf, err := s.runHandshake_ik(ctx, payloadEnc)
if err != nil {
log.Error("runHandshake ik err=%s", err)
Expand All @@ -190,10 +194,9 @@ func (s *secureSession) runHandshake(ctx context.Context) error {
}

s.xx_complete = true
} else {
s.ik_complete = true
}

s.ik_complete = true

} else {
// unknown static key for peer, try XX
err := s.runHandshake_xx(ctx, false, payloadEnc, nil)
Expand Down
34 changes: 18 additions & 16 deletions p2p/security/noise/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ func newConnPair(t *testing.T) (net.Conn, net.Conn) {
func connect(t *testing.T, initTransport, respTransport *Transport) (*secureSession, *secureSession) {
init, resp := newConnPair(t)

var respConn sec.SecureConn
var respErr error
var initConn sec.SecureConn
var initErr error
done := make(chan struct{})
go func() {
defer close(done)
respConn, respErr = respTransport.SecureOutbound(context.TODO(), resp, initTransport.LocalID)
initConn, initErr = initTransport.SecureOutbound(context.TODO(), init, respTransport.LocalID)
}()

initConn, initErr := initTransport.SecureInbound(context.TODO(), init)
respConn, respErr := respTransport.SecureInbound(context.TODO(), resp)
<-done

if initErr != nil {
Expand Down Expand Up @@ -176,25 +176,17 @@ func TestHandshakeXX(t *testing.T) {

// Test IK handshake
func TestHandshakeIK(t *testing.T) {
initTransport := newTestTransport(t, crypto.Ed25519, 2048)
respTransport := newTestTransport(t, crypto.Ed25519, 2048)

// do initial XX handshake
initConn, respConn := connect(t, initTransport, respTransport)
initConn.Close()
respConn.Close()

// turn on pipes, this will turn on IK
initTransport.NoisePipesSupport = true
respTransport.NoisePipesSupport = true
initTransport := newTestTransportPipes(t, crypto.Ed25519, 2048)
respTransport := newTestTransportPipes(t, crypto.Ed25519, 2048)

// add responder's static key to initiator's key cache
respTransport.NoiseKeypair = GenerateKeypair()
keycache := make(map[peer.ID]([32]byte))
keycache[respTransport.LocalID] = respTransport.NoiseKeypair.public_key
initTransport.NoiseStaticKeyCache = keycache

// do IK handshake
initConn, respConn = connect(t, initTransport, respTransport)
initConn, respConn := connect(t, initTransport, respTransport)
defer initConn.Close()
defer respConn.Close()

Expand All @@ -213,6 +205,11 @@ func TestHandshakeIK(t *testing.T) {
if !bytes.Equal(before, after) {
t.Errorf("Message mismatch. %v != %v", before, after)
}

// make sure IK was actually used
if !(initConn.ik_complete && respConn.ik_complete) {
t.Error("Expected IK handshake to be used")
}
}

// Test noise pipes
Expand Down Expand Up @@ -241,4 +238,9 @@ func TestHandshakeXXfallback(t *testing.T) {
if !bytes.Equal(before, after) {
t.Errorf("Message mismatch. %v != %v", before, after)
}

// make sure XX was actually used
if !(initConn.xx_complete && respConn.xx_complete) {
t.Error("Expected XXfallback handshake to be used")
}
}
2 changes: 1 addition & 1 deletion p2p/security/noise/xx_handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func (s *secureSession) runHandshake_xx(ctx context.Context, fallback bool, payl

} else {
var msgbuf *xx.MessageBuffer
msgbuf, err = xx.Decode1(initialMsg)
msgbuf, err = xx.Decode0(initialMsg)
if err != nil {
log.Errorf("runHandshake_xx recv msg err", err)
return err
Expand Down

0 comments on commit 8f13aa4

Please sign in to comment.