summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--_sys/etc/bash_completion.d/gotp4
-rw-r--r--cli.go44
-rw-r--r--cli_test.go19
-rw-r--r--cmd/gotp/main.go30
-rw-r--r--testdata/cli_SetPrivateKey_test.txt2
6 files changed, 92 insertions, 12 deletions
diff --git a/README.md b/README.md
index 6c977bc..85a9579 100644
--- a/README.md
+++ b/README.md
@@ -44,6 +44,11 @@ remove <LABEL>
Remove LABEL from configuration.
+remove-private-key
+
+ Decrypt the issuer's value (hash:secret...) using previous private key and
+ store it back to file as plain text.
+
rename <LABEL> <NEW-LABEL>
Rename a LABEL into NEW-LABEL.
diff --git a/_sys/etc/bash_completion.d/gotp b/_sys/etc/bash_completion.d/gotp
index 3e4bdf2..807147c 100644
--- a/_sys/etc/bash_completion.d/gotp
+++ b/_sys/etc/bash_completion.d/gotp
@@ -15,7 +15,7 @@ suggest_key() {
_gotp_completions()
{
- commands=("add" "gen" "import" "list" "remove" "rename" "set-private-key")
+ commands=("add" "gen" "import" "list" "remove" "remove-private-key" "rename" "set-private-key")
local len=${#COMP_WORDS[@]}
local cmd=${COMP_WORDS[1]}
@@ -38,6 +38,8 @@ _gotp_completions()
suggest_key "$key"
fi
;;
+ remove-private-key)
+ ;;
rename)
if [[ $len == 3 ]]; then
suggest_key "$key"
diff --git a/cli.go b/cli.go
index 46a6d7e..d858faa 100644
--- a/cli.go
+++ b/cli.go
@@ -271,6 +271,50 @@ func (cli *Cli) Remove(label string) (err error) {
return nil
}
+// RemovePrivateKey Decrypt the issuer's value (hash:secret...) using previous
+// private key and store it back to file as plain text.
+func (cli *Cli) RemovePrivateKey() (err error) {
+ if cli.cfg.privateKey == nil {
+ return nil
+ }
+
+ var (
+ logp = `RemovePrivateKey`
+ oldPrivateKey = cli.cfg.privateKey
+ oldIssuers = cli.cfg.Issuers
+
+ issuer *Issuer
+ label string
+ raw string
+ )
+
+ cli.cfg.privateKey = nil
+ cli.cfg.Issuers = map[string]string{}
+
+ for label, raw = range oldIssuers {
+ // Decrypt the issuer using old private key.
+ issuer, err = NewIssuer(label, raw, oldPrivateKey)
+ if err != nil {
+ return fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ // Add it to the config back as plain text.
+ err = cli.cfg.add(issuer)
+ if err != nil {
+ return fmt.Errorf(`%s: %w`, logp, err)
+ }
+ }
+
+ cli.cfg.PrivateKey = ``
+
+ err = cli.cfg.save()
+ if err != nil {
+ return fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ return nil
+}
+
// Rename a label to newLabel.
// It will return an error if the label parameter is not exist or newLabel
// already exist.
diff --git a/cli_test.go b/cli_test.go
index a900ede..70a5e1d 100644
--- a/cli_test.go
+++ b/cli_test.go
@@ -156,7 +156,7 @@ func TestCli_SetPrivateKey(t *testing.T) {
cfg *config
)
- rawConfig = tdata.Input[`config.ini.before`]
+ rawConfig = tdata.Input[`config.ini`]
cfg, err = loadConfig(rawConfig)
if err != nil {
@@ -208,4 +208,21 @@ func TestCli_SetPrivateKey(t *testing.T) {
}
test.Assert(t, `get all labels`, string(tdata.Output[`issuers`]), got.String())
+
+ // Remove the private key, and compare the plain config.
+
+ err = cli.RemovePrivateKey()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var gotConfig []byte
+
+ gotConfig, err = cli.cfg.MarshalText()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ rawConfig = tdata.Input[`config.ini`]
+ test.Assert(t, `RemovePrivateKey`, string(rawConfig), string(gotConfig))
}
diff --git a/cmd/gotp/main.go b/cmd/gotp/main.go
index 466818f..71e5226 100644
--- a/cmd/gotp/main.go
+++ b/cmd/gotp/main.go
@@ -17,15 +17,16 @@ import (
)
const (
- cmdName = `gotp`
- cmdAdd = `add`
- cmdGenerate = `gen`
- cmdImport = `import`
- cmdList = `list`
- cmdRemove = `remove`
- cmdRename = `rename`
- cmdSetPrivateKey = `set-private-key`
- cmdVersion = `version`
+ cmdName = `gotp`
+ cmdAdd = `add`
+ cmdGenerate = `gen`
+ cmdImport = `import`
+ cmdList = `list`
+ cmdRemove = `remove`
+ cmdRemovePrivateKey = `remove-private-key`
+ cmdRename = `rename`
+ cmdSetPrivateKey = `set-private-key`
+ cmdVersion = `version`
)
func main() {
@@ -75,6 +76,8 @@ func main() {
log.Printf(`%s %s: missing parameters`, cmdName, cmd)
os.Exit(1)
}
+ case cmdRemovePrivateKey:
+ // NOOP.
case cmdRename:
if len(args) <= 2 {
log.Printf(`%s %s: missing parameters`, cmdName, cmd)
@@ -113,6 +116,8 @@ func main() {
doList(cli)
case cmdRemove:
doRemove(cli, args)
+ case cmdRemovePrivateKey:
+ doRemovePrivateKey(cli)
case cmdRename:
doRename(cli, args)
case cmdSetPrivateKey:
@@ -213,6 +218,13 @@ func doRemove(cli *gotp.Cli, args []string) {
fmt.Println(`OK`)
}
+func doRemovePrivateKey(cli *gotp.Cli) {
+ var err = cli.RemovePrivateKey()
+ if err != nil {
+ log.Fatalf(`%s: %s`, cmdName, err)
+ }
+}
+
func doRename(cli *gotp.Cli, args []string) {
var (
label = args[1]
diff --git a/testdata/cli_SetPrivateKey_test.txt b/testdata/cli_SetPrivateKey_test.txt
index 1162ead..b767b01 100644
--- a/testdata/cli_SetPrivateKey_test.txt
+++ b/testdata/cli_SetPrivateKey_test.txt
@@ -3,7 +3,7 @@ private_key_openssh: testdata/keys/rsa-openssh.pem
Test setting private key from unencrypted configuration.
->>> config.ini.before
+>>> config.ini
[gotp "issuer"]
test1 = SHA1:a:6:30:
test2 = SHA1:b:6:30: