@cryptotaxi247 / kubo / commits / 45fc43c9c

add pub/priv key code to identify, not complete yet

Jeromy committed Sep 1, 2014 at 16:09 UTC 45fc43c9cf72a17ccf01b4d82933520a748cf47e
5 files changed +181 -27
config/config.go
+9 -2
@@ -1,13 +1,15 @@
1 package config
2
3 import (
4 - u "github.com/jbenet/go-ipfs/util"
4 "os"
5 +
6 + u "github.com/jbenet/go-ipfs/util"
7 )
8
9 // Identity tracks the configuration of the local node's identity.
10 type Identity struct {
10 - PeerID string
11 + PeerID string
12 + Address string
13 }
14
15 // Datastore tracks the configuration of the datastore.
@@ -16,10 +18,15 @@ type Datastore struct {
18 Path string
19 }
20
21 +type SavedPeer struct {
22 + Address string
23 +}
24 +
25 // Config is used to load IPFS config files.
26 type Config struct {
27 Identity *Identity
28 Datastore *Datastore
29 + Peers []*SavedPeer
30 }
31
32 var defaultConfigFilePath = "~/.go-ipfs/config"
core/core.go
+45 -25
@@ -67,34 +67,10 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
67
68 var swap *bitswap.BitSwap
69 if online {
70 - maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/4001")
70 + swap, err = loadBitswap(cfg, d)
71 if err != nil {
72 return nil, err
73 }
74 -
75 - local := &peer.Peer{
76 - ID: peer.ID(cfg.Identity.PeerID),
77 - Addresses: []*ma.Multiaddr{maddr},
78 - }
79 -
80 - if len(local.ID) == 0 {
81 - mh, err := u.Hash([]byte("blah blah blah ID"))
82 - if err != nil {
83 - return nil, err
84 - }
85 - local.ID = peer.ID(mh)
86 - }
87 -
88 - net := swarm.NewSwarm(local)
89 - err = net.Listen()
90 - if err != nil {
91 - return nil, err
92 - }
93 -
94 - route := dht.NewDHT(local, net, d)
95 - route.Start()
96 -
97 - swap = bitswap.NewBitSwap(local, net, d, route)
74 }
75
76 bs, err := bserv.NewBlockService(d, swap)
@@ -115,3 +91,47 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
91
92 return n, nil
93 }
94 +
95 +func loadBitswap(cfg *config.Config, d ds.Datastore) (*bitswap.BitSwap, error) {
96 + maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/4001")
97 + if err != nil {
98 + return nil, err
99 + }
100 +
101 + local := &peer.Peer{
102 + ID: peer.ID(cfg.Identity.PeerID),
103 + Addresses: []*ma.Multiaddr{maddr},
104 + }
105 +
106 + if len(local.ID) == 0 {
107 + mh, err := u.Hash([]byte("blah blah blah ID"))
108 + if err != nil {
109 + return nil, err
110 + }
111 + local.ID = peer.ID(mh)
112 + }
113 +
114 + net := swarm.NewSwarm(local)
115 + err = net.Listen()
116 + if err != nil {
117 + return nil, err
118 + }
119 +
120 + route := dht.NewDHT(local, net, d)
121 + route.Start()
122 +
123 + for _, p := range cfg.Peers {
124 + maddr, err := ma.NewMultiaddr(p.Address)
125 + if err != nil {
126 + u.PErr("error: %v\n", err)
127 + continue
128 + }
129 +
130 + _, err = route.Connect(maddr)
131 + if err != nil {
132 + u.PErr("Bootstrapping error: %v\n", err)
133 + }
134 + }
135 +
136 + return bitswap.NewBitSwap(local, net, d, route), nil
137 +}
identify/identify.go
+69
@@ -3,6 +3,13 @@
3 package identify
4
5 import (
6 + "crypto"
7 + "crypto/rand"
8 + "crypto/rsa"
9 + "crypto/x509"
10 + "errors"
11 + "io/ioutil"
12 +
13 peer "github.com/jbenet/go-ipfs/peer"
14 u "github.com/jbenet/go-ipfs/util"
15 )
@@ -18,3 +25,65 @@ func Handshake(self, remote *peer.Peer, in, out chan []byte) error {
25
26 return nil
27 }
28 +
29 +type KeyPair struct {
30 + Pub crypto.PublicKey
31 + Priv crypto.PrivateKey
32 +}
33 +
34 +func GenKeypair() (*KeyPair, error) {
35 + priv, err := rsa.GenerateKey(rand.Reader, 4096)
36 + if err != nil {
37 + return nil, err
38 + }
39 +
40 + return &KeyPair{
41 + Priv: priv,
42 + Pub: priv.PublicKey,
43 + }, nil
44 +}
45 +
46 +func LoadKeypair(dir string) (*KeyPair, error) {
47 + var kp KeyPair
48 + pk_b, err := ioutil.ReadFile(dir + "/priv.key")
49 + if err != nil {
50 + return nil, err
51 + }
52 +
53 + priv, err := x509.ParsePKCS1PrivateKey(pk_b)
54 + if err != nil {
55 + return nil, err
56 + }
57 +
58 + kp.Priv = priv
59 + kp.Pub = priv.PublicKey
60 +
61 + return &kp, nil
62 +}
63 +
64 +func (pk *KeyPair) ID() (peer.ID, error) {
65 + pub_b, err := x509.MarshalPKIXPublicKey(pk.Pub)
66 + if err != nil {
67 + return nil, err
68 + }
69 + hash, err := u.Hash(pub_b)
70 + if err != nil {
71 + return nil, err
72 + }
73 + return peer.ID(hash), nil
74 +}
75 +
76 +func (kp *KeyPair) Save(dir string) error {
77 + switch k := kp.Priv.(type) {
78 + case *rsa.PrivateKey:
79 + err := k.Validate()
80 + if err != nil {
81 + return err
82 + }
83 + pk_b := x509.MarshalPKCS1PrivateKey(k)
84 + err = ioutil.WriteFile(dir+"/priv.key", pk_b, 0600)
85 + return err
86 + default:
87 + return errors.New("invalid private key type.")
88 + }
89 +}
routing/dht/dht.go
+8
@@ -2,6 +2,7 @@ package dht
2
3 import (
4 "bytes"
5 + "crypto/rand"
6 "fmt"
7 "sync"
8 "time"
@@ -637,3 +638,10 @@ func (dht *IpfsDHT) peerFromInfo(pbp *PBDHTMessage_PBPeer) (*peer.Peer, error) {
638
639 return dht.network.GetConnection(peer.ID(pbp.GetId()), maddr)
640 }
641 +
642 +// Builds up list of peers by requesting random peer IDs
643 +func (dht *IpfsDHT) Bootstrap() {
644 + id := make([]byte, 16)
645 + rand.Read(id)
646 + dht.FindPeer(peer.ID(id), time.Second*10)
647 +}
routing/dht/routing.go
+50
@@ -340,6 +340,56 @@ func (dht *IpfsDHT) FindPeer(id peer.ID, timeout time.Duration) (*peer.Peer, err
340 return nil, u.ErrNotFound
341 }
342
343 +func (dht *IpfsDHT) findPeerMultiple(id peer.ID, timeout time.Duration) (*peer.Peer, error) {
344 + // Check if were already connected to them
345 + p, _ := dht.Find(id)
346 + if p != nil {
347 + return p, nil
348 + }
349 +
350 + routeLevel := 0
351 + peers := dht.routingTables[routeLevel].NearestPeers(kb.ConvertPeerID(id), AlphaValue)
352 + if len(peers) == 0 {
353 + return nil, kb.ErrLookupFailure
354 + }
355 +
356 + found := make(chan *peer.Peer)
357 + after := time.After(timeout)
358 +
359 + for _, p := range peers {
360 + go func(p *peer.Peer) {
361 + pmes, err := dht.findPeerSingle(p, id, timeout, routeLevel)
362 + if err != nil {
363 + u.DErr("getPeer error: %v\n", err)
364 + return
365 + }
366 + plist := pmes.GetPeers()
367 + if len(plist) == 0 {
368 + routeLevel++
369 + }
370 + for _, fp := range plist {
371 + nxtp, err := dht.peerFromInfo(fp)
372 + if err != nil {
373 + u.DErr("findPeer error: %v\n", err)
374 + continue
375 + }
376 +
377 + if nxtp.ID.Equal(dht.self.ID) {
378 + found <- nxtp
379 + return
380 + }
381 + }
382 + }(p)
383 + }
384 +
385 + select {
386 + case p := <-found:
387 + return p, nil
388 + case <-after:
389 + return nil, u.ErrTimeout
390 + }
391 +}
392 +
393 // Ping a peer, log the time it took
394 func (dht *IpfsDHT) Ping(p *peer.Peer, timeout time.Duration) error {
395 // Thoughts: maybe this should accept an ID and do a peer lookup?