From cde3a63e34ac664e70432856a69715aac2f74959 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Wed, 6 Sep 2017 16:30:03 -0700 Subject: [PATCH] WIP: add support for ed25519 key embedded identities License: MIT Signed-off-by: Jeromy --- cmd/ipfs/init.go | 16 ++++++++++++++-- core/core.go | 25 +++++++++++++++++++++++-- repo/config/init.go | 15 ++++++++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index ad258592170d..f21781534552 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -24,6 +24,7 @@ import ( const ( nBitsForKeypairDefault = 2048 keypairTypeDefault = ci.RSA + keypairTypeStrDefault = "rsa" ) var initCmd = &cmds.Command{ @@ -53,7 +54,7 @@ environment variable: }, Options: []cmds.Option{ cmds.IntOption("bits", "b", "Number of bits to use in the generated RSA private key.").Default(nBitsForKeypairDefault), - cmds.IntOption("key-type", "k", "Key type (RSA or Ed25519-id)").Default(keypairTypeDefault), + cmds.StringOption("key-type", "k", "Key type (RSA or Ed25519-id)").Default(keypairTypeStrDefault), cmds.BoolOption("empty-repo", "e", "Don't add and pin help files to the local storage.").Default(false), cmds.StringOption("profile", "p", "Apply profile settings to config. Multiple profiles can be separated by ','"), @@ -95,12 +96,23 @@ environment variable: return } - keyType, _, err := req.Option("key-type").Int() + keyTypeStr, _, err := req.Option("key-type").String() if err != nil { res.SetError(err, cmds.ErrNormal) return } + var keyType int + switch keyTypeStr { + case "rsa": + keyType = ci.RSA + case "ed25519": + keyType = ci.Ed25519 + default: + res.SetError(fmt.Errorf("unrecognized key-type: %s", keyTypeStr), cmds.ErrNormal) + return + } + var conf *config.Config f := req.Files() diff --git a/core/core.go b/core/core.go index 40bafabebae6..0f9c2513674d 100644 --- a/core/core.go +++ b/core/core.go @@ -42,6 +42,7 @@ import ( offroute "github.com/ipfs/go-ipfs/routing/offline" ft "github.com/ipfs/go-ipfs/unixfs" + mh "github.com/multiformats/go-multihash" pnet "gx/ipfs/QmNMCAuxnQFHLGWcvay3DmVFrKuY6Y2nsc9vzsf4gVouJV/go-libp2p-pnet" cid "gx/ipfs/QmNp85zy9RLrQ5oQD4hPyS39ezrrXpcaa7R4Y9kxdWQLLQ/go-cid" routing "gx/ipfs/QmPR2JzfKd9poHx9XBhzoFeBBC31ZM3W5iUPKJZWyaoZZm/go-libp2p-routing" @@ -759,9 +760,29 @@ func loadPrivateKey(cfg *config.Identity, id peer.ID) (ic.PrivKey, error) { return nil, err } - id2, err := peer.IDFromPrivateKey(sk) + decmh, err := mh.Decode([]byte(id)) if err != nil { - return nil, err + return nil, fmt.Errorf("id was not a valid multihash") + } + + // TODO: this isnt very elegant. Formalize how we want to do this + var id2 peer.ID + switch decmh.Code { + case mh.ID: + if _, ok := sk.(*ic.Ed25519PrivateKey); !ok { + return nil, fmt.Errorf("key embedded peer IDs are only supported for ed25519") + } + id2, err = peer.IDFromEd25519PublicKey(sk.GetPublic()) + if err != nil { + return nil, err + } + case mh.SHA2_256: + id2, err = peer.IDFromPrivateKey(sk) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unsupported peer ID hash: %q", mh.Codes[decmh.Code]) } if id2 != id { diff --git a/repo/config/init.go b/repo/config/init.go index 3f67613b8a53..65a5886415ce 100644 --- a/repo/config/init.go +++ b/repo/config/init.go @@ -126,6 +126,8 @@ func identityConfig(out io.Writer, nbits, keyType int) (Identity, error) { fmt.Fprintf(out, "generating %v-bit RSA keypair...", nbits) case ci.Ed25519: fmt.Fprintf(out, "generating Ed25519 keypair...") + default: + return ident, fmt.Errorf("unrecognized keyType: %d", keyType) } sk, pk, err := ci.GenerateKeyPair(keyType, nbits) @@ -142,11 +144,22 @@ func identityConfig(out io.Writer, nbits, keyType int) (Identity, error) { } ident.PrivKey = base64.StdEncoding.EncodeToString(skbytes) - id, err := peer.IDFromPublicKey(pk) + kf := peer.IDFromPublicKey + switch keyType { + case ci.RSA: + kf = peer.IDFromPublicKey + case ci.Ed25519: + kf = peer.IDFromEd25519PublicKey + default: + return ident, fmt.Errorf("unrecognized keyType: %d", keyType) + } + + id, err := kf(pk) if err != nil { return ident, err } ident.PeerID = id.Pretty() + fmt.Fprintf(out, "peer identity: %s\n", ident.PeerID) return ident, nil }