mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-29 01:12:24 +08:00
change handshake to use pub/priv keys for verification
This commit is contained in:
@ -3,6 +3,7 @@
|
|||||||
package identify
|
package identify
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
proto "code.google.com/p/goprotobuf/proto"
|
||||||
peer "github.com/jbenet/go-ipfs/peer"
|
peer "github.com/jbenet/go-ipfs/peer"
|
||||||
u "github.com/jbenet/go-ipfs/util"
|
u "github.com/jbenet/go-ipfs/util"
|
||||||
)
|
)
|
||||||
@ -17,15 +19,90 @@ import (
|
|||||||
// Perform initial communication with this peer to share node ID's and
|
// Perform initial communication with this peer to share node ID's and
|
||||||
// initiate communication
|
// initiate communication
|
||||||
func Handshake(self, remote *peer.Peer, in, out chan []byte) error {
|
func Handshake(self, remote *peer.Peer, in, out chan []byte) error {
|
||||||
// TODO: make this more... secure.
|
encoded, err := buildHandshake(self)
|
||||||
out <- self.ID
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out <- encoded
|
||||||
resp := <-in
|
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.ID = peer.ID(resp)
|
||||||
|
remote.PubKey = pubkey
|
||||||
u.DOut("[%s] identify: Got node id: %s\n", self.ID.Pretty(), remote.ID.Pretty())
|
u.DOut("[%s] identify: Got node id: %s\n", self.ID.Pretty(), remote.ID.Pretty())
|
||||||
|
|
||||||
return nil
|
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 {
|
type KeyPair struct {
|
||||||
Pub crypto.PublicKey
|
Pub crypto.PublicKey
|
||||||
Priv crypto.PrivateKey
|
Priv crypto.PrivateKey
|
||||||
|
48
identify/message.pb.go
Normal file
48
identify/message.pb.go
Normal 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() {
|
||||||
|
}
|
@ -1,3 +1,6 @@
|
|||||||
|
package identify;
|
||||||
|
|
||||||
message Identify {
|
message Identify {
|
||||||
required bytes id = 1;
|
required bytes id = 1;
|
||||||
|
required bytes pubkey = 2;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -33,6 +34,9 @@ type Peer struct {
|
|||||||
ID ID
|
ID ID
|
||||||
Addresses []*ma.Multiaddr
|
Addresses []*ma.Multiaddr
|
||||||
|
|
||||||
|
PubKey crypto.PublicKey
|
||||||
|
PrivKey crypto.PrivateKey
|
||||||
|
|
||||||
latency time.Duration
|
latency time.Duration
|
||||||
latenLock sync.RWMutex
|
latenLock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user