Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code refactor, added support for multiple public keys #2

Merged
merged 3 commits into from
Sep 25, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
feat(keys): ability to specify multiple public keys
  • Loading branch information
xanmanning committed Sep 25, 2021
commit 4006176aa0017d36991d657bf0b105bdb9df4615
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,24 @@ To dump, you need to ensure you have the following:
}
```

Example command using a public key:
Example dump command using multiple public keys:

```bash
$ ./vault_dump \
dump \
--file="$(date +%s).json.asc" \
--key=me@email.com.pub # This is a public key
--key=me.at.email.com.pub \ # This is one public key
--key=you.at.email.com.pub # This is another public key
```

Example command using a private key:
Example dump command using a private key (not recommended):

```bash
$ ./vault_dump \
dump \
--file="$(date +%s).json.asc" \
--passphrase="yo_r-Str0ng-Pa55-phRaSe" \ # This can also be specified with VAULT_DUMP_PASSPHRASE environment variable
--key=me@email.com.asc # This is a private key
--key=me.at.email.com.asc # This is a private key
```

### Restore prerequisites
Expand Down
10 changes: 5 additions & 5 deletions cmd/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ var dumpCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(dumpCmd)

dumpCmd.PersistentFlags().StringVarP(&core.KeyFile, "key", "k",
"", "gpg key to use (private key required for decryption)")
dumpCmd.PersistentFlags().StringSliceVarP(&core.KeyFile, "key", "k",
nil, "gpg key(s) to use for encryption")

dumpCmd.PersistentFlags().StringVarP(&core.OutFile, "file", "f",
"", "output file for dump")
Expand Down Expand Up @@ -143,7 +143,7 @@ func runDump() {
core.Logger.Debug("core.Logger created")
core.Logger.Debug("run() called")

if core.KeyFile == "" {
if core.KeyFile == nil {
core.Logger.Debug("empty key file path string",
"file", core.KeyFile)
core.Logger.Error("--key needs and argument")
Expand All @@ -168,8 +168,8 @@ func runDump() {
core.Logger.Error("failed to encrypt dump output", "err", err)
os.Exit(1)
} else {
core.Logger.Info("encrypted json file with key",
"key", core.KeyFile)
core.Logger.Info("encrypted json file with keys",
"keys", core.KeyFile)
}

output, err := out.GetArmored()
Expand Down
6 changes: 3 additions & 3 deletions cmd/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ var restoreCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(restoreCmd)

restoreCmd.PersistentFlags().StringVarP(&core.KeyFile, "key", "k",
"", "gpg key to use (private key required for decryption)")
restoreCmd.PersistentFlags().StringSliceVarP(&core.KeyFile, "key", "k",
nil, "gpg key to use (private key required for decryption)")

restoreCmd.PersistentFlags().StringVarP(&core.InFile, "file", "f",
"", "input file for restore")
Expand Down Expand Up @@ -159,7 +159,7 @@ func runRestore() {
core.Logger.Debug("core.Logger created")
core.Logger.Debug("run() called")

if core.KeyFile == "" {
if core.KeyFile == nil {
core.Logger.Debug("empty key file path string",
"KeyFile", core.KeyFile)
core.Logger.Error("--key needs and argument")
Expand Down
102 changes: 52 additions & 50 deletions core/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var (
IgnoreAddress bool
InFile string
IsRestore bool = false
KeyFile string
KeyFile []string
KeyRing crypto.KeyRing
KeyPass string
LogFmt bool
Expand Down Expand Up @@ -88,74 +88,76 @@ func LoadKey() crypto.KeyRing {
KeyPass = EPassPhrase
}

raw_key, err := ioutil.ReadFile(KeyFile)

KeyRing, err := crypto.NewKeyRing(nil)
if err != nil {
Logger.Error("unable to read file", "key", KeyFile, "err", err)
os.Exit(1)
}

keyObj, err := crypto.NewKeyFromArmored(string(raw_key))

if err != nil {
Logger.Error("unable to read key", "key", KeyFile, "err", err)
Logger.Error("cannot create key ring", "err", err)
os.Exit(1)
}

if keyObj.IsPrivate() {
Logger.Debug("private key loaded: can encrypt and decrypt")
isLocked, err := keyObj.IsLocked()
for _, keyfile := range KeyFile {
raw_key, err := ioutil.ReadFile(keyfile)
if err != nil {
Logger.Error("unable to determine if key is locked", "err", err)
Logger.Error("unable to read file", "key", keyfile, "err", err)
os.Exit(1)
}
if isLocked {
Logger.Debug("key information", "locked", "true")

if KeyPass == "" {
Logger.Error("cannot unlock key," +
"no passphrase specified" +
"(--passphrase|-p|VAULT_DUMP_PASSPHRASE)")
os.Exit(1)
}
keyObj, err := crypto.NewKeyFromArmored(string(raw_key))
if err != nil {
Logger.Error("unable to read key", "key", keyfile, "err", err)
os.Exit(1)
}

keyObjUnlocked, err = keyObj.Unlock([]byte(KeyPass))
if keyObj.IsPrivate() {
Logger.Debug("private key loaded: can encrypt and decrypt")
isLocked, err := keyObj.IsLocked()
if err != nil {
Logger.Error("unable to unlock key", "err", err)
Logger.Error("unable to determine if key is locked", "err", err)
os.Exit(1)
}

Logger.Debug("key unlocked")
if isLocked {
Logger.Debug("key information", "locked", "true")

if KeyPass == "" {
Logger.Error("cannot unlock key," +
"no passphrase specified" +
"(--passphrase|-p|VAULT_DUMP_PASSPHRASE)")
os.Exit(1)
}

keyObjUnlocked, err = keyObj.Unlock([]byte(KeyPass))
if err != nil {
Logger.Error("unable to unlock key", "err", err)
os.Exit(1)
}

Logger.Debug("key unlocked")
} else {
keyObjUnlocked = keyObj
}
} else {
Logger.Debug("public key loaded: can encrypt only")
Logger.Debug("is this a restore?", "IsRestore", IsRestore)
if IsRestore {
Logger.Error("key file is a public key, cannot decrypt vault dump",
"KeyFile", KeyFile)
os.Exit(1)
}
keyObjUnlocked = keyObj
}
} else {
Logger.Debug("public key loaded: can encrypt only")
Logger.Debug("is this a restore?", "IsRestore", IsRestore)
if IsRestore {
Logger.Error("key file is a public key, cannot decrypt vault dump",
"KeyFile", KeyFile)
os.Exit(1)
}
keyObjUnlocked = keyObj
}

if keyObjUnlocked.IsExpired() {
Logger.Warn("key has expired")
}

Logger.Debug("key information", "fingerprint",
keyObjUnlocked.GetFingerprint())
Logger.Debug("key information", "id",
keyObjUnlocked.GetKeyID())
Logger.Debug("key information", "hex",
keyObjUnlocked.GetHexKeyID())
if keyObjUnlocked.IsExpired() {
Logger.Warn("key has expired")
}

KeyRing, err := crypto.NewKeyRing(keyObjUnlocked)
Logger.Debug("key information", "fingerprint",
keyObjUnlocked.GetFingerprint())
Logger.Debug("key information", "id",
keyObjUnlocked.GetKeyID())
Logger.Debug("key information", "hex",
keyObjUnlocked.GetHexKeyID())

if err != nil {
Logger.Error("cannot create key ring", "err", err)
os.Exit(1)
KeyRing.AddKey(keyObjUnlocked)
}

return *KeyRing
Expand Down