diff --git a/core/commands/keystore.go b/core/commands/keystore.go index f22d64afae3..c9865fd93ee 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -5,10 +5,11 @@ import ( "io" "text/tabwriter" - cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" - cmds "github.com/ipfs/go-ipfs-cmds" + cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" options "github.com/ipfs/interface-go-ipfs-core/options" + peer "github.com/libp2p/go-libp2p-core/peer" + mbase "github.com/multiformats/go-multibase" ) var KeyCmd = &cmds.Command{ @@ -56,6 +57,7 @@ type KeyRenameOutput struct { const ( keyStoreTypeOptionName = "type" keyStoreSizeOptionName = "size" + keyFormatOptionName = "format" ) var keyGenCmd = &cmds.Command{ @@ -65,6 +67,7 @@ var keyGenCmd = &cmds.Command{ Options: []cmds.Option{ cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault("rsa"), cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"), + cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"), }, Arguments: []cmds.Argument{ cmds.StringArg("name", true, false, "name of key to create"), @@ -91,6 +94,9 @@ var keyGenCmd = &cmds.Command{ if sizefound { opts = append(opts, options.Key.Size(size)) } + if err = verifyFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil { + return err + } key, err := api.Key().Generate(req.Context, name, opts...) @@ -100,7 +106,7 @@ var keyGenCmd = &cmds.Command{ return cmds.EmitOnce(res, &KeyOutput{ Name: name, - Id: key.ID().Pretty(), + Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)), }) }, Encoders: cmds.EncoderMap{ @@ -112,14 +118,44 @@ var keyGenCmd = &cmds.Command{ Type: KeyOutput{}, } +func verifyFormatLabel(formatLabel string) error { + switch formatLabel { + case "b58mh": + return nil + case "b36cid": + return nil + } + return fmt.Errorf("invalid output format option") +} + +func formatID(id peer.ID, formatLabel string) string { + switch formatLabel { + case "b58mh": + return id.Pretty() + case "b36cid": + if s, err := peer.ToCid(id).StringOfBase(mbase.Base36); err != nil { + panic(err) + } else { + return s + } + default: + panic("unreachable") + } +} + var keyListCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List all local keypairs", }, Options: []cmds.Option{ cmds.BoolOption("l", "Show extra information about keys."), + cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + if err := verifyFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil { + return err + } + api, err := cmdenv.GetApi(env, req) if err != nil { return err @@ -133,7 +169,10 @@ var keyListCmd = &cmds.Command{ list := make([]KeyOutput, 0, len(keys)) for _, key := range keys { - list = append(list, KeyOutput{Name: key.Name(), Id: key.ID().Pretty()}) + list = append(list, KeyOutput{ + Name: key.Name(), + Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)), + }) } return cmds.EmitOnce(res, &KeyOutputList{list}) diff --git a/go.mod b/go.mod index 25b5b6da722..7dac7eb6111 100644 --- a/go.mod +++ b/go.mod @@ -89,6 +89,7 @@ require ( github.com/miekg/dns v1.1.29 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/mr-tron/base58 v1.1.3 + github.com/multiformats/go-base36 v0.1.0 github.com/multiformats/go-multiaddr v0.2.2 github.com/multiformats/go-multiaddr-dns v0.2.0 github.com/multiformats/go-multiaddr-net v0.1.5 diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 69766579a71..4b7fd32aa61 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -451,6 +451,38 @@ test_check_peerid() { } } +test_check_rsa2048_b58mh_peerid() { + peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && + test "$peeridlen" = "46" || { + echo "Bad RSA2048 B58MH peerid '$1' with len '$peeridlen'" + return 1 + } +} + +test_check_ed25519_b58mh_peerid() { + peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && + test "$peeridlen" = "46" || { + echo "Bad ED25519 B58MH peerid '$1' with len '$peeridlen'" + return 1 + } +} + +test_check_rsa2048_b36cid_peerid() { + peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && + test "$peeridlen" = "56" || { + echo "Bad RSA2048 B36CID peerid '$1' with len '$peeridlen'" + return 1 + } +} + +test_check_ed25519_b36cid_peerid() { + peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") && + test "$peeridlen" = "62" || { + echo "Bad ED25519 B36CID peerid '$1' with len '$peeridlen'" + return 1 + } +} + convert_tcp_maddr() { echo $1 | awk -F'/' '{ printf "%s:%s", $3, $5 }' } diff --git a/test/sharness/t0100-name.sh b/test/sharness/t0100-name.sh index 96d2ce5ea82..10ee52f64ae 100755 --- a/test/sharness/t0100-name.sh +++ b/test/sharness/t0100-name.sh @@ -101,7 +101,7 @@ test_expect_failure "publish with our explicit node ID looks good" ' # publish with an explicit node ID as key name test_expect_success "generate and verify a new key" ' - NEWID=`ipfs key gen --type=rsa --size=2048 keyname` && + NEWID=`ipfs key gen -f=b58mh --type=rsa --size=2048 keyname` && test_check_peerid "${NEWID}" ' diff --git a/test/sharness/t0160-resolve.sh b/test/sharness/t0160-resolve.sh index 1524ed8d28e..6f63d6f31b3 100755 --- a/test/sharness/t0160-resolve.sh +++ b/test/sharness/t0160-resolve.sh @@ -23,7 +23,7 @@ test_expect_success "resolve: prepare dag" ' test_expect_success "resolve: prepare keys" ' self_hash=$(ipfs id -f="") && - alt_hash=$(ipfs key gen -t rsa alt) + alt_hash=$(ipfs key gen -f=b58mh -t rsa alt) ' test_resolve_setup_name() { diff --git a/test/sharness/t0165-keystore.sh b/test/sharness/t0165-keystore.sh index 617b0e2b5e3..c4538c70eef 100755 --- a/test/sharness/t0165-keystore.sh +++ b/test/sharness/t0165-keystore.sh @@ -11,37 +11,62 @@ test_description="Test keystore commands" test_init_ipfs test_key_cmd() { +# test key output format +test_expect_success "create an RSA key and test B58MH multihash output" ' +PEERID=$(ipfs key gen -f=b58mh --type=rsa --size=2048 key_rsa) && +test_check_rsa2048_b58mh_peerid $PEERID +' + +test_expect_success "test RSA key B36CID multihash format" ' +PEERID=$(ipfs key list -f=b36cid -l | grep key_rsa | head -n 1 | cut -d " " -f1) && +test_check_rsa2048_b36cid_peerid $PEERID && +ipfs key rm key_rsa +' + +test_expect_success "create an ED25519 key and test multihash output" ' +PEERID=$(ipfs key gen -f=b36cid --type=ed25519 key_ed25519) && +test_check_ed25519_b36cid_peerid $PEERID +' + +test_expect_success "test ED25519 key B36CID multihash format" ' +PEERID=$(ipfs key list -f=b36cid -l | grep key_ed25519 | head -n 1 | cut -d " " -f1) && +test_check_ed25519_b36cid_peerid $PEERID && +ipfs key rm key_ed25519 +' +# end of format test + + test_expect_success "create a new rsa key" ' - rsahash=$(ipfs key gen foobarsa --type=rsa --size=2048) + rsahash=$(ipfs key gen -f=b58mh foobarsa --type=rsa --size=2048) ' test_expect_success "create a new ed25519 key" ' - edhash=$(ipfs key gen bazed --type=ed25519) + edhash=$(ipfs key gen -f=b58mh bazed --type=ed25519) ' test_expect_success "both keys show up in list output" ' echo bazed > list_exp && echo foobarsa >> list_exp && echo self >> list_exp - ipfs key list | sort > list_out && + ipfs key list -f=b58mh | sort > list_out && test_cmp list_exp list_out ' test_expect_success "key hashes show up in long list output" ' - ipfs key list -l | grep $edhash > /dev/null && - ipfs key list -l | grep $rsahash > /dev/null + ipfs key list -f=b58mh -l | grep $edhash > /dev/null && + ipfs key list -f=b58mh -l | grep $rsahash > /dev/null ' test_expect_success "key list -l contains self key with peerID" ' PeerID="$(ipfs config Identity.PeerID)" - ipfs key list -l | grep "$PeerID\s\+self" + ipfs key list -f=b58mh -l | grep "$PeerID\s\+self" ' test_expect_success "key rm remove a key" ' ipfs key rm foobarsa echo bazed > list_exp && echo self >> list_exp - ipfs key list | sort > list_out && + ipfs key list -f=b58mh | sort > list_out && test_cmp list_exp list_out ' @@ -54,12 +79,12 @@ test_key_cmd() { ipfs key rename bazed fooed echo fooed > list_exp && echo self >> list_exp - ipfs key list | sort > list_out && + ipfs key list -f=b58mh | sort > list_out && test_cmp list_exp list_out ' test_expect_success "key rename rename key output succeeds" ' - key_content=$(ipfs key gen key1 --type=rsa --size=2048) && + key_content=$(ipfs key gen -f=b58mh key1 --type=rsa --size=2048) && ipfs key rename key1 key2 >rs && echo "Key $key_content renamed to key2" >expect && test_cmp rs expect