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
This commit is contained in:
Hendrik 'T4cC0re' Meyer 2021-07-18 22:41:01 +02:00
parent 126388e321
commit c5a8b1f2f7

View file

@ -156,7 +156,7 @@ func (key *Key) Unlock(passphrase []byte) (*Key, error) {
} }
for _, sub := range unlockedKey.entity.Subkeys { 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 { if err := sub.PrivateKey.Decrypt(passphrase); err != nil {
return nil, errors.Wrap(err, "gopenpgp: error in unlocking sub key") 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") return true, errors.New("gopenpgp: a public key cannot be locked")
} }
encryptedKeys := 0
for _, sub := range key.entity.Subkeys { for _, sub := range key.entity.Subkeys {
if sub.PrivateKey != nil && !sub.PrivateKey.Encrypted { if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted {
return false, nil 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. // 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") return true, errors.New("gopenpgp: a public key cannot be unlocked")
} }
encryptedKeys := 0
for _, sub := range key.entity.Subkeys { for _, sub := range key.entity.Subkeys {
if sub.PrivateKey != nil && sub.PrivateKey.Encrypted { if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted {
return false, nil 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 // Check verifies if the public keys match the private key parameters by