Store PGP keys in Keychain

This commit is contained in:
Danny Moesch 2019-06-24 23:37:01 +02:00 committed by Mingshen Sun
parent ca3271b20a
commit a66a79abc6
5 changed files with 40 additions and 53 deletions

View file

@ -90,8 +90,8 @@ class PGPKeyArmorSettingTableViewController: AutoCellHeightUITableViewController
override func viewDidLoad() {
super.viewDidLoad()
armorPublicKeyTextView.text = SharedDefaults[.pgpPublicKeyArmor]
armorPrivateKeyTextView.text = SharedDefaults[.pgpPrivateKeyArmor]
armorPublicKeyTextView.text = String(data: Utils.getDataFromKeychain(for: PasswordStore.PGPKeyType.PUBLIC.rawValue)!, encoding: .ascii)
armorPrivateKeyTextView.text = String(data: Utils.getDataFromKeychain(for: PasswordStore.PGPKeyType.PRIVATE.rawValue)!, encoding: .ascii)
pgpPassphrase = passwordStore.pgpKeyPassphrase
scanPublicKeyCell?.textLabel?.text = "ScanPublicKeyQrCodes".localize()

View file

@ -59,17 +59,13 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
if SharedDefaults[.isRememberPGPPassphraseOn] {
self.passwordStore.pgpKeyPassphrase = controller.pgpPassphrase
}
SharedDefaults[.pgpPublicKeyArmor] = controller.armorPublicKeyTextView.text!
SharedDefaults[.pgpPrivateKeyArmor] = controller.armorPrivateKeyTextView.text!
SVProgressHUD.setDefaultMaskType(.black)
SVProgressHUD.setDefaultStyle(.light)
SVProgressHUD.show(withStatus: "FetchingPgpKey".localize())
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
do {
try self.passwordStore.initPGPKey(with: SharedDefaults[.pgpPublicKeyArmor] ?? "", keyType: .PUBLIC)
try self.passwordStore.initPGPKey(with: SharedDefaults[.pgpPrivateKeyArmor] ?? "", keyType: .PRIVATE)
try self.passwordStore.initPGPKey(with: controller.armorPublicKeyTextView.text ?? "", keyType: .PUBLIC)
try self.passwordStore.initPGPKey(with: controller.armorPrivateKeyTextView.text ?? "", keyType: .PRIVATE)
DispatchQueue.main.async {
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
SVProgressHUD.showSuccess(withStatus: "Success".localize())

View file

@ -16,9 +16,6 @@ public extension DefaultsKeys {
static let pgpPublicKeyURL = DefaultsKey<URL?>("pgpPublicKeyURL")
static let pgpPrivateKeyURL = DefaultsKey<URL?>("pgpPrivateKeyURL")
static let pgpPublicKeyArmor = DefaultsKey<String?>("pgpPublicKeyArmor")
static let pgpPrivateKeyArmor = DefaultsKey<String?>("pgpPrivateKeyArmor")
static let gitURL = DefaultsKey<URL?>("gitURL")
static let gitAuthenticationMethod = DefaultsKey<String?>("gitAuthenticationMethod")
static let gitUsername = DefaultsKey<String?>("gitUsername")

View file

@ -32,6 +32,14 @@ public class Utils {
try? keychain.removeAll()
}
public static func addDataToKeychain(key: String, data: Data) {
keychain[data: key] = data
}
public static func getDataFromKeychain(for key: String) -> Data? {
return try? keychain.getData(key)
}
public static func copyToPasteboard(textToCopy: String?) {
guard textToCopy != nil else {
return

View file

@ -34,8 +34,9 @@ public class PasswordStore {
}
}
public var privateKey: GopenpgpwrapperKey?
public enum PGPKeyType {
case PUBLIC, PRIVATE
public enum PGPKeyType: String {
case PUBLIC = "pgpPublicKey"
case PRIVATE = "pgpPrivateKey"
}
public var gitSignatureForNow: GTSignature? {
@ -196,55 +197,31 @@ public class PasswordStore {
try initPGPKey(.PRIVATE)
}
public func initPGPKey(_ keyType: PGPKeyType) throws {
switch keyType {
case .PUBLIC:
let keyPath = Globals.pgpPublicKeyPath
self.publicKey = importKey(from: keyPath)
if self.publicKey == nil {
throw AppError.KeyImport
}
case .PRIVATE:
let keyPath = Globals.pgpPrivateKeyPath
self.privateKey = importKey(from: keyPath)
if self.privateKey == nil {
throw AppError.KeyImport
private func initPGPKey(_ keyType: PGPKeyType) throws {
if let key = GopenpgpwrapperReadKey(Utils.getDataFromKeychain(for: keyType.rawValue)) {
switch keyType {
case .PUBLIC:
self.publicKey = key
case .PRIVATE:
self.privateKey = key
}
return
}
throw AppError.KeyImport
}
public func initPGPKey(from url: URL, keyType: PGPKeyType) throws {
var pgpKeyLocalPath = ""
if keyType == .PUBLIC {
pgpKeyLocalPath = Globals.pgpPublicKeyPath
} else {
pgpKeyLocalPath = Globals.pgpPrivateKeyPath
}
let pgpKeyData = try Data(contentsOf: url)
try pgpKeyData.write(to: URL(fileURLWithPath: pgpKeyLocalPath), options: .atomic)
Utils.addDataToKeychain(key: keyType.rawValue, data: pgpKeyData)
try initPGPKey(keyType)
}
public func initPGPKey(with armorKey: String, keyType: PGPKeyType) throws {
var pgpKeyLocalPath = ""
if keyType == .PUBLIC {
pgpKeyLocalPath = Globals.pgpPublicKeyPath
} else {
pgpKeyLocalPath = Globals.pgpPrivateKeyPath
}
try armorKey.write(toFile: pgpKeyLocalPath, atomically: true, encoding: .ascii)
let pgpKeyData = armorKey.data(using: .ascii)!
Utils.addDataToKeychain(key: keyType.rawValue, data: pgpKeyData)
try initPGPKey(keyType)
}
private func importKey(from keyPath: String) -> GopenpgpwrapperKey? {
if fm.fileExists(atPath: keyPath) {
return GopenpgpwrapperReadKey(fm.contents(atPath: keyPath))
}
return nil
}
public func repositoryExisted() -> Bool {
let fm = FileManager()
return fm.fileExists(atPath: Globals.repositoryPath)
@ -846,11 +823,11 @@ public class PasswordStore {
try? fm.removeItem(atPath: Globals.pgpPublicKeyPath)
try? fm.removeItem(atPath: Globals.pgpPrivateKeyPath)
SharedDefaults.remove(.pgpKeySource)
SharedDefaults.remove(.pgpPublicKeyArmor)
SharedDefaults.remove(.pgpPrivateKeyArmor)
SharedDefaults.remove(.pgpPrivateKeyURL)
SharedDefaults.remove(.pgpPublicKeyURL)
Utils.removeKeychain(name: ".pgpKeyPassphrase")
Utils.removeKeychain(name: PGPKeyType.PUBLIC.rawValue)
Utils.removeKeychain(name: PGPKeyType.PRIVATE.rawValue)
publicKey = nil
privateKey = nil
}
@ -883,7 +860,16 @@ public class PasswordStore {
}
public func pgpKeyImportFromFileSharing() throws {
try fm.moveItem(atPath: Globals.iTunesFileSharingPGPPublic, toPath: Globals.pgpPublicKeyPath)
try fm.moveItem(atPath: Globals.iTunesFileSharingPGPPrivate, toPath: Globals.pgpPrivateKeyPath)
let publicKeyFileUrl = URL(fileURLWithPath: Globals.iTunesFileSharingPGPPublic)
let privateKeyFileUrl = URL(fileURLWithPath: Globals.iTunesFileSharingPGPPrivate)
let publicKeyFileContent = try Data(contentsOf: publicKeyFileUrl)
let privateKeyFileContent = try Data(contentsOf: privateKeyFileUrl)
Utils.addDataToKeychain(key: PGPKeyType.PUBLIC.rawValue, data: publicKeyFileContent)
Utils.addDataToKeychain(key: PGPKeyType.PRIVATE.rawValue, data: privateKeyFileContent)
try fm.removeItem(at: publicKeyFileUrl)
try fm.removeItem(at: privateKeyFileUrl)
}
}