Refactoring
This commit is contained in:
parent
7702e9b8be
commit
9f7564448d
|
@ -57,7 +57,7 @@ func (e *EchoProtocol) onEchoRequest(s inet.Stream) {
|
|||
// send response to the request using the message string he provided
|
||||
|
||||
resp := &p2p.EchoResponse{
|
||||
MessageData: NewMessageData(e.node, data.MessageData.Id, false),
|
||||
MessageData: e.node.NewMessageData(data.MessageData.Id, false),
|
||||
Message: data.Message}
|
||||
|
||||
// sign the data
|
||||
|
@ -121,7 +121,7 @@ func (e *EchoProtocol) Echo(host host.Host) bool {
|
|||
|
||||
// create message data
|
||||
req := &p2p.EchoRequest{
|
||||
MessageData: NewMessageData(e.node, uuid.New().String(), false),
|
||||
MessageData: e.node.NewMessageData(uuid.New().String(), false),
|
||||
Message: fmt.Sprintf("Echo from %s", e.node.ID())}
|
||||
|
||||
signature, err := e.node.signProtoMessage(req)
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"github.com/gogo/protobuf/proto"
|
||||
host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
|
||||
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
|
||||
|
||||
crypto "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Node type - a p2p host implementing one or more p2p protocols
|
||||
|
@ -18,7 +18,7 @@ type Node struct {
|
|||
// add other protocols here...
|
||||
}
|
||||
|
||||
// create a new node with its implemented protocols
|
||||
// Create a new node with its implemented protocols
|
||||
func NewNode(host host.Host, done chan bool) *Node {
|
||||
node := &Node{Host: host}
|
||||
node.PingProtocol = NewPingProtocol(node, done)
|
||||
|
@ -26,13 +26,16 @@ func NewNode(host host.Host, done chan bool) *Node {
|
|||
return node
|
||||
}
|
||||
|
||||
// Authenticate incoming p2p message
|
||||
// message: a protobufs go data object
|
||||
// data: common p2p message data
|
||||
func (n *Node) authenticateMessage(message proto.Message, data *p2p.MessageData) bool {
|
||||
|
||||
// store a temp ref to sig and remove it from data
|
||||
// store a temp ref to signature and remove it from message data
|
||||
sign := data.Sign
|
||||
data.Sign = ""
|
||||
|
||||
// marshall data without the sig to binary format
|
||||
// marshall data without the signature to protobufs3 binary format
|
||||
bin, err := proto.Marshal(message)
|
||||
if err != nil {
|
||||
log.Println(err, "failed to marshal pb message")
|
||||
|
@ -42,15 +45,19 @@ func (n *Node) authenticateMessage(message proto.Message, data *p2p.MessageData)
|
|||
// restore sig in message data (for possible future use)
|
||||
data.Sign = sign
|
||||
|
||||
// restore peer id binary format from base58 encoded node id data
|
||||
peerId, err := peer.IDB58Decode(data.NodeId)
|
||||
if err != nil {
|
||||
log.Println(err, "Failed to decode node id from base58")
|
||||
return false
|
||||
}
|
||||
|
||||
// verify the data was authored by the signing peer identified by the public key
|
||||
// and signature included in the message
|
||||
return n.verifyData(bin, []byte(sign), peerId, data.NodePubKey)
|
||||
}
|
||||
|
||||
// sign an outgoing p2p message payload
|
||||
func (n *Node) signProtoMessage(message proto.Message) ([]byte, error) {
|
||||
data, err := proto.Marshal(message)
|
||||
if err != nil {
|
||||
|
@ -59,17 +66,20 @@ func (n *Node) signProtoMessage(message proto.Message) ([]byte, error) {
|
|||
return n.signData(data)
|
||||
}
|
||||
|
||||
// sign binary data using the local node's private key
|
||||
func (n *Node) signData(data []byte) ([]byte, error) {
|
||||
key := n.Peerstore().PrivKey(n.ID())
|
||||
res, err := key.Sign(data)
|
||||
return res, err
|
||||
}
|
||||
|
||||
// precondition: we have info about the signer peer in the local peer store
|
||||
// Verify incoming p2p message data integrity
|
||||
// data: data to verify
|
||||
// signature: author signature provided in the message payload
|
||||
// peerId: author peer id from the message payload
|
||||
// pubKeyData: author public key from the message payload
|
||||
func (n *Node) verifyData(data []byte, signature []byte, peerId peer.ID, pubKeyData []byte) bool {
|
||||
|
||||
key, err := crypto.UnmarshalPublicKey(pubKeyData)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err, "Failed to extract key from message key data")
|
||||
return false
|
||||
|
@ -90,7 +100,6 @@ func (n *Node) verifyData(data []byte, signature []byte, peerId peer.ID, pubKeyD
|
|||
}
|
||||
|
||||
res, err := key.Verify(data, signature)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err, "Error authenticating data")
|
||||
return false
|
||||
|
@ -98,3 +107,23 @@ func (n *Node) verifyData(data []byte, signature []byte, peerId peer.ID, pubKeyD
|
|||
|
||||
return res
|
||||
}
|
||||
|
||||
// helper method - generate message data shared between all node's p2p protocols
|
||||
// messageId: unique for requests, copied from request for responses
|
||||
func (n *Node) NewMessageData(messageId string, gossip bool) *p2p.MessageData {
|
||||
|
||||
// Add protobufs bin data for message author public key
|
||||
// this is useful for authenticating messages forwarded by a node authored by another node
|
||||
nodePubKey, err := n.Peerstore().PubKey(n.ID()).Bytes()
|
||||
|
||||
if err != nil {
|
||||
panic("Failed to get public key for sender from local peer store.")
|
||||
}
|
||||
|
||||
return &p2p.MessageData{ClientVersion: clientVersion,
|
||||
NodeId: peer.IDB58Encode(n.ID()),
|
||||
NodePubKey: nodePubKey,
|
||||
Timestamp: time.Now().Unix(),
|
||||
Id: messageId,
|
||||
Gossip: gossip}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ func (p *PingProtocol) onPingRequest(s inet.Stream) {
|
|||
// generate response message
|
||||
log.Printf("%s: Sending ping response to %s. Message id: %s...", s.Conn().LocalPeer(), s.Conn().RemotePeer(), data.MessageData.Id)
|
||||
|
||||
resp := &p2p.PingResponse{MessageData: NewMessageData(p.node, data.MessageData.Id, false),
|
||||
resp := &p2p.PingResponse{MessageData: p.node.NewMessageData(data.MessageData.Id, false),
|
||||
Message: fmt.Sprintf("Ping response from %s", p.node.ID())}
|
||||
|
||||
// sign the data
|
||||
|
@ -117,7 +117,7 @@ func (p *PingProtocol) Ping(host host.Host) bool {
|
|||
log.Printf("%s: Sending ping to: %s....", p.node.ID(), host.ID())
|
||||
|
||||
// create message data
|
||||
req := &p2p.PingRequest{MessageData: NewMessageData(p.node, uuid.New().String(), false),
|
||||
req := &p2p.PingRequest{MessageData: p.node.NewMessageData(uuid.New().String(), false),
|
||||
Message: fmt.Sprintf("Ping from %s", p.node.ID())}
|
||||
|
||||
// sign the data
|
||||
|
|
|
@ -2,13 +2,10 @@ package main
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
p2p "github.com/avive/go-libp2p/examples/multipro/pb"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
protobufCodec "github.com/multiformats/go-multicodec/protobuf"
|
||||
"gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
|
||||
inet "gx/ipfs/QmbD5yKbXahNvoMqzeuNyKQA9vAs9fUvJg2GXeWU1fVqY5/go-libp2p-net"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// node version
|
||||
|
@ -28,23 +25,3 @@ func sendProtoMessage(data proto.Message, s inet.Stream) bool {
|
|||
writer.Flush()
|
||||
return true
|
||||
}
|
||||
|
||||
// helper method - generate message data shared between all node's p2p protocols
|
||||
// messageId - unique for requests, copied from request for responses
|
||||
func NewMessageData(node *Node, messageId string, gossip bool) *p2p.MessageData {
|
||||
|
||||
// Add protobufs bin data for message author public key
|
||||
// this is useful for authenticating messages forwarded by a node authored by another node
|
||||
nodePubKey, err := node.Peerstore().PubKey(node.ID()).Bytes()
|
||||
|
||||
if err != nil {
|
||||
panic("Failed to get public key for sender from local peer store.")
|
||||
}
|
||||
|
||||
return &p2p.MessageData{ClientVersion: clientVersion,
|
||||
NodeId: peer.IDB58Encode(node.ID()),
|
||||
NodePubKey: nodePubKey,
|
||||
Timestamp: time.Now().Unix(),
|
||||
Id: messageId,
|
||||
Gossip: gossip}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue