diff --git a/internal/decryptor/main.go b/internal/decryptor/main.go index b100523..845303c 100644 --- a/internal/decryptor/main.go +++ b/internal/decryptor/main.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/nicola-strappazzon/password-manager/internal/card" + "github.com/nicola-strappazzon/password-manager/internal/config" "github.com/nicola-strappazzon/password-manager/internal/openpgp" "github.com/nicola-strappazzon/password-manager/internal/term" ) @@ -16,6 +17,14 @@ func Decrypt(passphrase, path string) (card.Card, error) { return card.Card{}, err } + belongs, err := openpgp.KeyBelongsToRecipient(cardID, config.GetRecipient()) + if err != nil { + return card.Card{}, err + } + if !belongs { + return card.Card{}, fmt.Errorf("This file is not encrypted for the configured recipient (%s).", config.GetRecipient()) + } + useCard, err := openpgp.RequiresSmartCard(cardID) if err != nil { return card.Card{}, err diff --git a/internal/openpgp/main.go b/internal/openpgp/main.go index 5e738ef..00404e7 100644 --- a/internal/openpgp/main.go +++ b/internal/openpgp/main.go @@ -82,6 +82,39 @@ func CardIsReady() error { return nil } +func KeyBelongsToRecipient(keyID, recipient string) (bool, error) { + lookup := strings.TrimSuffix(recipient, "!") + out, err := runCommand(nil, "gpg", "--with-colons", "--list-keys", lookup) + if err != nil { + return false, fmt.Errorf("recipient %q not found in keyring", recipient) + } + + keyID = strings.ToUpper(keyID) + + for _, line := range strings.Split(string(out), "\n") { + fields := strings.Split(line, ":") + if len(fields) < 5 { + continue + } + switch fields[0] { + case "pub", "sub": + id := strings.ToUpper(fields[4]) + if strings.HasSuffix(id, keyID) || strings.HasSuffix(keyID, id) { + return true, nil + } + case "fpr": + if len(fields) >= 10 { + fpr := strings.ToUpper(fields[9]) + if strings.HasSuffix(fpr, keyID) || strings.HasSuffix(keyID, fpr) { + return true, nil + } + } + } + } + + return false, nil +} + func Encrypt(in, recipient string) (out []byte, err error) { out, err = runCommand( []byte(in),