Commit 49182bcf authored by Aviv Eyal's avatar Aviv Eyal Committed by Steven Allen
Browse files

Don't rely on local peer store for remote nodes public keys

parent efdab230
<h1 align="center"> <h1 align="center">
<a href="libp2p.io"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/alternates/libp2p-logo-alt-2.png?raw=true" alt="libp2p hex logo" /></a> <a href="libp2p.io"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/alternates/libp2p-logo-alt-2.png?raw=true" alt="libp2p hex logo" /></a>
</h1> </h1>
......
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.
...@@ -30,8 +30,14 @@ From `multipro` base source folder: ...@@ -30,8 +30,14 @@ From `multipro` base source folder:
## Details ## Details
The example creates two LibP2P Hosts supporting 2 protocols: ping and echo. 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). 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). 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. 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
...@@ -5,6 +5,8 @@ import ( ...@@ -5,6 +5,8 @@ import (
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host" host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer" peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
crypto "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
"log" "log"
) )
...@@ -46,7 +48,7 @@ func (n *Node) authenticateMessage(message proto.Message, data *p2p.MessageData) ...@@ -46,7 +48,7 @@ func (n *Node) authenticateMessage(message proto.Message, data *p2p.MessageData)
return false 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) { func (n *Node) signProtoMessage(message proto.Message) ([]byte, error) {
...@@ -66,20 +68,31 @@ func (n *Node) signData(data []byte) ([]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 // 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 { 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, err := crypto.UnmarshalPublicKey(pubKeyData)
key := n.Peerstore().PubKey(peerId)
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 if err != nil {
//key, err := key.UnmarshalPublicKey(pubKeyData) log.Println(err, "Failed to extract peer id from public key")
return false
}
if key == nil { // verify that message author node id matches the provided public key
log.Println("Failed to find public key for %s in local peer store.", peerId.String()) if idFromKey != peerId {
log.Println(err, "Node id and provided public key mismatch")
return false return false
} }
res, err := key.Verify(data, signature) res, err := key.Verify(data, signature)
if err != nil { if err != nil {
log.Println ("Error authenticating data") log.Println(err, "Error authenticating data")
return false return false
} }
......
...@@ -33,7 +33,8 @@ func sendProtoMessage(data proto.Message, s inet.Stream) bool { ...@@ -33,7 +33,8 @@ func sendProtoMessage(data proto.Message, s inet.Stream) bool {
// messageId - unique for requests, copied from request for responses // messageId - unique for requests, copied from request for responses
func NewMessageData(node *Node, messageId string, gossip bool) *p2p.MessageData { 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() nodePubKey, err := node.Peerstore().PubKey(node.ID()).Bytes()
if err != nil { if err != nil {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment