Update to gopengpg v2.0.0

This commit is contained in:
Mingshen Sun 2020-04-11 23:23:38 -07:00
parent 9a688b518f
commit 84b1c07f64
13 changed files with 314 additions and 56 deletions

View file

@ -11,42 +11,56 @@ import Crypto
struct GopenPgp: PgpInterface {
private static let errorMapping: [String: Error] = [
"openpgp: invalid data: private key checksum failure": AppError.WrongPassphrase,
"gopenpgp: error in unlocking key: openpgp: invalid data: private key checksum failure": AppError.WrongPassphrase,
"openpgp: incorrect key": AppError.KeyExpiredOrIncompatible,
]
private let publicKey: CryptoKeyRing
private let privateKey: CryptoKeyRing
private let publicKey: CryptoKey
private let privateKey: CryptoKey
init(publicArmoredKey: String, privateArmoredKey: String) throws {
var error: NSError?
guard let publicKey = CryptoBuildKeyRingArmored(publicArmoredKey, &error),
let privateKey = CryptoBuildKeyRingArmored(privateArmoredKey, &error) else {
guard let publicKey = CryptoNewKeyFromArmored(publicArmoredKey, &error),
let privateKey = CryptoNewKeyFromArmored(privateArmoredKey, &error) else {
guard error == nil else {
throw error!
}
throw AppError.KeyImport
}
guard error == nil else {
throw error!
}
self.publicKey = publicKey
self.privateKey = privateKey
}
func decrypt(encryptedData: Data, passphrase: String) throws -> Data? {
func decrypt(encryptedData: Data, keyID: String, passphrase: String) throws -> Data? {
do {
try privateKey.unlock(withPassphrase: passphrase)
} catch {
throw Self.errorMapping[error.localizedDescription, default: error]
}
let message = createPgpMessage(from: encryptedData)
do {
return try privateKey.decrypt(message, verifyKey: nil, verifyTime: 0).data
let unlockedKey = try privateKey.unlock(passphrase.data(using: .utf8))
var error: NSError?
guard let keyRing = CryptoNewKeyRing(unlockedKey, &error) else {
guard error == nil else {
throw error!
}
throw AppError.Decryption
}
let message = createPgpMessage(from: encryptedData)
return try keyRing.decrypt(message, verifyKey: nil, verifyTime: 0).data
} catch {
throw Self.errorMapping[error.localizedDescription, default: error]
}
}
func encrypt(plainData: Data) throws -> Data {
let encryptedData = try publicKey.encrypt(CryptoNewPlainMessage(plainData.mutable as Data), privateKey: nil)
func encrypt(plainData: Data, keyID: String) throws -> Data {
var error: NSError?
guard let keyRing = CryptoNewKeyRing(publicKey, &error) else {
guard error == nil else {
throw error!
}
throw AppError.Encryption
}
let encryptedData = try keyRing.encrypt(CryptoNewPlainMessage(plainData.mutable as Data), privateKey: nil)
if Defaults.encryptInArmored {
var error: NSError?
let armor = encryptedData.getArmored(&error)
@ -60,8 +74,14 @@ struct GopenPgp: PgpInterface {
var keyId: String {
var error: NSError?
let fingerprint = publicKey.getFingerprint(&error)
return error == nil ? String(fingerprint.suffix(8)).uppercased() : ""
let fingerprint = publicKey.getHexKeyID()
return String(fingerprint).uppercased()
}
var shortKeyId: String {
var error: NSError?
let fingerprint = publicKey.getHexKeyID()
return String(fingerprint.suffix(8)).uppercased()
}
private func createPgpMessage(from encryptedData: Data) -> CryptoPGPMessage? {

View file

@ -30,11 +30,11 @@ struct ObjectivePgp: PgpInterface {
self.privateKey = privateKey
}
func decrypt(encryptedData: Data, passphrase: String) throws -> Data? {
func decrypt(encryptedData: Data, keyID: String, passphrase: String) throws -> Data? {
return try ObjectivePGP.decrypt(encryptedData, andVerifySignature: false, using: keyring.keys) { _ in passphrase }
}
func encrypt(plainData: Data) throws -> Data {
func encrypt(plainData: Data, keyID: String) throws -> Data {
let encryptedData = try ObjectivePGP.encrypt(plainData, addSignature: false, using: keyring.keys, passphraseForKey: nil)
if Defaults.encryptInArmored {
return Armor.armored(encryptedData, as: .message).data(using: .ascii)!
@ -43,6 +43,10 @@ struct ObjectivePgp: PgpInterface {
}
var keyId: String {
return publicKey.keyID.longIdentifier
}
var shortKeyId: String {
return publicKey.keyID.shortIdentifier
}
}

View file

@ -40,6 +40,11 @@ public class PGPAgent {
return pgpInterface?.keyId
}
public func getShortKeyId() throws -> String? {
try checkAndInit()
return pgpInterface?.shortKeyId
}
public func decrypt(encryptedData: Data, requestPGPKeyPassphrase: () -> String) throws -> Data? {
// Remember the previous status and set the current status
let previousDecryptStatus = self.latestDecryptStatus
@ -54,7 +59,7 @@ public class PGPAgent {
passphrase = keyStore.get(for: Globals.pgpKeyPassphrase) ?? requestPGPKeyPassphrase()
}
// Decrypt.
guard let result = try pgpInterface!.decrypt(encryptedData: encryptedData, passphrase: passphrase) else {
guard let result = try pgpInterface!.decrypt(encryptedData: encryptedData, keyID: "", passphrase: passphrase) else {
return nil
}
// The decryption step has succeed.
@ -67,7 +72,7 @@ public class PGPAgent {
guard let pgpInterface = pgpInterface else {
throw AppError.Encryption
}
return try pgpInterface.encrypt(plainData: plainData)
return try pgpInterface.encrypt(plainData: plainData, keyID: "")
}
public var isPrepared: Bool {

View file

@ -8,9 +8,11 @@
protocol PgpInterface {
func decrypt(encryptedData: Data, passphrase: String) throws -> Data?
func decrypt(encryptedData: Data, keyID: String, passphrase: String) throws -> Data?
func encrypt(plainData: Data) throws -> Data
func encrypt(plainData: Data, keyID: String) throws -> Data
var keyId: String { get }
var shortKeyId: String { get }
}