So the system can have multiple private keys, and the caller doesn't need to specify a specific one regardless. Ideally: If there are several matches we could also take into account which keys have already been unlocked (or passthrases saved in keychain). Right now it only grabs the first match.
59 lines
2 KiB
Swift
59 lines
2 KiB
Swift
//
|
|
// ObjectivePGPInterface.swift
|
|
// passKit
|
|
//
|
|
// Created by Danny Moesch on 08.09.19.
|
|
// Copyright © 2019 Bob Sun. All rights reserved.
|
|
//
|
|
|
|
import ObjectivePGP
|
|
|
|
struct ObjectivePGPInterface: PGPInterface {
|
|
private let keyring = ObjectivePGP.defaultKeyring
|
|
|
|
init(publicArmoredKey: String, privateArmoredKey: String) throws {
|
|
guard let publicKeyData = publicArmoredKey.data(using: .ascii), let privateKeyData = privateArmoredKey.data(using: .ascii) else {
|
|
throw AppError.keyImport
|
|
}
|
|
let publicKeys = try ObjectivePGP.readKeys(from: publicKeyData)
|
|
let privateKeys = try ObjectivePGP.readKeys(from: privateKeyData)
|
|
keyring.import(keys: publicKeys)
|
|
keyring.import(keys: privateKeys)
|
|
guard publicKeys.first != nil, privateKeys.first != nil else {
|
|
throw AppError.keyImport
|
|
}
|
|
}
|
|
|
|
func decrypt(encryptedData: Data, keyIDHint _: String?, passPhraseForKey: @escaping (String) -> String) throws -> Data? {
|
|
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 {
|
|
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)!
|
|
}
|
|
return encryptedData
|
|
}
|
|
|
|
func containsPublicKey(with keyID: String) -> Bool {
|
|
keyring.findKey(keyID)?.isPublic ?? false
|
|
}
|
|
|
|
func containsPrivateKey(with keyID: String) -> Bool {
|
|
keyring.findKey(keyID)?.isSecret ?? false
|
|
}
|
|
|
|
var keyID: [String] {
|
|
keyring.keys.map(\.keyID.longIdentifier)
|
|
}
|
|
|
|
var shortKeyID: [String] {
|
|
keyring.keys.map(\.keyID.shortIdentifier)
|
|
}
|
|
}
|