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
'