github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/crypto/secio/interface.go (about) 1 // package secio handles establishing secure communication between two peers. 2 package secio 3 4 import ( 5 "io" 6 7 ci "github.com/ipfs/go-ipfs/p2p/crypto" 8 9 msgio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio" 10 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" 11 peer "github.com/ipfs/go-ipfs/p2p/peer" 12 ) 13 14 // SessionGenerator constructs secure communication sessions for a peer. 15 type SessionGenerator struct { 16 LocalID peer.ID 17 PrivateKey ci.PrivKey 18 } 19 20 // NewSession takes an insecure io.ReadWriter, sets up a TLS-like 21 // handshake with the other side, and returns a secure session. 22 // The handshake isn't run until the connection is read or written to. 23 // See the source for the protocol details and security implementation. 24 // The provided Context is only needed for the duration of this function. 25 func (sg *SessionGenerator) NewSession(ctx context.Context, insecure io.ReadWriteCloser) (Session, error) { 26 return newSecureSession(ctx, sg.LocalID, sg.PrivateKey, insecure) 27 } 28 29 type Session interface { 30 // ReadWriter returns the encrypted communication channel 31 ReadWriter() msgio.ReadWriteCloser 32 33 // LocalPeer retrieves the local peer. 34 LocalPeer() peer.ID 35 36 // LocalPrivateKey retrieves the local private key 37 LocalPrivateKey() ci.PrivKey 38 39 // RemotePeer retrieves the remote peer. 40 RemotePeer() peer.ID 41 42 // RemotePublicKey retrieves the remote's public key 43 // which was received during the handshake. 44 RemotePublicKey() ci.PubKey 45 46 // Close closes the secure session 47 Close() error 48 } 49 50 // SecureReadWriter returns the encrypted communication channel 51 func (s *secureSession) ReadWriter() msgio.ReadWriteCloser { 52 if err := s.Handshake(); err != nil { 53 return &closedRW{err} 54 } 55 return s.secure 56 } 57 58 // LocalPeer retrieves the local peer. 59 func (s *secureSession) LocalPeer() peer.ID { 60 return s.localPeer 61 } 62 63 // LocalPrivateKey retrieves the local peer's PrivateKey 64 func (s *secureSession) LocalPrivateKey() ci.PrivKey { 65 return s.localKey 66 } 67 68 // RemotePeer retrieves the remote peer. 69 func (s *secureSession) RemotePeer() peer.ID { 70 if err := s.Handshake(); err != nil { 71 return "" 72 } 73 return s.remotePeer 74 } 75 76 // RemotePeer retrieves the remote peer. 77 func (s *secureSession) RemotePublicKey() ci.PubKey { 78 if err := s.Handshake(); err != nil { 79 return nil 80 } 81 return s.remote.permanentPubKey 82 } 83 84 // Close closes the secure session 85 func (s *secureSession) Close() error { 86 s.cancel() 87 s.handshakeMu.Lock() 88 defer s.handshakeMu.Unlock() 89 if s.secure == nil { 90 return s.insecure.Close() // hadn't secured yet. 91 } 92 return s.secure.Close() 93 } 94 95 // closedRW implements a stub msgio interface that's already 96 // closed and errored. 97 type closedRW struct { 98 err error 99 } 100 101 func (c *closedRW) Read(buf []byte) (int, error) { 102 return 0, c.err 103 } 104 105 func (c *closedRW) Write(buf []byte) (int, error) { 106 return 0, c.err 107 } 108 109 func (c *closedRW) NextMsgLen() (int, error) { 110 return 0, c.err 111 } 112 113 func (c *closedRW) ReadMsg() ([]byte, error) { 114 return nil, c.err 115 } 116 117 func (c *closedRW) WriteMsg(buf []byte) error { 118 return c.err 119 } 120 121 func (c *closedRW) Close() error { 122 return c.err 123 } 124 125 func (c *closedRW) ReleaseMsg(m []byte) { 126 }