1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-28 00:39:31 +08:00

change handshake to use pub/priv keys for verification

This commit is contained in:
Jeromy
2014-09-01 19:04:18 -07:00
parent 45fc43c9cf
commit 48865db1ea
4 changed files with 134 additions and 2 deletions

View File

@ -3,6 +3,7 @@
package identify
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
@ -10,6 +11,7 @@ import (
"errors"
"io/ioutil"
proto "code.google.com/p/goprotobuf/proto"
peer "github.com/jbenet/go-ipfs/peer"
u "github.com/jbenet/go-ipfs/util"
)
@ -17,15 +19,90 @@ import (
// Perform initial communication with this peer to share node ID's and
// initiate communication
func Handshake(self, remote *peer.Peer, in, out chan []byte) error {
// TODO: make this more... secure.
out <- self.ID
encoded, err := buildHandshake(self)
if err != nil {
return err
}
out <- encoded
resp := <-in
pbresp := new(Identify)
err = proto.Unmarshal(resp, pbresp)
if err != nil {
return err
}
// Verify that the given ID matches their given public key
if verifyErr := verifyID(peer.ID(pbresp.GetId()), pbresp.GetPubkey()); verifyErr != nil {
return verifyErr
}
pubkey, err := x509.ParsePKIXPublicKey(pbresp.GetPubkey())
if err != nil {
return err
}
// Challenge peer to ensure they own the given pubkey
secret := make([]byte, 32)
rand.Read(secret)
encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, pubkey.(*rsa.PublicKey), secret)
if err != nil {
//... this is odd
return err
}
out <- encrypted
challenge := <-in
plain, err := rsa.DecryptPKCS1v15(rand.Reader, self.PrivKey.(*rsa.PrivateKey), challenge)
if err != nil {
return err
}
out <- plain
chalResp := <-in
if !bytes.Equal(chalResp, secret) {
return errors.New("Recieved incorrect challenge response!")
}
remote.ID = peer.ID(resp)
remote.PubKey = pubkey
u.DOut("[%s] identify: Got node id: %s\n", self.ID.Pretty(), remote.ID.Pretty())
return nil
}
func buildHandshake(self *peer.Peer) ([]byte, error) {
pkb, err := x509.MarshalPKIXPublicKey(self.PubKey)
if err != nil {
return nil, err
}
pmes := new(Identify)
pmes.Id = []byte(self.ID)
pmes.Pubkey = pkb
encoded, err := proto.Marshal(pmes)
if err != nil {
return nil, err
}
return encoded, nil
}
func verifyID(id peer.ID, pubkey []byte) error {
hash, err := u.Hash(pubkey)
if err != nil {
return err
}
if id.Equal(peer.ID(hash)) {
return nil
}
return errors.New("ID did not match public key!")
}
type KeyPair struct {
Pub crypto.PublicKey
Priv crypto.PrivateKey

48
identify/message.pb.go Normal file
View File

@ -0,0 +1,48 @@
// Code generated by protoc-gen-go.
// source: message.proto
// DO NOT EDIT!
/*
Package identify is a generated protocol buffer package.
It is generated from these files:
message.proto
It has these top-level messages:
Identify
*/
package identify
import proto "code.google.com/p/goprotobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type Identify struct {
Id []byte `protobuf:"bytes,1,req,name=id" json:"id,omitempty"`
Pubkey []byte `protobuf:"bytes,2,req,name=pubkey" json:"pubkey,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Identify) Reset() { *m = Identify{} }
func (m *Identify) String() string { return proto.CompactTextString(m) }
func (*Identify) ProtoMessage() {}
func (m *Identify) GetId() []byte {
if m != nil {
return m.Id
}
return nil
}
func (m *Identify) GetPubkey() []byte {
if m != nil {
return m.Pubkey
}
return nil
}
func init() {
}

View File

@ -1,3 +1,6 @@
package identify;
message Identify {
required bytes id = 1;
required bytes pubkey = 2;
}

View File

@ -1,6 +1,7 @@
package peer
import (
"crypto"
"sync"
"time"
@ -33,6 +34,9 @@ type Peer struct {
ID ID
Addresses []*ma.Multiaddr
PubKey crypto.PublicKey
PrivKey crypto.PrivateKey
latency time.Duration
latenLock sync.RWMutex
}