Authenticate ping protocol messages

This commit is contained in:
Aviv Eyal 2017-11-28 12:28:40 +02:00 committed by Steven Allen
parent b3d54ab284
commit 0b1ed3936a
2 changed files with 57 additions and 6 deletions

View File

@ -4,15 +4,44 @@ import (
host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
"github.com/gogo/protobuf/proto"
p2p "github.com/libp2p/go-libp2p/examples/multipro/pb"
"log"
)
func (n Node) authenticateMessage(message proto.Message, data *p2p.MessageData) bool {
// store a temp ref to sig and remove it from data
sign := data.Sign
data.Sign = ""
//log.Print("Signature: %s", []byte(sign))
// marshall data without the sig to binary format
bin, err := proto.Marshal(message)
if err != nil {
// todo: log
return false
}
// restore sig in message data (for possible future use)
data.Sign = sign
peerId, err := peer.IDB58Decode(data.NodeId)
if err != nil {
log.Fatal(err, "Failed to decode node id")
return false
}
return n.verifyData(bin, []byte(sign), peerId)
}
func (n Node) signProtoMessage(message proto.Message) ([]byte, error) {
// sign the data
data, err := proto.Marshal(message)
if err != nil {
return nil, err
}
return n.signData(data)
}
@ -22,8 +51,10 @@ func (n Node) signData(data []byte) ([]byte, error) {
return res, err
}
func (n Node) verifyData(data []byte, signature []byte, signerHostId peer.ID) bool {
key := n.Peerstore().PubKey(signerHostId)
// precondition: we have info about the signer peer in the local peer store
func (n Node) verifyData(data []byte, signature []byte, peerId peer.ID) bool {
key := n.Peerstore().PubKey(peerId)
//log.Print ("%s %s %s", peerId, key, peerId.String())
res, err := key.Verify(data, signature)
return res == true && err == nil
}

View File

@ -12,6 +12,7 @@ import (
p2p "github.com/libp2p/go-libp2p/examples/multipro/pb"
protobufCodec "github.com/multiformats/go-multicodec/protobuf"
"gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
"gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
)
// pattern: /protocol-name/request-or-response-message/version
@ -46,9 +47,19 @@ func (p PingProtocol) onPingRequest(s inet.Stream) {
log.Printf("%s: Received ping request from %s. Message: %s", s.Conn().LocalPeer(), s.Conn().RemotePeer(), data.Message)
valid := p.node.authenticateMessage(data, data.MessageData)
if !valid {
log.Fatal("Failed to authenticate message")
return
} else {
log.Print("Authenticated request content was generated by claimed node :-)")
}
// 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.ID().String(), data.MessageData.Id, false),
resp := &p2p.PingResponse{MessageData: NewMessageData(peer.IDB58Encode(p.node.ID()), data.MessageData.Id, false),
Message: fmt.Sprintf("Ping response from %s", p.node.ID())}
// sign the data
@ -84,6 +95,15 @@ func (p PingProtocol) onPingResponse(s inet.Stream) {
return
}
valid := p.node.authenticateMessage(data, data.MessageData)
if !valid {
log.Fatal("Failed to authenticate message")
return
} else {
log.Print("Authenticated response content generated by claimed node :-)")
}
// locate request data and remove it if found
_, ok := p.requests[data.MessageData.Id]
if ok {
@ -102,7 +122,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.ID().String(), uuid.New().String(), false),
req := &p2p.PingRequest{MessageData: NewMessageData(peer.IDB58Encode(p.node.ID()), uuid.New().String(), false),
Message: fmt.Sprintf("Ping from %s", p.node.ID())}
// sign the data