From 49182bcfebf4026bf3b961bc782e60d05cf41075 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Wed, 29 Nov 2017 11:46:00 +0200 Subject: [PATCH] Don't rely on local peer store for remote nodes public keys --- README.md | 1 + examples/multipro/LICENSE | 21 +++++++++++++++++++++ examples/multipro/README.md | 6 ++++++ examples/multipro/node.go | 29 +++++++++++++++++++++-------- examples/multipro/protocol.go | 3 ++- 5 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 examples/multipro/LICENSE diff --git a/README.md b/README.md index 1e60e39..b44b25d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

libp2p hex logo

diff --git a/examples/multipro/LICENSE b/examples/multipro/LICENSE new file mode 100644 index 0000000..c7386b3 --- /dev/null +++ b/examples/multipro/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/examples/multipro/README.md b/examples/multipro/README.md index 15d4e02..343ac0c 100644 --- a/examples/multipro/README.md +++ b/examples/multipro/README.md @@ -30,8 +30,14 @@ From `multipro` base source folder: ## Details The example creates two LibP2P Hosts supporting 2 protocols: ping and echo. + Each protocol consists RPC-style requests and respones and each request and response is a typed protobufs message (and a go data object). + This is a different pattern then defining a whole p2p protocol as 1 protobuf message with lots of optional fields (as can be observed in various p2p-lib protocols using protobufs such as dht). + The example shows how to match async received responses with their requests. This is useful when processing a response requires access to the request data. +## Author + +@avive diff --git a/examples/multipro/node.go b/examples/multipro/node.go index 39c9d67..0d63570 100644 --- a/examples/multipro/node.go +++ b/examples/multipro/node.go @@ -5,6 +5,8 @@ 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" ) @@ -46,7 +48,7 @@ func (n *Node) authenticateMessage(message proto.Message, data *p2p.MessageData) return false } - return n.verifyData(bin, []byte(sign), peerId, []byte(data.NodePubKey)) + return n.verifyData(bin, []byte(sign), peerId, data.NodePubKey) } func (n *Node) signProtoMessage(message proto.Message) ([]byte, error) { @@ -66,20 +68,31 @@ func (n *Node) signData(data []byte) ([]byte, error) { // precondition: we have info about the signer peer in the local peer store func (n *Node) verifyData(data []byte, signature []byte, peerId peer.ID, pubKeyData []byte) bool { - // todo: restore pub key from message and not from the local peer store and use it - key := n.Peerstore().PubKey(peerId) + key, err := crypto.UnmarshalPublicKey(pubKeyData) + + if err != nil { + log.Println(err, "Failed to extract key from message key data") + return false + } + + // extract node id from the provided public key + idFromKey, err := peer.IDFromPublicKey(key) - //todo: fix this - //key, err := key.UnmarshalPublicKey(pubKeyData) + if err != nil { + log.Println(err, "Failed to extract peer id from public key") + return false + } - if key == nil { - log.Println("Failed to find public key for %s in local peer store.", peerId.String()) + // verify that message author node id matches the provided public key + if idFromKey != peerId { + log.Println(err, "Node id and provided public key mismatch") return false } res, err := key.Verify(data, signature) + if err != nil { - log.Println ("Error authenticating data") + log.Println(err, "Error authenticating data") return false } diff --git a/examples/multipro/protocol.go b/examples/multipro/protocol.go index 0b57d89..6fe6f60 100644 --- a/examples/multipro/protocol.go +++ b/examples/multipro/protocol.go @@ -33,7 +33,8 @@ func sendProtoMessage(data proto.Message, s inet.Stream) bool { // messageId - unique for requests, copied from request for responses func NewMessageData(node *Node, messageId string, gossip bool) *p2p.MessageData { - // Create protobufs bin data for a public key + // 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 { -- GitLab