mirror of
https://github.com/ipfs/kubo.git
synced 2025-07-04 13:27:14 +08:00
Key import and export cli commands
This commit is contained in:
@ -133,6 +133,9 @@ func TestCommands(t *testing.T) {
|
||||
"/id",
|
||||
"/key",
|
||||
"/key/gen",
|
||||
"/key/export",
|
||||
"/key/import",
|
||||
"/key/identify",
|
||||
"/key/list",
|
||||
"/key/rename",
|
||||
"/key/rm",
|
||||
|
@ -7,8 +7,13 @@ import (
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
"github.com/ipfs/go-ipfs/core/coreapi"
|
||||
repo "github.com/ipfs/go-ipfs/repo"
|
||||
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
|
||||
options "github.com/ipfs/interface-go-ipfs-core/options"
|
||||
"github.com/libp2p/go-libp2p-core/crypto"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/mr-tron/base58/base58"
|
||||
mbase "github.com/multiformats/go-multibase"
|
||||
)
|
||||
|
||||
@ -31,6 +36,9 @@ publish'.
|
||||
},
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"gen": keyGenCmd,
|
||||
"export": keyExportCmd,
|
||||
"import": keyImportCmd,
|
||||
"identify": keyIdentifyCmd,
|
||||
"list": keyListCmd,
|
||||
"rename": keyRenameCmd,
|
||||
"rm": keyRmCmd,
|
||||
@ -42,6 +50,16 @@ type KeyOutput struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
type GenerateKeyOutput struct {
|
||||
Name string
|
||||
Id string
|
||||
Sk string
|
||||
}
|
||||
|
||||
type ExportKeyOutput struct {
|
||||
Sk string
|
||||
}
|
||||
|
||||
type KeyOutputList struct {
|
||||
Keys []KeyOutput
|
||||
}
|
||||
@ -58,6 +76,8 @@ const (
|
||||
keyStoreTypeOptionName = "type"
|
||||
keyStoreSizeOptionName = "size"
|
||||
keyFormatOptionName = "format"
|
||||
keyExportOptionName = "export"
|
||||
keyNoStoreOptionName = "no-store"
|
||||
)
|
||||
|
||||
var keyGenCmd = &cmds.Command{
|
||||
@ -68,54 +88,111 @@ var keyGenCmd = &cmds.Command{
|
||||
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"),
|
||||
cmds.BoolOption(keyExportOptionName, "e", "return generated key for later re-import").WithDefault(false),
|
||||
cmds.BoolOption(keyNoStoreOptionName, "n", "don't add the key to the keychain").WithDefault(false),
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("name", true, false, "name of key to create"),
|
||||
cmds.StringArg("name", false, false, "name of key to create, required unless -n specified"),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
typ, f := req.Options[keyStoreTypeOptionName].(string)
|
||||
if !f {
|
||||
return fmt.Errorf("please specify a key type with --type")
|
||||
}
|
||||
|
||||
name := req.Arguments[0]
|
||||
store := !req.Options[keyNoStoreOptionName].(bool)
|
||||
export := req.Options[keyExportOptionName].(bool)
|
||||
|
||||
var name string
|
||||
var r repo.Repo = nil
|
||||
defer func() {
|
||||
if r != nil {
|
||||
r.Close()
|
||||
}
|
||||
}()
|
||||
if store {
|
||||
if len(req.Arguments) == 0 {
|
||||
return fmt.Errorf("you must specify a key name")
|
||||
}
|
||||
|
||||
name = req.Arguments[0]
|
||||
|
||||
if name == "self" {
|
||||
return fmt.Errorf("cannot create key with name 'self'")
|
||||
}
|
||||
|
||||
cfgRoot, err := cmdenv.GetConfigRoot(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err = fsrepo.Open(cfgRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = r.Keystore().Get(name)
|
||||
if err == nil {
|
||||
return fmt.Errorf("key with name '%s' already exists", name)
|
||||
}
|
||||
}
|
||||
|
||||
if !store && !export {
|
||||
return fmt.Errorf("you must export key if not storing")
|
||||
}
|
||||
|
||||
opts := []options.KeyGenerateOption{options.Key.Type(typ)}
|
||||
|
||||
size, sizefound := req.Options[keyStoreSizeOptionName].(int)
|
||||
if sizefound {
|
||||
opts = append(opts, options.Key.Size(size))
|
||||
}
|
||||
if err = verifyFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
|
||||
if err := verifyFormatLabel(req.Options[keyFormatOptionName].(string)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key, err := api.Key().Generate(req.Context, name, opts...)
|
||||
|
||||
sk, pk, err := coreapi.GenerateKey(opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &KeyOutput{
|
||||
if store {
|
||||
err = r.Keystore().Put(name, sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
pid, err := peer.IDFromPublicKey(pk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var encoded string
|
||||
if export {
|
||||
encoded, err = encodeSKForExport(sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &GenerateKeyOutput{
|
||||
Name: name,
|
||||
Id: formatID(key.ID(), req.Options[keyFormatOptionName].(string)),
|
||||
Id: formatID(pid, req.Options[keyFormatOptionName].(string)),
|
||||
Sk: encoded,
|
||||
})
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ko *KeyOutput) error {
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ko *GenerateKeyOutput) error {
|
||||
if ko.Sk != "" {
|
||||
_, err := w.Write([]byte(ko.Sk + "\n"))
|
||||
return err
|
||||
}
|
||||
_, err := w.Write([]byte(ko.Id + "\n"))
|
||||
return err
|
||||
}),
|
||||
},
|
||||
Type: KeyOutput{},
|
||||
Type: GenerateKeyOutput{},
|
||||
}
|
||||
|
||||
func verifyFormatLabel(formatLabel string) error {
|
||||
@ -143,6 +220,170 @@ func formatID(id peer.ID, formatLabel string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func encodeSKForExport(sk crypto.PrivKey) (string, error) {
|
||||
data, err := crypto.MarshalPrivateKey(sk)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base58.Encode(data), nil
|
||||
}
|
||||
|
||||
var keyExportCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Export a keypair",
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("name", true, false, "name of key to export").EnableStdin(),
|
||||
},
|
||||
Options: []cmds.Option{},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
name := req.Arguments[0]
|
||||
|
||||
if name == "self" {
|
||||
return fmt.Errorf("exporting key 'self' is not allowed")
|
||||
}
|
||||
|
||||
cfgRoot, err := cmdenv.GetConfigRoot(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := fsrepo.Open(cfgRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
sk, err := r.Keystore().Get(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("key with name '%s' doesn't exist", name)
|
||||
}
|
||||
|
||||
encoded, err := encodeSKForExport(sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &ExportKeyOutput{
|
||||
Sk: encoded,
|
||||
})
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ko *ExportKeyOutput) error {
|
||||
_, err := w.Write([]byte(ko.Sk + "\n"))
|
||||
return err
|
||||
}),
|
||||
},
|
||||
Type: ExportKeyOutput{},
|
||||
}
|
||||
|
||||
var keyImportCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Import a key and prints imported key id",
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"),
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("name", true, false, "name to associate with key in keychain"),
|
||||
cmds.StringArg("key", true, false, "key provided by generate or export"),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
name := req.Arguments[0]
|
||||
encoded := req.Arguments[1]
|
||||
|
||||
data, err := base58.Decode(encoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sk, err := crypto.UnmarshalPrivateKey(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfgRoot, err := cmdenv.GetConfigRoot(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := fsrepo.Open(cfgRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
_, err = r.Keystore().Get(name)
|
||||
if err == nil {
|
||||
return fmt.Errorf("key with name '%s' already exists", name)
|
||||
}
|
||||
|
||||
err = r.Keystore().Put(name, sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := peer.IDFromPrivateKey(sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &KeyOutput{
|
||||
Name: name,
|
||||
Id: formatID(pid, req.Options[keyFormatOptionName].(string)),
|
||||
})
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ko *KeyOutput) error {
|
||||
_, err := w.Write([]byte(ko.Id + "\n"))
|
||||
return err
|
||||
}),
|
||||
},
|
||||
Type: KeyOutput{},
|
||||
}
|
||||
|
||||
var keyIdentifyCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Identify an exported keypair",
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"),
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("key", true, false, "key provided by generate or export"),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
encoded := req.Arguments[0]
|
||||
|
||||
data, err := base58.Decode(encoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sk, err := crypto.UnmarshalPrivateKey(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := peer.IDFromPrivateKey(sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &KeyOutput{
|
||||
Name: "",
|
||||
Id: formatID(pid, req.Options[keyFormatOptionName].(string)),
|
||||
})
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ko *KeyOutput) error {
|
||||
_, err := w.Write([]byte(ko.Id + "\n"))
|
||||
return err
|
||||
}),
|
||||
},
|
||||
Type: KeyOutput{},
|
||||
}
|
||||
|
||||
var keyListCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "List all local keypairs",
|
||||
|
@ -37,21 +37,11 @@ func (k *key) ID() peer.ID {
|
||||
return k.peerID
|
||||
}
|
||||
|
||||
// Generate generates new key, stores it in the keystore under the specified
|
||||
// name and returns a base58 encoded multihash of its public key.
|
||||
func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (coreiface.Key, error) {
|
||||
// GenerateKey generates a new keypair and returns it
|
||||
func GenerateKey(opts ...caopts.KeyGenerateOption) (crypto.PrivKey, crypto.PubKey, error) {
|
||||
options, err := caopts.KeyGenerateOptions(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if name == "self" {
|
||||
return nil, fmt.Errorf("cannot create key with name 'self'")
|
||||
}
|
||||
|
||||
_, err = api.repo.Keystore().Get(name)
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("key with name '%s' already exists", name)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var sk crypto.PrivKey
|
||||
@ -65,7 +55,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
|
||||
|
||||
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.RSA, options.Size, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sk = priv
|
||||
@ -73,13 +63,33 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
|
||||
case "ed25519":
|
||||
priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sk = priv
|
||||
pk = pub
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized key type: %s", options.Algorithm)
|
||||
return nil, nil, fmt.Errorf("unrecognized key type: %s", options.Algorithm)
|
||||
}
|
||||
|
||||
return sk, pk, nil
|
||||
}
|
||||
|
||||
// Generate generates new key, stores it in the keystore under the specified
|
||||
// name and returns a base58 encoded multihash of its public key.
|
||||
func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (coreiface.Key, error) {
|
||||
if name == "self" {
|
||||
return nil, fmt.Errorf("cannot create key with name 'self'")
|
||||
}
|
||||
|
||||
_, err := api.repo.Keystore().Get(name)
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("key with name '%s' already exists", name)
|
||||
}
|
||||
|
||||
sk, pk, err := GenerateKey(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = api.repo.Keystore().Put(name, sk)
|
||||
|
@ -483,6 +483,22 @@ test_check_ed25519_b36cid_peerid() {
|
||||
}
|
||||
}
|
||||
|
||||
test_check_rsa2048_sk() {
|
||||
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
|
||||
test "$sklen" = "300" || {
|
||||
echo "Bad RSA2048 sk '$1' with len '$sklen'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
test_check_ed25519_sk() {
|
||||
sklen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
|
||||
test "$sklen" = "300" || {
|
||||
echo "Bad ED25519 sk '$1' with len '$sklen'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
convert_tcp_maddr() {
|
||||
echo $1 | awk -F'/' '{ printf "%s:%s", $3, $5 }'
|
||||
}
|
||||
|
@ -17,6 +17,11 @@ 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 sk export format" '
|
||||
PEERID=$(ipfs key export key_rsa) &&
|
||||
test_check_rsa2048_sk $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 &&
|
||||
@ -28,6 +33,11 @@ PEERID=$(ipfs key gen -f=b36cid --type=ed25519 key_ed25519) &&
|
||||
test_check_ed25519_b36cid_peerid $PEERID
|
||||
'
|
||||
|
||||
test_expect_success "test RSA key ED25519 sk export format" '
|
||||
PEERID=$(ipfs key export key_ed25519) &&
|
||||
test_check_ed25519_sk $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 &&
|
||||
@ -44,10 +54,31 @@ ipfs key rm key_ed25519
|
||||
edhash=$(ipfs key gen -f=b58mh bazed --type=ed25519)
|
||||
'
|
||||
|
||||
test_expect_success "both keys show up in list output" '
|
||||
test_expect_success "import an rsa key" '
|
||||
imphash=$(ipfs key import -f=b58mh quxel B9bLmHeKLQU1hX23meSn2kJiNW7AZ31C6PBNSYumejXB13vxSVvViZDkEnchAH4BTs9yVnBNZKZYLwykaCohzxTntesTCVaBhZR2Br2Swav2NXwVBhfrUbaBTrR2248KfbVxSiUdkpFn8kcAmUGwp2KGMGRmq85WreGFDdAvzz8ruN2EFfWSHLc1YeUxHeUgKsQm3N13uF7q5x4qvjWM6yvMWNY7JtZrihT8BZQhgb2ezR4iYPjXZTtPZWsLbrrhUvHhxSn1NsTw6NZ7Jbs84qMXXnH56BmT8J9LugRhQQvgBquSoS1m7aeD2y1L1A7mueVDYGLDzgxRSt5CohY7VVMdheUpPiq44CicuYt5YgbbuE3wMHntn6sd9QSYw7f4SjjKdw7Jhy5fNW29SkHvpLfZKfqzBNhSfHsofXVEASDpfr5mqws1eQTztqvvZhHXQxAoxxP3PK6TfDnATdLdV3Cy5v6nLt7ppsBj54hif5EZneHMLeYP8bYLbELQ2fZdoprpnKVBsMY1nWvgrMKUTpLjoKB6bzAZYuXaYVtmrdhESmKCyE12yEyvCcD8DJQU6JjqaD1DyVSPNkL3ze26Mm3ZyiFEH7M4XirUsPLrsj41Qt1xGaVGNEdkdthihytTZxxnmgyAptZMUNfSviBfH1tVbfoXFtBGU8eYMLdSHFqxSktT1mqeiWatxMQZ8pTeA9VCvAp9RTSRFkTQR9uP6w6qTzRD9cFcH4HyCEc5TJpiZdP7u9RjaEo2S3P9VkHfmqCH4McpLgw7He9nm7rf9JA2Gh7ubTKy5e6dJUWojgYhGS4KGe3yKGFhLaNgRiME63fUEFSnN2ZvCSM9qsrj34q2h8962xBod9hCVEDfk4tfmHu1UHX5AGaW6mk3pzqKKVYTTWXi84JSH7vzKPmQuhwaAR9Ye3Jbdzehp4xhrT5aFCjnz3r5qNv2zz48Fq5bGc1RUh88PUMT3z6kuzv6B1eXTLYpeu9gGdjc5C9DQDTYPfcHWn7dSHr4AGV1sN6SwVy8W5LZdMAZaeXCDn9iXDwbeD2DYd2ozVCEzceygVzpVdnueNx5FmG6zHtGzfuStr4Jj85sbd2jUGh4ES2bMU41jw2gJ6ujjf6CrxZpCWhXz6NJpAS9njcDFXuspf7otbMjCB6TzwokJwEse31nGUZQdhQgXn23vnZtxwCV621uXFbm7xVACRZKeuXgw8VdEVaXGvf2V4DdhjZnjmePBbTeJ7WjABavLcpMqZJH7FgaLxazFqk9RXtnfUEbVAAhuZzxz6L8Z6axHwz3a4EZtALRjfFjn6xjaUtsWXYW8P6F7femM6UHx3qXMo43hKC7oxnd6Tfta972dgyQfSoBwWkWzB8cvaJreNh4bdLNkw6mty86NXGKyijv83LR1HjbnUoTwPbEMX8JyzLfMf3qiWzwf6MHrXprwygmEpNc6w8tNNivmcWyCX3wmPkMKK1bmi5TCHoUtRrxcyXKhmuyo6zzag8KyK6iZaRbMiFiUJBi5VYwidMutkexWo8SRqfSV5yp2kxswknmpeVTnXBhVEy3anMEiD6bV48AnbF6SfKAi2DGBFqxBFfpFEbYtPauHiYYzZX1epqvKxY23xA9J8FosMk4yYN4Ps7Rh)
|
||||
'
|
||||
|
||||
test_expect_success "identify an rsa key" '
|
||||
gothash=$(ipfs key identify B9bLmHeKLQU1hX23meSn2kJiNW7AZ31C6PBNSYumejXB13vxSVvViZDkEnchAH4BTs9yVnBNZKZYLwykaCohzxTntesTCVaBhZR2Br2Swav2NXwVBhfrUbaBTrR2248KfbVxSiUdkpFn8kcAmUGwp2KGMGRmq85WreGFDdAvzz8ruN2EFfWSHLc1YeUxHeUgKsQm3N13uF7q5x4qvjWM6yvMWNY7JtZrihT8BZQhgb2ezR4iYPjXZTtPZWsLbrrhUvHhxSn1NsTw6NZ7Jbs84qMXXnH56BmT8J9LugRhQQvgBquSoS1m7aeD2y1L1A7mueVDYGLDzgxRSt5CohY7VVMdheUpPiq44CicuYt5YgbbuE3wMHntn6sd9QSYw7f4SjjKdw7Jhy5fNW29SkHvpLfZKfqzBNhSfHsofXVEASDpfr5mqws1eQTztqvvZhHXQxAoxxP3PK6TfDnATdLdV3Cy5v6nLt7ppsBj54hif5EZneHMLeYP8bYLbELQ2fZdoprpnKVBsMY1nWvgrMKUTpLjoKB6bzAZYuXaYVtmrdhESmKCyE12yEyvCcD8DJQU6JjqaD1DyVSPNkL3ze26Mm3ZyiFEH7M4XirUsPLrsj41Qt1xGaVGNEdkdthihytTZxxnmgyAptZMUNfSviBfH1tVbfoXFtBGU8eYMLdSHFqxSktT1mqeiWatxMQZ8pTeA9VCvAp9RTSRFkTQR9uP6w6qTzRD9cFcH4HyCEc5TJpiZdP7u9RjaEo2S3P9VkHfmqCH4McpLgw7He9nm7rf9JA2Gh7ubTKy5e6dJUWojgYhGS4KGe3yKGFhLaNgRiME63fUEFSnN2ZvCSM9qsrj34q2h8962xBod9hCVEDfk4tfmHu1UHX5AGaW6mk3pzqKKVYTTWXi84JSH7vzKPmQuhwaAR9Ye3Jbdzehp4xhrT5aFCjnz3r5qNv2zz48Fq5bGc1RUh88PUMT3z6kuzv6B1eXTLYpeu9gGdjc5C9DQDTYPfcHWn7dSHr4AGV1sN6SwVy8W5LZdMAZaeXCDn9iXDwbeD2DYd2ozVCEzceygVzpVdnueNx5FmG6zHtGzfuStr4Jj85sbd2jUGh4ES2bMU41jw2gJ6ujjf6CrxZpCWhXz6NJpAS9njcDFXuspf7otbMjCB6TzwokJwEse31nGUZQdhQgXn23vnZtxwCV621uXFbm7xVACRZKeuXgw8VdEVaXGvf2V4DdhjZnjmePBbTeJ7WjABavLcpMqZJH7FgaLxazFqk9RXtnfUEbVAAhuZzxz6L8Z6axHwz3a4EZtALRjfFjn6xjaUtsWXYW8P6F7femM6UHx3qXMo43hKC7oxnd6Tfta972dgyQfSoBwWkWzB8cvaJreNh4bdLNkw6mty86NXGKyijv83LR1HjbnUoTwPbEMX8JyzLfMf3qiWzwf6MHrXprwygmEpNc6w8tNNivmcWyCX3wmPkMKK1bmi5TCHoUtRrxcyXKhmuyo6zzag8KyK6iZaRbMiFiUJBi5VYwidMutkexWo8SRqfSV5yp2kxswknmpeVTnXBhVEy3anMEiD6bV48AnbF6SfKAi2DGBFqxBFfpFEbYtPauHiYYzZX1epqvKxY23xA9J8FosMk4yYN4Ps7Rh) &&
|
||||
test $imphash = $gothash
|
||||
'
|
||||
|
||||
test_expect_success "key import can't export self" '
|
||||
test_must_fail ipfs key export self 2>&1 | tee key_exp_out &&
|
||||
grep -q "Error: cannot export key with name" key_exp_out
|
||||
'
|
||||
|
||||
test_expect_success "key import can't import self" '
|
||||
test_must_fail ipfs key import self B9bLmHeKLQU1hX23meSn2kJiNW7AZ31C6PBNSYumejXB13vxSVvViZDkEnchAH4BTs9yVnBNZKZYLwykaCohzxTntesTCVaBhZR2Br2Swav2NXwVBhfrUbaBTrR2248KfbVxSiUdkpFn8kcAmUGwp2KGMGRmq85WreGFDdAvzz8ruN2EFfWSHLc1YeUxHeUgKsQm3N13uF7q5x4qvjWM6yvMWNY7JtZrihT8BZQhgb2ezR4iYPjXZTtPZWsLbrrhUvHhxSn1NsTw6NZ7Jbs84qMXXnH56BmT8J9LugRhQQvgBquSoS1m7aeD2y1L1A7mueVDYGLDzgxRSt5CohY7VVMdheUpPiq44CicuYt5YgbbuE3wMHntn6sd9QSYw7f4SjjKdw7Jhy5fNW29SkHvpLfZKfqzBNhSfHsofXVEASDpfr5mqws1eQTztqvvZhHXQxAoxxP3PK6TfDnATdLdV3Cy5v6nLt7ppsBj54hif5EZneHMLeYP8bYLbELQ2fZdoprpnKVBsMY1nWvgrMKUTpLjoKB6bzAZYuXaYVtmrdhESmKCyE12yEyvCcD8DJQU6JjqaD1DyVSPNkL3ze26Mm3ZyiFEH7M4XirUsPLrsj41Qt1xGaVGNEdkdthihytTZxxnmgyAptZMUNfSviBfH1tVbfoXFtBGU8eYMLdSHFqxSktT1mqeiWatxMQZ8pTeA9VCvAp9RTSRFkTQR9uP6w6qTzRD9cFcH4HyCEc5TJpiZdP7u9RjaEo2S3P9VkHfmqCH4McpLgw7He9nm7rf9JA2Gh7ubTKy5e6dJUWojgYhGS4KGe3yKGFhLaNgRiME63fUEFSnN2ZvCSM9qsrj34q2h8962xBod9hCVEDfk4tfmHu1UHX5AGaW6mk3pzqKKVYTTWXi84JSH7vzKPmQuhwaAR9Ye3Jbdzehp4xhrT5aFCjnz3r5qNv2zz48Fq5bGc1RUh88PUMT3z6kuzv6B1eXTLYpeu9gGdjc5C9DQDTYPfcHWn7dSHr4AGV1sN6SwVy8W5LZdMAZaeXCDn9iXDwbeD2DYd2ozVCEzceygVzpVdnueNx5FmG6zHtGzfuStr4Jj85sbd2jUGh4ES2bMU41jw2gJ6ujjf6CrxZpCWhXz6NJpAS9njcDFXuspf7otbMjCB6TzwokJwEse31nGUZQdhQgXn23vnZtxwCV621uXFbm7xVACRZKeuXgw8VdEVaXGvf2V4DdhjZnjmePBbTeJ7WjABavLcpMqZJH7FgaLxazFqk9RXtnfUEbVAAhuZzxz6L8Z6axHwz3a4EZtALRjfFjn6xjaUtsWXYW8P6F7femM6UHx3qXMo43hKC7oxnd6Tfta972dgyQfSoBwWkWzB8cvaJreNh4bdLNkw6mty86NXGKyijv83LR1HjbnUoTwPbEMX8JyzLfMf3qiWzwf6MHrXprwygmEpNc6w8tNNivmcWyCX3wmPkMKK1bmi5TCHoUtRrxcyXKhmuyo6zzag8KyK6iZaRbMiFiUJBi5VYwidMutkexWo8SRqfSV5yp2kxswknmpeVTnXBhVEy3anMEiD6bV48AnbF6SfKAi2DGBFqxBFfpFEbYtPauHiYYzZX1epqvKxY23xA9J8FosMk4yYN4Ps7Rh 2>&1 | tee key_imp_out &&
|
||||
grep -q "Error: cannot import key with name" key_imp_out
|
||||
'
|
||||
|
||||
test_expect_success "all keys show up in list output" '
|
||||
echo bazed > list_exp &&
|
||||
echo foobarsa >> list_exp &&
|
||||
echo self >> list_exp
|
||||
echo quxel >> list_exp &&
|
||||
echo self >> list_exp &&
|
||||
sort -o list_exp list_exp
|
||||
ipfs key list -f=b58mh | sort > list_out &&
|
||||
test_cmp list_exp list_out
|
||||
'
|
||||
|
Reference in New Issue
Block a user