Authenticate ping protocol messages
This commit is contained in:
parent
b3d54ab284
commit
0b1ed3936a
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue