@cryptotaxi247 / kubo / commits / 0f658484d

move key rotation command to ipfs key rotate

Adin Schmahmann committed Aug 17, 2020 at 06:33 UTC 0f658484d1d5db63827f376d0f7ffb66c9bfb578
5 files changed +114 -124
cmd/ipfs/ipfs.go
-1
@@ -22,7 +22,6 @@ var commandsClientCmd = commands.CommandsCmd(Root)
22 var localCommands = map[string]*cmds.Command{
23 "daemon": daemonCmd,
24 "init": initCmd,
25 - "rotate": rotateCmd,
25 "commands": commandsClientCmd,
26 }
27
cmd/ipfs/rotate.go deleted
-116
@@ -1,116 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 - "io"
6 - "os"
7 -
8 - cmds "github.com/ipfs/go-ipfs-cmds"
9 - config "github.com/ipfs/go-ipfs-config"
10 - oldcmds "github.com/ipfs/go-ipfs/commands"
11 - fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
12 - "github.com/ipfs/interface-go-ipfs-core/options"
13 -)
14 -
15 -const (
16 - oldKeyOptionName = "oldkey"
17 -)
18 -
19 -var rotateCmd = &cmds.Command{
20 - Helptext: cmds.HelpText{
21 - Tagline: "Rotates the ipfs identity.",
22 - ShortDescription: `
23 -Generates a new ipfs identity and saves it to the ipfs config file.
24 -The daemon must not be running when calling this command.
25 -
26 -ipfs uses a repository in the local file system. By default, the repo is
27 -located at ~/.ipfs. To change the repo location, set the $IPFS_PATH
28 -environment variable:
29 -
30 - export IPFS_PATH=/path/to/ipfsrepo
31 -`,
32 - },
33 - Arguments: []cmds.Argument{},
34 - Options: []cmds.Option{
35 - cmds.StringOption(oldKeyOptionName, "o", "Keystore name for the old/rotated-out key."),
36 - cmds.StringOption(algorithmOptionName, "a", "Cryptographic algorithm to use for key generation.").WithDefault(algorithmDefault),
37 - cmds.IntOption(bitsOptionName, "b", "Number of bits to use in the generated RSA private key."),
38 - },
39 - NoRemote: true,
40 - PreRun: func(req *cmds.Request, env cmds.Environment) error {
41 - cctx := env.(*oldcmds.Context)
42 - daemonLocked, err := fsrepo.LockedByOtherProcess(cctx.ConfigRoot)
43 - if err != nil {
44 - return err
45 - }
46 -
47 - log.Info("checking if daemon is running...")
48 - if daemonLocked {
49 - log.Debug("ipfs daemon is running")
50 - e := "ipfs daemon is running. please stop it to run this command"
51 - return cmds.ClientError(e)
52 - }
53 -
54 - return nil
55 - },
56 - Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
57 - cctx := env.(*oldcmds.Context)
58 - nBitsForKeypair, nBitsGiven := req.Options[bitsOptionName].(int)
59 - algorithm, _ := req.Options[algorithmOptionName].(string)
60 - oldKey, ok := req.Options[oldKeyOptionName].(string)
61 - if !ok {
62 - return fmt.Errorf("keystore name for backing up old key must be provided")
63 - }
64 - return doRotate(os.Stdout, cctx.ConfigRoot, oldKey, algorithm, nBitsForKeypair, nBitsGiven)
65 - },
66 -}
67 -
68 -func doRotate(out io.Writer, repoRoot string, oldKey string, algorithm string, nBitsForKeypair int, nBitsGiven bool) error {
69 - // Open repo
70 - repo, err := fsrepo.Open(repoRoot)
71 - if err != nil {
72 - return fmt.Errorf("opening repo (%v)", err)
73 - }
74 - defer repo.Close()
75 -
76 - // Read config file from repo
77 - cfg, err := repo.Config()
78 - if err != nil {
79 - return fmt.Errorf("reading config from repo (%v)", err)
80 - }
81 -
82 - // Generate new identity
83 - var identity config.Identity
84 - if nBitsGiven {
85 - identity, err = config.CreateIdentity(out, []options.KeyGenerateOption{
86 - options.Key.Size(nBitsForKeypair),
87 - options.Key.Type(algorithm),
88 - })
89 - } else {
90 - identity, err = config.CreateIdentity(out, []options.KeyGenerateOption{
91 - options.Key.Type(algorithm),
92 - })
93 - }
94 - if err != nil {
95 - return fmt.Errorf("creating identity (%v)", err)
96 - }
97 -
98 - // Save old identity to keystore
99 - oldPrivKey, err := cfg.Identity.DecodePrivateKey("")
100 - if err != nil {
101 - return fmt.Errorf("decoding old private key (%v)", err)
102 - }
103 - keystore := repo.Keystore()
104 - if err := keystore.Put(oldKey, oldPrivKey); err != nil {
105 - return fmt.Errorf("saving old key in keystore (%v)", err)
106 - }
107 -
108 - // Update identity
109 - cfg.Identity = identity
110 -
111 - // Write config file to repo
112 - if err = repo.SetConfig(cfg); err != nil {
113 - return fmt.Errorf("saving new key to config (%v)", err)
114 - }
115 - return nil
116 -}
core/commands/commands_test.go
+1
@@ -138,6 +138,7 @@ func TestCommands(t *testing.T) {
138 "/key/list",
139 "/key/rename",
140 "/key/rm",
141 + "/key/rotate",
142 "/log",
143 "/log/level",
144 "/log/ls",
core/commands/keystore.go
+110 -4
@@ -11,6 +11,8 @@ import (
11 "text/tabwriter"
12
13 cmds "github.com/ipfs/go-ipfs-cmds"
14 + config "github.com/ipfs/go-ipfs-config"
15 + oldcmds "github.com/ipfs/go-ipfs/commands"
16 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
17 "github.com/ipfs/go-ipfs/core/commands/e"
18 fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
@@ -44,6 +46,7 @@ publish'.
46 "list": keyListCmd,
47 "rename": keyRenameCmd,
48 "rm": keyRmCmd,
49 + "rotate": keyRotateCmd,
50 },
51 }
52
@@ -65,9 +68,13 @@ type KeyRenameOutput struct {
68 }
69
70 const (
68 - keyStoreTypeOptionName = "type"
69 - keyStoreSizeOptionName = "size"
70 - keyFormatOptionName = "format"
71 + keyStoreAlgorithmDefault = options.RSAKey
72 + keyStoreAlgorithmOptionName = "algorithm"
73 + keyStoreBitsOptionName = "bits"
74 + keyStoreTypeOptionName = "type"
75 + keyStoreSizeOptionName = "size"
76 + keyFormatOptionName = "format"
77 + oldKeyOptionName = "oldkey"
78 )
79
80 var keyGenCmd = &cmds.Command{
@@ -75,7 +82,7 @@ var keyGenCmd = &cmds.Command{
82 Tagline: "Create a new keypair",
83 },
84 Options: []cmds.Option{
78 - cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault("rsa"),
85 + cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault),
86 cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"),
87 cmds.StringOption(keyFormatOptionName, "f", "output format: b58mh or b36cid").WithDefault("b58mh"),
88 },
@@ -413,6 +420,105 @@ var keyRmCmd = &cmds.Command{
420 Type: KeyOutputList{},
421 }
422
423 +var keyRotateCmd = &cmds.Command{
424 + Helptext: cmds.HelpText{
425 + Tagline: "Rotates the ipfs identity.",
426 + ShortDescription: `
427 +Generates a new ipfs identity and saves it to the ipfs config file.
428 +The daemon must not be running when calling this command.
429 +
430 +ipfs uses a repository in the local file system. By default, the repo is
431 +located at ~/.ipfs. To change the repo location, set the $IPFS_PATH
432 +environment variable:
433 +
434 + export IPFS_PATH=/path/to/ipfsrepo
435 +`,
436 + },
437 + Arguments: []cmds.Argument{},
438 + Options: []cmds.Option{
439 + cmds.StringOption(oldKeyOptionName, "o", "Keystore name for the old/rotated-out key."),
440 + cmds.StringOption(keyStoreAlgorithmOptionName, "a", "Cryptographic algorithm to use for key generation.").WithDefault(keyStoreAlgorithmDefault),
441 + cmds.IntOption(keyStoreBitsOptionName, "b", "Number of bits to use in the generated RSA private key."),
442 + },
443 + NoRemote: true,
444 + PreRun: func(req *cmds.Request, env cmds.Environment) error {
445 + cctx := env.(*oldcmds.Context)
446 + daemonLocked, err := fsrepo.LockedByOtherProcess(cctx.ConfigRoot)
447 + if err != nil {
448 + return err
449 + }
450 +
451 + log.Info("checking if daemon is running...")
452 + if daemonLocked {
453 + log.Debug("ipfs daemon is running")
454 + e := "ipfs daemon is running. please stop it to run this command"
455 + return cmds.ClientError(e)
456 + }
457 +
458 + return nil
459 + },
460 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
461 + cctx := env.(*oldcmds.Context)
462 + nBitsForKeypair, nBitsGiven := req.Options[keyStoreBitsOptionName].(int)
463 + algorithm, _ := req.Options[keyStoreAlgorithmOptionName].(string)
464 + oldKey, ok := req.Options[oldKeyOptionName].(string)
465 + if !ok {
466 + return fmt.Errorf("keystore name for backing up old key must be provided")
467 + }
468 + return doRotate(os.Stdout, cctx.ConfigRoot, oldKey, algorithm, nBitsForKeypair, nBitsGiven)
469 + },
470 +}
471 +
472 +func doRotate(out io.Writer, repoRoot string, oldKey string, algorithm string, nBitsForKeypair int, nBitsGiven bool) error {
473 + // Open repo
474 + repo, err := fsrepo.Open(repoRoot)
475 + if err != nil {
476 + return fmt.Errorf("opening repo (%v)", err)
477 + }
478 + defer repo.Close()
479 +
480 + // Read config file from repo
481 + cfg, err := repo.Config()
482 + if err != nil {
483 + return fmt.Errorf("reading config from repo (%v)", err)
484 + }
485 +
486 + // Generate new identity
487 + var identity config.Identity
488 + if nBitsGiven {
489 + identity, err = config.CreateIdentity(out, []options.KeyGenerateOption{
490 + options.Key.Size(nBitsForKeypair),
491 + options.Key.Type(algorithm),
492 + })
493 + } else {
494 + identity, err = config.CreateIdentity(out, []options.KeyGenerateOption{
495 + options.Key.Type(algorithm),
496 + })
497 + }
498 + if err != nil {
499 + return fmt.Errorf("creating identity (%v)", err)
500 + }
501 +
502 + // Save old identity to keystore
503 + oldPrivKey, err := cfg.Identity.DecodePrivateKey("")
504 + if err != nil {
505 + return fmt.Errorf("decoding old private key (%v)", err)
506 + }
507 + keystore := repo.Keystore()
508 + if err := keystore.Put(oldKey, oldPrivKey); err != nil {
509 + return fmt.Errorf("saving old key in keystore (%v)", err)
510 + }
511 +
512 + // Update identity
513 + cfg.Identity = identity
514 +
515 + // Write config file to repo
516 + if err = repo.SetConfig(cfg); err != nil {
517 + return fmt.Errorf("saving new key to config (%v)", err)
518 + }
519 + return nil
520 +}
521 +
522 func verifyIDFormatLabel(formatLabel string) error {
523 switch formatLabel {
524 case "b58mh":
test/sharness/t0027-rotate.sh
+3 -3
@@ -35,13 +35,13 @@ test_rotate() {
35 test_expect_success "rotating keys" '
36 case $TO_ALG in
37 rsa)
38 - ipfs rotate -a=rsa -b=2048 --oldkey=oldkey
38 + ipfs key rotate -a=rsa -b=2048 --oldkey=oldkey
39 ;;
40 ed25519)
41 - ipfs rotate -a=ed25519 --oldkey=oldkey
41 + ipfs key rotate -a=ed25519 --oldkey=oldkey
42 ;;
43 *)
44 - ipfs rotate --oldkey=oldkey
44 + ipfs key rotate --oldkey=oldkey
45 ;;
46 esac
47 '