Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/ed25519 ident #4215

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions cmd/ipfs/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ import (
namesys "github.com/ipfs/go-ipfs/namesys"
config "github.com/ipfs/go-ipfs/repo/config"
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"

ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
)

// The default keypair is 2048-bit RSA
const (
nBitsForKeypairDefault = 2048
keypairTypeDefault = ci.RSA
keypairTypeStrDefault = "rsa"
)

var initCmd = &cmds.Command{
Expand Down Expand Up @@ -49,6 +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.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 ','"),

Expand Down Expand Up @@ -78,18 +84,35 @@ environment variable:
return
}

empty, _, err := req.Option("e").Bool()
empty, _, err := req.Option("empty-repo").Bool()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

nBitsForKeypair, _, err := req.Option("b").Int()
nBitsForKeypair, _, err := req.Option("bits").Int()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

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()
Expand Down Expand Up @@ -118,7 +141,7 @@ environment variable:
profiles = strings.Split(profile, ",")
}

if err := doInit(os.Stdout, req.InvocContext().ConfigRoot, empty, nBitsForKeypair, profiles, conf); err != nil {
if err := doInit(os.Stdout, req.InvocContext().ConfigRoot, empty, nBitsForKeypair, keyType, profiles, conf); err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
Expand All @@ -130,10 +153,10 @@ Reinitializing would overwrite your keys.
`)

func initWithDefaults(out io.Writer, repoRoot string) error {
return doInit(out, repoRoot, false, nBitsForKeypairDefault, nil, nil)
return doInit(out, repoRoot, false, nBitsForKeypairDefault, keypairTypeDefault, nil, nil)
}

func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, confProfiles []string, conf *config.Config) error {
func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair, keyType int, confProfiles []string, conf *config.Config) error {
if _, err := fmt.Fprintf(out, "initializing IPFS node at %s\n", repoRoot); err != nil {
return err
}
Expand All @@ -148,7 +171,7 @@ func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, con

if conf == nil {
var err error
conf, err = config.Init(out, nBitsForKeypair)
conf, err = config.Init(out, nBitsForKeypair, keyType)
if err != nil {
return err
}
Expand Down
25 changes: 23 additions & 2 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
b58 "gx/ipfs/QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf/go-base58"
floodsub "gx/ipfs/QmTm7GoSkSSQPP32bZhvu17oY1AfvPKND6ELUdYAcKuR1j/floodsub"
mh "gx/ipfs/QmU9a9NV9RdPNwZQDYd5uKsm6N6LJLSvLbywDDYFbaaC6P/go-multihash"
p2phost "gx/ipfs/QmUwW8jMQDxXhLD2j4EfWqLEMX3MsvyWcWGvJPVDh1aTmu/go-libp2p-host"
addrutil "gx/ipfs/QmVJGsPeK3vwtEyyTxpCs47yjBYMmYsAhEouPDF3Gb2eK3/go-addr-util"
ds "gx/ipfs/QmVSase1JP7cq9QkPT46oNwdp9pT6kBkG3oqS14y3QcZjG/go-datastore"
Expand Down Expand Up @@ -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 {
Expand Down
36 changes: 28 additions & 8 deletions repo/config/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
)

func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
identity, err := identityConfig(out, nBitsForKeypair)
func Init(out io.Writer, nBitsForKeypair, keyType int) (*Config, error) {
identity, err := identityConfig(out, nBitsForKeypair, keyType)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -113,15 +113,24 @@ func DefaultDatastoreConfig() Datastore {
}

// identityConfig initializes a new identity.
func identityConfig(out io.Writer, nbits int) (Identity, error) {
func identityConfig(out io.Writer, nbits, keyType int) (Identity, error) {
// TODO guard higher up
ident := Identity{}
if nbits < 1024 {
return ident, errors.New("Bitsize less than 1024 is considered unsafe.")

switch keyType {
case ci.RSA:
if nbits < 1024 {
return ident, errors.New("Bitsize less than 1024 is considered unsafe for RSA.")
}

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)
}

fmt.Fprintf(out, "generating %v-bit RSA keypair...", nbits)
sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits)
sk, pk, err := ci.GenerateKeyPair(keyType, nbits)
if err != nil {
return ident, err
}
Expand All @@ -135,11 +144,22 @@ func identityConfig(out io.Writer, nbits 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
}