Skip to content

Commit

Permalink
switch ipfs key import/export to use files instead of strings
Browse files Browse the repository at this point in the history
  • Loading branch information
aschmahmann committed Aug 3, 2020
1 parent 356ca3a commit 04d8e95
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 63 deletions.
79 changes: 52 additions & 27 deletions core/commands/keystore.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package commands

import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"text/tabwriter"

cmds "github.com/ipfs/go-ipfs-cmds"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
"github.com/ipfs/go-ipfs/core/commands/e"
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"
)

Expand Down Expand Up @@ -47,10 +50,6 @@ type KeyOutput struct {
Id string
}

type ExportKeyOutput struct {
Sk string
}

type KeyOutputList struct {
Keys []KeyOutput
}
Expand Down Expand Up @@ -152,22 +151,22 @@ 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",
ShortDescription: `
Exports a named libp2p key to disk.
By default, the output will be stored at './<key-name>', but an alternate
path can be specified with '--output=<path>' or '-o=<path>'.
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("name", true, false, "name of key to export").EnableStdin(),
},
Options: []cmds.Option{},
Options: []cmds.Option{
cmds.StringOption(outputOptionName, "o", "The path where the output should be stored."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
name := req.Arguments[0]

Expand All @@ -191,22 +190,44 @@ var keyExportCmd = &cmds.Command{
return fmt.Errorf("key with name '%s' doesn't exist", name)
}

encoded, err := encodeSKForExport(sk)
encoded, err := crypto.MarshalPrivateKey(sk)
if err != nil {
return err
}

return cmds.EmitOnce(res, &ExportKeyOutput{
Sk: encoded,
})
return res.Emit(bytes.NewReader(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
}),
PostRun: cmds.PostRunMap{
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
req := res.Request()

v, err := res.Next()
if err != nil {
return err
}

outReader, ok := v.(io.Reader)
if !ok {
return e.New(e.TypeErr(outReader, v))
}

outPath := getOutPath(req)

// create file
file, err := os.Create(outPath)
if err != nil {
return err
}
defer file.Close()

_, err = io.Copy(file, outReader)
if err != nil {
return err
}

return nil
},
},
Type: ExportKeyOutput{},
}

var keyImportCmd = &cmds.Command{
Expand All @@ -218,7 +239,7 @@ var keyImportCmd = &cmds.Command{
},
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"),
cmds.FileArg("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]
Expand All @@ -227,9 +248,13 @@ var keyImportCmd = &cmds.Command{
return fmt.Errorf("cannot import key with name 'self'")
}

encoded := req.Arguments[1]
file, err := cmdenv.GetFileArg(req.Files.Entries())
if err != nil {
return err
}
defer file.Close()

data, err := base58.Decode(encoded)
data, err := ioutil.ReadAll(file)
if err != nil {
return err
}
Expand Down
16 changes: 0 additions & 16 deletions test/sharness/lib/test-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -483,22 +483,6 @@ test_check_ed25519_b36cid_peerid() {
}
}

test_check_rsa2048_sk() {
sklen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
if (($sklen < 1600)); then
echo "Bad RSA2048 sk '$1' with len '$sklen'"
return 1
fi
}

test_check_ed25519_sk() {
sklen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
test "$sklen" = "93" || {
echo "Bad ED25519 sk '$1' with len '$sklen'"
return 1
}
}

convert_tcp_maddr() {
echo $1 | awk -F'/' '{ printf "%s:%s", $3, $5 }'
}
Expand Down
83 changes: 63 additions & 20 deletions test/sharness/t0165-keystore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ test_check_rsa2048_b58mh_peerid $PEERID
'

test_expect_success "test RSA key sk export format" '
SK=$(ipfs key export key_rsa) &&
test_check_rsa2048_sk $SK
ipfs key export key_rsa &&
test_check_rsa2048_sk key_rsa &&
rm key_rsa
'

test_expect_success "test RSA key B36CID multihash format" '
Expand All @@ -34,8 +35,9 @@ test_check_ed25519_b36cid_peerid $PEERID
'

test_expect_success "test ED25519 key sk export format" '
SK=$(ipfs key export key_ed25519) &&
test_check_ed25519_sk $SK
ipfs key export key_ed25519 &&
test_check_ed25519_sk key_ed25519 &&
rm key_ed25519
'

test_expect_success "test ED25519 key B36CID multihash format" '
Expand All @@ -47,36 +49,59 @@ ipfs key rm key_ed25519


test_expect_success "create a new rsa key" '
rsahash=$(ipfs key gen -f=b58mh foobarsa --type=rsa --size=2048)
rsahash=$(ipfs key gen -f=b58mh generated_rsa_key --type=rsa --size=2048)
echo $rsahash > rsa_key_id
'

test_expect_success "create a new ed25519 key" '
edhash=$(ipfs key gen -f=b58mh bazed --type=ed25519)
edhash=$(ipfs key gen -f=b58mh generated_ed25519_key --type=ed25519)
echo $edhash > ed25519_key_id
'

test_expect_success "import an rsa key" '
echo "B9bLmHeKLQU1hX23meSn2kJiNW7AZ31C6PBNSYumejXB13vxSVvViZDkEnchAH4BTs9yVnBNZKZYLwykaCohzxTntesTCVaBhZR2Br2Swav2NXwVBhfrUbaBTrR2248KfbVxSiUdkpFn8kcAmUGwp2KGMGRmq85WreGFDdAvzz8ruN2EFfWSHLc1YeUxHeUgKsQm3N13uF7q5x4qvjWM6yvMWNY7JtZrihT8BZQhgb2ezR4iYPjXZTtPZWsLbrrhUvHhxSn1NsTw6NZ7Jbs84qMXXnH56BmT8J9LugRhQQvgBquSoS1m7aeD2y1L1A7mueVDYGLDzgxRSt5CohY7VVMdheUpPiq44CicuYt5YgbbuE3wMHntn6sd9QSYw7f4SjjKdw7Jhy5fNW29SkHvpLfZKfqzBNhSfHsofXVEASDpfr5mqws1eQTztqvvZhHXQxAoxxP3PK6TfDnATdLdV3Cy5v6nLt7ppsBj54hif5EZneHMLeYP8bYLbELQ2fZdoprpnKVBsMY1nWvgrMKUTpLjoKB6bzAZYuXaYVtmrdhESmKCyE12yEyvCcD8DJQU6JjqaD1DyVSPNkL3ze26Mm3ZyiFEH7M4XirUsPLrsj41Qt1xGaVGNEdkdthihytTZxxnmgyAptZMUNfSviBfH1tVbfoXFtBGU8eYMLdSHFqxSktT1mqeiWatxMQZ8pTeA9VCvAp9RTSRFkTQR9uP6w6qTzRD9cFcH4HyCEc5TJpiZdP7u9RjaEo2S3P9VkHfmqCH4McpLgw7He9nm7rf9JA2Gh7ubTKy5e6dJUWojgYhGS4KGe3yKGFhLaNgRiME63fUEFSnN2ZvCSM9qsrj34q2h8962xBod9hCVEDfk4tfmHu1UHX5AGaW6mk3pzqKKVYTTWXi84JSH7vzKPmQuhwaAR9Ye3Jbdzehp4xhrT5aFCjnz3r5qNv2zz48Fq5bGc1RUh88PUMT3z6kuzv6B1eXTLYpeu9gGdjc5C9DQDTYPfcHWn7dSHr4AGV1sN6SwVy8W5LZdMAZaeXCDn9iXDwbeD2DYd2ozVCEzceygVzpVdnueNx5FmG6zHtGzfuStr4Jj85sbd2jUGh4ES2bMU41jw2gJ6ujjf6CrxZpCWhXz6NJpAS9njcDFXuspf7otbMjCB6TzwokJwEse31nGUZQdhQgXn23vnZtxwCV621uXFbm7xVACRZKeuXgw8VdEVaXGvf2V4DdhjZnjmePBbTeJ7WjABavLcpMqZJH7FgaLxazFqk9RXtnfUEbVAAhuZzxz6L8Z6axHwz3a4EZtALRjfFjn6xjaUtsWXYW8P6F7femM6UHx3qXMo43hKC7oxnd6Tfta972dgyQfSoBwWkWzB8cvaJreNh4bdLNkw6mty86NXGKyijv83LR1HjbnUoTwPbEMX8JyzLfMf3qiWzwf6MHrXprwygmEpNc6w8tNNivmcWyCX3wmPkMKK1bmi5TCHoUtRrxcyXKhmuyo6zzag8KyK6iZaRbMiFiUJBi5VYwidMutkexWo8SRqfSV5yp2kxswknmpeVTnXBhVEy3anMEiD6bV48AnbF6SfKAi2DGBFqxBFfpFEbYtPauHiYYzZX1epqvKxY23xA9J8FosMk4yYN4Ps7Rh" >> importkey
imphash=$(ipfs key import -f=b58mh quxel $(cat importkey))

test_expect_success "export and import rsa key" '
ipfs key export generated_rsa_key &&
ipfs key rm generated_rsa_key &&
ipfs key import generated_rsa_key generated_rsa_key > roundtrip_rsa_key_id &&
test_cmp rsa_key_id roundtrip_rsa_key_id
'

test_expect_success "exported key matches imported" '
ipfs key export quxel >> exportkey &&
test_cmp importkey exportkey
test_expect_success "export and import ed25519 key" '
ipfs key export generated_ed25519_key &&
ipfs key rm generated_ed25519_key &&
ipfs key import generated_ed25519_key generated_ed25519_key > roundtrip_ed25519_key_id &&
test_cmp ed25519_key_id roundtrip_ed25519_key_id
'

test_expect_success "test export file option" '
ipfs key export generated_rsa_key -o=named_rsa_export_file &&
test_cmp generated_rsa_key named_rsa_export_file &&
ipfs key export generated_ed25519_key -o=named_ed25519_export_file &&
test_cmp generated_ed25519_key named_ed25519_export_file
'

test_expect_success "key export 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_must_fail ipfs key export self -o=selfexport 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 $(cat importkey) 2>&1 | tee key_imp_out &&
grep -q "Error: cannot import key with name" key_imp_out
ipfs key gen overwrite_self_import &&
ipfs key export overwrite_self_import &&
test_must_fail ipfs key import self overwrite_self_import 2>&1 | tee key_imp_out &&
grep -q "Error: cannot import key with name" key_imp_out &&
ipfs key rm overwrite_self_import &&
rm overwrite_self_import
'

test_expect_success "add a default key" '
ipfs key gen quxel
'

test_expect_success "all keys show up in list output" '
echo bazed > list_exp &&
echo foobarsa >> list_exp &&
echo generated_ed25519_key > list_exp &&
echo generated_rsa_key >> list_exp &&
echo quxel >> list_exp &&
echo self >> list_exp
ipfs key list -f=b58mh > list_out &&
Expand All @@ -94,8 +119,8 @@ ipfs key rm key_ed25519
'

test_expect_success "key rm remove a key" '
ipfs key rm foobarsa
echo bazed > list_exp &&
ipfs key rm generated_rsa_key
echo generated_ed25519_key > list_exp &&
echo quxel >> list_exp &&
echo self >> list_exp
ipfs key list -f=b58mh > list_out &&
Expand All @@ -108,7 +133,7 @@ ipfs key rm key_ed25519
'

test_expect_success "key rename rename a key" '
ipfs key rename bazed fooed
ipfs key rename generated_ed25519_key fooed
echo fooed > list_exp &&
echo quxel >> list_exp &&
echo self >> list_exp
Expand All @@ -134,6 +159,24 @@ ipfs key rm key_ed25519
'
}

test_check_rsa2048_sk() {
sklen=$(cat "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
test $sklen -lt 1600
and $sklen -gt 1000 || {
echo "Bad RSA2048 sk '$1' with len '$sklen'"
return 1
}
}

test_check_ed25519_sk() {
sklen=$(cat "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
test $sklen -lt 100
and $sklen -gt 80 || {
echo "Bad ED25519 sk '$1' with len '$sklen'"
return 1
}
}

test_key_cmd

test_done

0 comments on commit 04d8e95

Please sign in to comment.