diff --git a/pass/de.lproj/Localizable.strings b/pass/de.lproj/Localizable.strings index 6e53b83..bd37fd5 100644 --- a/pass/de.lproj/Localizable.strings +++ b/pass/de.lproj/Localizable.strings @@ -130,6 +130,8 @@ "RememberToRemoveKey" = "Vergiss das Löschen des Schlüssels nicht"; "RememberToRemoveKeyFromServer." = "Vergiss nicht, den Schlüssel wieder vom Server zu entfernen."; "RemovePgpKeys" = "PGP-Schlüssel entfernen"; +"KeyExpiredOrIncompatibleError." = "Der öffentliche PGP-Schlüssel ist eventuell abgelaufen oder inkompatibel mit dem privaten Schlüssel."; +"WrongPassphraseError." = "Das Passwort für den privaten PGP-Schlüssel ist falsch."; // App passcode "RemovePasscode" = "Passcode entfernen"; diff --git a/pass/en.lproj/Localizable.strings b/pass/en.lproj/Localizable.strings index 1455d51..d0deb43 100644 --- a/pass/en.lproj/Localizable.strings +++ b/pass/en.lproj/Localizable.strings @@ -131,6 +131,8 @@ "RememberToRemoveKeyFromServer." = "Remember to remove the key from the server."; "RemovePgpKeys" = "Remove PGP Keys"; "PgpCopyPublicAndPrivateKeyToPass." = "Copy your ASCII-armored public and private keys to Pass with names \"gpg_key.pub\" and \"gpg_key\" (without quotes) via iTunes. Then come back and click \"iTunes File Sharing\" to finish."; +"KeyExpiredOrIncompatibleError." = "PGP public key may be expired or incompatible with the private key."; +"WrongPassphraseError." = "Passphrase of your PGP secret key is wrong."; // App passcode "RemovePasscode" = "Remove Passcode"; diff --git a/passKit/Crypto/GopenPgp.swift b/passKit/Crypto/GopenPgp.swift index 24e5684..a7a7a0b 100644 --- a/passKit/Crypto/GopenPgp.swift +++ b/passKit/Crypto/GopenPgp.swift @@ -10,6 +10,11 @@ import Crypto struct GopenPgp: PgpInterface { + private static let errorMapping: [String: Error] = [ + "openpgp: invalid data: private key checksum failure": AppError.WrongPassphrase, + "openpgp: incorrect key": AppError.KeyExpiredOrIncompatible, + ] + private let publicKey: CryptoKeyRing private let privateKey: CryptoKeyRing @@ -22,9 +27,17 @@ struct GopenPgp: PgpInterface { } func decrypt(encryptedData: Data, passphrase: String) throws -> Data? { - try privateKey.unlock(withPassphrase: passphrase) + do { + try privateKey.unlock(withPassphrase: passphrase) + } catch { + throw Self.errorMapping[error.localizedDescription, default: error] + } let message = createPgpMessage(from: encryptedData) - return try privateKey.decrypt(message, verifyKey: nil, verifyTime: 0).data + do { + return try privateKey.decrypt(message, verifyKey: nil, verifyTime: 0).data + } catch { + throw Self.errorMapping[error.localizedDescription, default: error] + } } func encrypt(plainData: Data) throws -> Data { diff --git a/passKit/Helpers/AppError.swift b/passKit/Helpers/AppError.swift index 507e0ca..5c183d6 100644 --- a/passKit/Helpers/AppError.swift +++ b/passKit/Helpers/AppError.swift @@ -17,6 +17,8 @@ public enum AppError: Error, Equatable { case GitCommit case PasswordEntity case PgpPublicKeyNotExist + case KeyExpiredOrIncompatible + case WrongPassphrase case WrongPasswordFilename case Decryption case Encryption diff --git a/passKitTests/Crypto/PGPAgentTest.swift b/passKitTests/Crypto/PGPAgentTest.swift index 7478de8..6347aa7 100644 --- a/passKitTests/Crypto/PGPAgentTest.swift +++ b/passKitTests/Crypto/PGPAgentTest.swift @@ -86,7 +86,7 @@ class PGPAgentTest: XCTestCase { try importKeys(ED25519.publicKey, RSA2048.privateKey) XCTAssert(pgpAgent.isPrepared) XCTAssertThrowsError(try basicEncryptDecrypt(using: pgpAgent)) { - XCTAssert($0.localizedDescription.contains("openpgp: incorrect key")) + XCTAssertEqual($0 as! AppError, AppError.KeyExpiredOrIncompatible) } } @@ -128,7 +128,7 @@ class PGPAgentTest: XCTestCase { // Provide the wrong passphrase. XCTAssertThrowsError(try basicEncryptDecrypt(using: pgpAgent, requestPassphrase: provideIncorrectPassphrase)) { - XCTAssert($0.localizedDescription.contains("openpgp: invalid data: private key checksum failure")) + XCTAssertEqual($0 as! AppError, AppError.WrongPassphrase) } XCTAssertEqual(passphraseRequestCalledCount, 2)