decryption: always request key passphrase based on key ID

This commit is contained in:
Lysann Tranvouez 2026-03-10 17:14:11 +01:00
parent c4f81c16eb
commit 01739e5aec
4 changed files with 23 additions and 17 deletions

View file

@ -70,7 +70,7 @@ struct GopenPGPInterface: PGPInterface {
privateKeys.keys.contains { key in key.hasSuffix(keyID.lowercased()) } privateKeys.keys.contains { key in key.hasSuffix(keyID.lowercased()) }
} }
func decrypt(encryptedData: Data, keyID: String?, passphrase: String) throws -> Data? { func decrypt(encryptedData: Data, keyID: String?, passPhraseForKey: @escaping (String) -> String) throws -> Data? {
let key: CryptoKey? = { let key: CryptoKey? = {
if let keyID { if let keyID {
return privateKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value return privateKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value
@ -87,6 +87,7 @@ struct GopenPGPInterface: PGPInterface {
try privateKey.isLocked(&isLocked) try privateKey.isLocked(&isLocked)
var unlockedKey: CryptoKey! var unlockedKey: CryptoKey!
if isLocked.boolValue { if isLocked.boolValue {
let passphrase = passPhraseForKey(privateKey.getFingerprint())
unlockedKey = try privateKey.unlock(passphrase.data(using: .utf8)) unlockedKey = try privateKey.unlock(passphrase.data(using: .utf8))
} else { } else {
unlockedKey = privateKey unlockedKey = privateKey

View file

@ -24,8 +24,13 @@ struct ObjectivePGPInterface: PGPInterface {
} }
} }
func decrypt(encryptedData: Data, keyID _: String?, passphrase: String) throws -> Data? { func decrypt(encryptedData: Data, keyID _: String?, passPhraseForKey: @escaping (String) -> String) throws -> Data? {
try ObjectivePGP.decrypt(encryptedData, andVerifySignature: false, using: keyring.keys) { _ in passphrase } try ObjectivePGP.decrypt(encryptedData, andVerifySignature: false, using: keyring.keys) { selectedKey in
guard let selectedKey else {
return nil
}
return passPhraseForKey(selectedKey.keyID.longIdentifier)
}
} }
func encrypt(plainData: Data, keyID _: String?) throws -> Data { func encrypt(plainData: Data, keyID _: String?) throws -> Data {

View file

@ -69,14 +69,14 @@ public class PGPAgent {
latestDecryptStatus = false latestDecryptStatus = false
// Get the PGP key passphrase. // Get the PGP key passphrase.
var passphrase = "" let providePassPhraseForKey = { (selectedKeyID: String) -> String in
if previousDecryptStatus == false { if previousDecryptStatus == false {
passphrase = requestPGPKeyPassphrase(keyID) return requestPGPKeyPassphrase(selectedKeyID)
} else { }
passphrase = keyStore.get(for: AppKeychain.getPGPKeyPassphraseKey(keyID: keyID)) ?? requestPGPKeyPassphrase(keyID) return self.keyStore.get(for: AppKeychain.getPGPKeyPassphraseKey(keyID: selectedKeyID)) ?? requestPGPKeyPassphrase(selectedKeyID)
} }
// Decrypt. // Decrypt.
guard let result = try pgpInterface.decrypt(encryptedData: encryptedData, keyID: keyID, passphrase: passphrase) else { guard let result = try pgpInterface.decrypt(encryptedData: encryptedData, keyID: keyID, passPhraseForKey: providePassPhraseForKey) else {
return nil return nil
} }
// The decryption step has succeed. // The decryption step has succeed.
@ -100,21 +100,21 @@ public class PGPAgent {
return try pgpInterface.encrypt(plainData: plainData, keyID: keyID) return try pgpInterface.encrypt(plainData: plainData, keyID: keyID)
} }
public func decrypt(encryptedData: Data, requestPGPKeyPassphrase: (String) -> String) throws -> Data? { public func decrypt(encryptedData: Data, requestPGPKeyPassphrase: @escaping (String) -> String) throws -> Data? {
// Remember the previous status and set the current status // Remember the previous status and set the current status
let previousDecryptStatus = latestDecryptStatus let previousDecryptStatus = latestDecryptStatus
latestDecryptStatus = false latestDecryptStatus = false
// Init keys. // Init keys.
try checkAndInit() try checkAndInit()
// Get the PGP key passphrase. // Get the PGP key passphrase.
var passphrase = "" let providePassPhraseForKey = { (selectedKeyID: String) -> String in
if previousDecryptStatus == false { if previousDecryptStatus == false {
passphrase = requestPGPKeyPassphrase("") return requestPGPKeyPassphrase(selectedKeyID)
} else { }
passphrase = keyStore.get(for: AppKeychain.getPGPKeyPassphraseKey(keyID: "")) ?? requestPGPKeyPassphrase("") return self.keyStore.get(for: AppKeychain.getPGPKeyPassphraseKey(keyID: selectedKeyID)) ?? requestPGPKeyPassphrase(selectedKeyID)
} }
// Decrypt. // Decrypt.
guard let result = try pgpInterface!.decrypt(encryptedData: encryptedData, keyID: nil, passphrase: passphrase) else { guard let result = try pgpInterface!.decrypt(encryptedData: encryptedData, keyID: nil, passPhraseForKey: providePassPhraseForKey) else {
return nil return nil
} }
// The decryption step has succeed. // The decryption step has succeed.

View file

@ -7,7 +7,7 @@
// //
protocol PGPInterface { protocol PGPInterface {
func decrypt(encryptedData: Data, keyID: String?, passphrase: String) throws -> Data? func decrypt(encryptedData: Data, keyID: String?, passPhraseForKey: @escaping (String) -> String) throws -> Data?
func encrypt(plainData: Data, keyID: String?) throws -> Data func encrypt(plainData: Data, keyID: String?) throws -> Data