From c5a8b1f2f744f052c2a5159b4415379b6c582b35 Mon Sep 17 00:00:00 2001 From: Hendrik 'T4cC0re' Meyer Date: Sun, 18 Jul 2021 22:41:01 +0200 Subject: [PATCH] Disregard GNU dummy subkeys when checking (un)locked state and unlocking a crypto.Key Because a GNU dummy key has a `PrivateKey` property, the existing check will count it as a key to be decrypted. However, a `Decrypt` call on such key will then yield an error, as it is a dummy key. This commit addresses this behaviour by summing all valid decrpytable private keys and returning on their count. Further, it adapts `Unlock` to ignore any dummy subkey. Fixes #138 --- crypto/key.go | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/crypto/key.go b/crypto/key.go index 49af11e..38a9e8c 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -156,7 +156,7 @@ func (key *Key) Unlock(passphrase []byte) (*Key, error) { } for _, sub := range unlockedKey.entity.Subkeys { - if sub.PrivateKey != nil { + if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() { if err := sub.PrivateKey.Decrypt(passphrase); err != nil { return nil, errors.Wrap(err, "gopenpgp: error in unlocking sub key") } @@ -280,13 +280,19 @@ func (key *Key) IsLocked() (bool, error) { return true, errors.New("gopenpgp: a public key cannot be locked") } + encryptedKeys := 0 + for _, sub := range key.entity.Subkeys { - if sub.PrivateKey != nil && !sub.PrivateKey.Encrypted { - return false, nil + if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted { + encryptedKeys++ } } - return key.entity.PrivateKey.Encrypted, nil + if key.entity.PrivateKey.Encrypted { + encryptedKeys++ + } + + return encryptedKeys > 0, nil } // IsUnlocked checks if a private key is unlocked. @@ -295,13 +301,19 @@ func (key *Key) IsUnlocked() (bool, error) { return true, errors.New("gopenpgp: a public key cannot be unlocked") } + encryptedKeys := 0 + for _, sub := range key.entity.Subkeys { - if sub.PrivateKey != nil && sub.PrivateKey.Encrypted { - return false, nil + if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted { + encryptedKeys++ } } - return !key.entity.PrivateKey.Encrypted, nil + if key.entity.PrivateKey.Encrypted { + encryptedKeys++ + } + + return encryptedKeys == 0, nil } // Check verifies if the public keys match the private key parameters by