node.go 2.28 KB
Newer Older
1
2
3
package main

import (
Aviv Eyal's avatar
Aviv Eyal committed
4
	p2p "github.com/avive/go-libp2p/examples/multipro/pb"
Aviv Eyal's avatar
Aviv Eyal committed
5
	"github.com/gogo/protobuf/proto"
6
	host "gx/ipfs/QmRS46AyqtpJBsf1zmQdeizSDEzo1qkWR7rdEuPFAv8237/go-libp2p-host"
Aviv Eyal's avatar
Aviv Eyal committed
7
	peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
8
	"log"
9
10
)

Aviv Eyal's avatar
Aviv Eyal committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Node type - a p2p host implementing one or more p2p protocols
type Node struct {
	host.Host     // lib-p2p host
	*PingProtocol // ping protocol impl
	*EchoProtocol // echo protocol impl
	// add other protocols here...
}

// create a new node with its implemented protocols
func NewNode(host host.Host, done chan bool) *Node {
	node := &Node{Host: host}
	node.PingProtocol = NewPingProtocol(node, done)
	node.EchoProtocol = NewEchoProtocol(node, done)
	return node
}

27
func (n *Node) authenticateMessage(message proto.Message, data *p2p.MessageData) bool {
28
29
30
31
32
33
34
35

	// store a temp ref to sig and remove it from data
	sign := data.Sign
	data.Sign = ""

	// marshall data without the sig to binary format
	bin, err := proto.Marshal(message)
	if err != nil {
Aviv Eyal's avatar
Aviv Eyal committed
36
		log.Println(err, "failed to marshal pb message")
37
38
39
40
41
42
43
44
		return false
	}

	// restore sig in message data (for possible future use)
	data.Sign = sign

	peerId, err := peer.IDB58Decode(data.NodeId)
	if err != nil {
Aviv Eyal's avatar
Aviv Eyal committed
45
		log.Println(err, "Failed to decode node id from base58")
46
47
48
		return false
	}

Aviv Eyal's avatar
Aviv Eyal committed
49
	return n.verifyData(bin, []byte(sign), peerId, []byte(data.NodePubKey))
50
51
}

52
func (n *Node) signProtoMessage(message proto.Message) ([]byte, error) {
Aviv Eyal's avatar
Aviv Eyal committed
53
54
55
56
57
58
59
	data, err := proto.Marshal(message)
	if err != nil {
		return nil, err
	}
	return n.signData(data)
}

60
func (n *Node) signData(data []byte) ([]byte, error) {
Aviv Eyal's avatar
Aviv Eyal committed
61
62
63
	key := n.Peerstore().PrivKey(n.ID())
	res, err := key.Sign(data)
	return res, err
64
65
}

66
// precondition: we have info about the signer peer in the local peer store
67
func (n *Node) verifyData(data []byte, signature []byte, peerId peer.ID, pubKeyData []byte) bool {
Aviv Eyal's avatar
Aviv Eyal committed
68

69
	// todo: restore pub key from message and not from the local peer store and use it
70
	key := n.Peerstore().PubKey(peerId)
71

Aviv Eyal's avatar
Aviv Eyal committed
72
73
	//todo: fix this
	//key, err := key.UnmarshalPublicKey(pubKeyData)
74

Aviv Eyal's avatar
Aviv Eyal committed
75
	if key == nil {
Aviv Eyal's avatar
Aviv Eyal committed
76
		log.Println("Failed to find public key for %s in local peer store.", peerId.String())
Aviv Eyal's avatar
Aviv Eyal committed
77
78
79
80
81
		return false
	}

	res, err := key.Verify(data, signature)
	if err != nil {
82
		log.Println	("Error authenticating data")
Aviv Eyal's avatar
Aviv Eyal committed
83
84
85
86
		return false
	}

	return res
87
}