diff --git a/README.md b/README.md index 1e60e3979446ee639aeea7ce072611ab8c009dbb..b44b25dec3513099e66976052fbdadc8c50d49f1 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 0000000000000000000000000000000000000000..c7386b3c940d8aa7baea2dd6fec2908fed562b89 --- /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 15d4e02a74769321bd4a173ea37941c08b866e35..343ac0c61b1ecb76181fcba44a4a5154f1afd8c3 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 39c9d67d2a02021cbc87da573e742584f8bf6fff..0d6357081c5bdbc483e376114d1643d1845b789f 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 0b57d89859e38b3512359e33909d55aa7fc061e7..6fe6f60804a75ae238c35c2655c80b890157b37d 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 {