identify.go 1.72 KB
Newer Older
1 2 3 4 5
// The identify package handles how peers identify with eachother upon
// connection to the network
package identify

import (
6 7 8 9 10 11 12
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"errors"
	"io/ioutil"

13
	peer "github.com/jbenet/go-ipfs/peer"
14
	u "github.com/jbenet/go-ipfs/util"
15 16 17 18
)

// Perform initial communication with this peer to share node ID's and
// initiate communication
19
func Handshake(self, remote *peer.Peer, in, out chan []byte) error {
Jeromy's avatar
Jeromy committed
20
	// TODO: make this more... secure.
21 22 23
	out <- self.ID
	resp := <-in
	remote.ID = peer.ID(resp)
24
	u.DOut("[%s] identify: Got node id: %s\n", self.ID.Pretty(), remote.ID.Pretty())
25 26 27

	return nil
}
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

type KeyPair struct {
	Pub  crypto.PublicKey
	Priv crypto.PrivateKey
}

func GenKeypair() (*KeyPair, error) {
	priv, err := rsa.GenerateKey(rand.Reader, 4096)
	if err != nil {
		return nil, err
	}

	return &KeyPair{
		Priv: priv,
		Pub:  priv.PublicKey,
	}, nil
}

func LoadKeypair(dir string) (*KeyPair, error) {
	var kp KeyPair
	pk_b, err := ioutil.ReadFile(dir + "/priv.key")
	if err != nil {
		return nil, err
	}

	priv, err := x509.ParsePKCS1PrivateKey(pk_b)
	if err != nil {
		return nil, err
	}

	kp.Priv = priv
	kp.Pub = priv.PublicKey

	return &kp, nil
}

func (pk *KeyPair) ID() (peer.ID, error) {
	pub_b, err := x509.MarshalPKIXPublicKey(pk.Pub)
	if err != nil {
		return nil, err
	}
	hash, err := u.Hash(pub_b)
	if err != nil {
		return nil, err
	}
	return peer.ID(hash), nil
}

func (kp *KeyPair) Save(dir string) error {
	switch k := kp.Priv.(type) {
	case *rsa.PrivateKey:
		err := k.Validate()
		if err != nil {
			return err
		}
		pk_b := x509.MarshalPKCS1PrivateKey(k)
		err = ioutil.WriteFile(dir+"/priv.key", pk_b, 0600)
		return err
	default:
		return errors.New("invalid private key type.")
	}
}