@cryptotaxi247 / kubo / commits / 0817ffa36

spipe + handshake with peerstore

Juan Batiz-Benet committed Sep 26, 2014 at 02:09 UTC 0817ffa366ea592a604430b7416173bc3fc1d9c4
2 files changed +79 -14
crypto/spipe/handshake.go
+64 -10
@@ -90,23 +90,18 @@ func (s *SecurePipe) handshake() error {
90 return err
91 }
92
93 - s.remote.PubKey, err = ci.UnmarshalPublicKey(proposeResp.GetPubkey())
93 + // get remote identity
94 + remotePubKey, err := ci.UnmarshalPublicKey(proposeResp.GetPubkey())
95 if err != nil {
96 return err
97 }
98
98 - remoteID, err := IDFromPubKey(s.remote.PubKey)
99 + // get or construct peer
100 + s.remote, err = getOrConstructPeer(s.peers, remotePubKey)
101 if err != nil {
102 return err
103 }
102 -
103 - if s.remote.ID != nil && !remoteID.Equal(s.remote.ID) {
104 - e := "Expected pubkey does not match sent pubkey: %v - %v"
105 - return fmt.Errorf(e, s.remote.ID.Pretty(), remoteID.Pretty())
106 - } else if s.remote.ID == nil {
107 - s.remote.ID = remoteID
108 - }
109 - // u.POut("Remote Peer Identified as %s\n", s.remote.ID.Pretty())
104 + u.DOut("[%s] Remote Peer Identified as %s\n", s.local.ID.Pretty(), s.remote.ID.Pretty())
105
106 exchange, err := selectBest(SupportedExchanges, proposeResp.GetExchanges())
107 if err != nil {
@@ -340,3 +335,62 @@ func selectBest(myPrefs, theirPrefs string) (string, error) {
335
336 return "", errors.New("No algorithms in common!")
337 }
338 +
339 +// getOrConstructPeer attempts to fetch a peer from a peerstore.
340 +// if succeeds, verify ID and PubKey match.
341 +// else, construct it.
342 +func getOrConstructPeer(peers peer.Peerstore, rpk ci.PubKey) (*peer.Peer, error) {
343 +
344 + rid, err := IDFromPubKey(rpk)
345 + if err != nil {
346 + return nil, err
347 + }
348 +
349 + npeer, err := peers.Get(rid)
350 + if err != nil {
351 + if err != peer.ErrNotFound {
352 + return nil, err // unexpected error happened.
353 + }
354 +
355 + // dont have peer, so construct it + add it to peerstore.
356 + npeer = &peer.Peer{ID: rid, PubKey: rpk}
357 + if err := peers.Put(npeer); err != nil {
358 + return nil, err
359 + }
360 +
361 + // done, return the newly constructed peer.
362 + return npeer, nil
363 + }
364 +
365 + // did have it locally.
366 +
367 + // let's verify ID
368 + if !npeer.ID.Equal(rid) {
369 + e := "Expected peer.ID does not match sent pubkey's hash: %v - %v"
370 + return nil, fmt.Errorf(e, npeer.ID.Pretty(), rid.Pretty())
371 + }
372 +
373 + if npeer.PubKey == nil {
374 + // didn't have a pubkey, just set it.
375 + npeer.PubKey = rpk
376 + return npeer, nil
377 + }
378 +
379 + // did have pubkey, let's verify it's really the same.
380 + // this shouldn't ever happen, given we hashed, etc, but it could mean
381 + // expected code (or protocol) invariants violated.
382 +
383 + lb, err1 := npeer.PubKey.Bytes()
384 + if err1 != nil {
385 + return nil, err1
386 + }
387 + rb, err2 := rpk.Bytes()
388 + if err2 != nil {
389 + return nil, err2
390 + }
391 +
392 + if !bytes.Equal(lb, rb) {
393 + return nil, fmt.Errorf("WARNING: PubKey mismatch: %v", npeer.ID.Pretty())
394 + }
395 + return npeer, nil
396 +}
crypto/spipe/pipe.go
+15 -4
@@ -20,6 +20,7 @@ type SecurePipe struct {
20
21 local *peer.Peer
22 remote *peer.Peer
23 + peers peer.Peerstore
24
25 params params
26
@@ -32,16 +33,16 @@ type params struct {
33 }
34
35 // NewSecurePipe constructs a pipe with channels of a given buffer size.
35 -func NewSecurePipe(ctx context.Context, bufsize int, local,
36 - remote *peer.Peer) (*SecurePipe, error) {
36 +func NewSecurePipe(ctx context.Context, bufsize int, local *peer.Peer,
37 + peers peer.Peerstore) (*SecurePipe, error) {
38
39 sp := &SecurePipe{
40 Duplex: Duplex{
41 In: make(chan []byte, bufsize),
42 Out: make(chan []byte, bufsize),
43 },
43 - local: local,
44 - remote: remote,
44 + local: local,
45 + peers: peers,
46 }
47 return sp, nil
48 }
@@ -63,6 +64,16 @@ func (s *SecurePipe) Wrap(ctx context.Context, insecure Duplex) error {
64 return nil
65 }
66
67 +// LocalPeer retrieves the local peer.
68 +func (s *SecurePipe) LocalPeer() *peer.Peer {
69 + return s.local
70 +}
71 +
72 +// RemotePeer retrieves the local peer.
73 +func (s *SecurePipe) RemotePeer() *peer.Peer {
74 + return s.remote
75 +}
76 +
77 // Close closes the secure pipe
78 func (s *SecurePipe) Close() error {
79 if s.cancel == nil {