From 441a7f1e9bd62b3fe4ff2138e71888f9ede04f7e Mon Sep 17 00:00:00 2001 From: Danny Moesch Date: Tue, 25 Jun 2019 22:44:19 +0200 Subject: [PATCH] Put Keychain related methods to separate class --- pass.xcodeproj/project.pbxproj | 4 ++ ...GPKeyArmorSettingTableViewController.swift | 10 ++++- passKit/Helpers/AppKeychain.swift | 40 ++++++++++++++++++ passKit/Helpers/Utils.swift | 32 -------------- passKit/Models/PasswordStore.swift | 42 +++++++++++-------- 5 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 passKit/Helpers/AppKeychain.swift diff --git a/pass.xcodeproj/project.pbxproj b/pass.xcodeproj/project.pbxproj index fec6535..05fb57a 100644 --- a/pass.xcodeproj/project.pbxproj +++ b/pass.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 301F6463216162550071A4CE /* AdditionField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6462216162550071A4CE /* AdditionField.swift */; }; 301F6468216165290071A4CE /* ConstantsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6467216165290071A4CE /* ConstantsTest.swift */; }; 301F646D216166AA0071A4CE /* AdditionFieldTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F646C216166AA0071A4CE /* AdditionFieldTest.swift */; }; + 302B2C9822C2BDE700D831EE /* AppKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B2C9722C2BDE700D831EE /* AppKeychain.swift */; }; 302E85612125ECC70031BA64 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85602125ECC70031BA64 /* Parser.swift */; }; 302E85632125EE550031BA64 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85622125EE550031BA64 /* Constants.swift */; }; 30697C2A21F63C5A0064FCAC /* NotificationNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30697C2321F63C580064FCAC /* NotificationNames.swift */; }; @@ -208,6 +209,7 @@ 301F6467216165290071A4CE /* ConstantsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsTest.swift; sourceTree = ""; }; 301F646C216166AA0071A4CE /* AdditionFieldTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionFieldTest.swift; sourceTree = ""; }; 302202EE222F14E400555236 /* SearchBarScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarScope.swift; sourceTree = ""; }; + 302B2C9722C2BDE700D831EE /* AppKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppKeychain.swift; sourceTree = ""; }; 302E85602125ECC70031BA64 /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = ""; }; 302E85622125EE550031BA64 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 30697C2321F63C580064FCAC /* NotificationNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNames.swift; sourceTree = ""; }; @@ -565,6 +567,7 @@ isa = PBXGroup; children = ( 30697C2921F63C590064FCAC /* AppError.swift */, + 302B2C9722C2BDE700D831EE /* AppKeychain.swift */, 30697C2821F63C590064FCAC /* DefaultsKeys.swift */, 30697C2521F63C590064FCAC /* FileManagerExtension.swift */, 30697C2421F63C590064FCAC /* Globals.swift */, @@ -1054,6 +1057,7 @@ 30697C2F21F63C5A0064FCAC /* DefaultsKeys.swift in Sources */, 30A1D2A821B2D53200E2D1F7 /* PasswordChange.swift in Sources */, 30697C3E21F63C990064FCAC /* String+Utilities.swift in Sources */, + 302B2C9822C2BDE700D831EE /* AppKeychain.swift in Sources */, 30697C3B21F63C990064FCAC /* String+Localization.swift in Sources */, 302E85612125ECC70031BA64 /* Parser.swift in Sources */, 30697C4621F63CAB0064FCAC /* GitCredential.swift in Sources */, diff --git a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift index 9fb4ac1..e380534 100644 --- a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift +++ b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift @@ -90,8 +90,14 @@ class PGPKeyArmorSettingTableViewController: AutoCellHeightUITableViewController override func viewDidLoad() { super.viewDidLoad() - 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) + + if let publicKey: Data = AppKeychain.get(for: PasswordStore.PGPKeyType.PUBLIC.rawValue) { + armorPublicKeyTextView.text = String(data: publicKey, encoding: .ascii) + } + if let privateKey: Data = AppKeychain.get(for: PasswordStore.PGPKeyType.PRIVATE.rawValue) { + armorPrivateKeyTextView.text = String(data: privateKey, encoding: .ascii) + } + pgpPassphrase = passwordStore.pgpKeyPassphrase scanPublicKeyCell?.textLabel?.text = "ScanPublicKeyQrCodes".localize() diff --git a/passKit/Helpers/AppKeychain.swift b/passKit/Helpers/AppKeychain.swift new file mode 100644 index 0000000..d2b6b1c --- /dev/null +++ b/passKit/Helpers/AppKeychain.swift @@ -0,0 +1,40 @@ +// +// AppKeychain.swift +// passKit +// +// Created by Danny Moesch on 25.06.19. +// Copyright © 2019 Bob Sun. All rights reserved. +// + +import KeychainAccess + +public class AppKeychain { + + private static let keychain = Keychain(service: Globals.bundleIdentifier, accessGroup: Globals.groupIdentifier) + .accessibility(.whenUnlockedThisDeviceOnly) + .synchronizable(false) + + public static func add(data: Data, for key: String) { + keychain[data: key] = data + } + + public static func add(string: String, for key: String) { + keychain[key] = string + } + + public static func get(for key: String) -> Data? { + return try? keychain.getData(key) + } + + public static func get(for key: String) -> String? { + return try? keychain.getString(key) + } + + public static func removeContent(for key: String) { + try? keychain.remove(key) + } + + public static func removeAllContent() { + try? keychain.removeAll() + } +} diff --git a/passKit/Helpers/Utils.swift b/passKit/Helpers/Utils.swift index eb91b22..dff3c54 100644 --- a/passKit/Helpers/Utils.swift +++ b/passKit/Helpers/Utils.swift @@ -6,40 +6,8 @@ // Copyright © 2017 Bob Sun. All rights reserved. // -import Foundation -import SwiftyUserDefaults -import KeychainAccess - public class Utils { - private static let keychain = Keychain(service: Globals.bundleIdentifier, accessGroup: Globals.groupIdentifier) - .accessibility(.whenUnlockedThisDeviceOnly) - .synchronizable(false) - - public static func getPasswordFromKeychain(name: String) -> String? { - return try? keychain.getString(name) - } - - public static func addPasswordToKeychain(name: String, password: String?) { - keychain[name] = password - } - - public static func removeKeychain(name: String) { - try? keychain.remove(name) - } - - public static func removeAllKeychain() { - 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 diff --git a/passKit/Models/PasswordStore.swift b/passKit/Models/PasswordStore.swift index 7dc901e..010c072 100644 --- a/passKit/Models/PasswordStore.swift +++ b/passKit/Models/PasswordStore.swift @@ -49,28 +49,34 @@ public class PasswordStore { public var pgpKeyPassphrase: String? { set { - Utils.addPasswordToKeychain(name: "pgpKeyPassphrase", password: newValue) + if newValue != nil { + AppKeychain.add(string: newValue!, for: "pgpKeyPassphrase") + } } get { - return Utils.getPasswordFromKeychain(name: "pgpKeyPassphrase") + return AppKeychain.get(for: "pgpKeyPassphrase") } } public var gitPassword: String? { set { - Utils.addPasswordToKeychain(name: "gitPassword", password: newValue) + if newValue != nil { + AppKeychain.add(string: newValue!, for: "gitPassword") + } } get { - return Utils.getPasswordFromKeychain(name: "gitPassword") + return AppKeychain.get(for: "gitPassword") } } public var gitSSHPrivateKeyPassphrase: String? { set { - Utils.addPasswordToKeychain(name: "gitSSHPrivateKeyPassphrase", password: newValue) + if newValue != nil { + AppKeychain.add(string: newValue!, for: "gitSSHPrivateKeyPassphrase") + } } get { - return Utils.getPasswordFromKeychain(name: "gitSSHPrivateKeyPassphrase") + return AppKeychain.get(for: "gitSSHPrivateKeyPassphrase") } } @@ -186,10 +192,10 @@ public class PasswordStore { private func importExistingKeysIntoKeychain() { if let publicKey = fm.contents(atPath: Globals.pgpPublicKeyPath) { - Utils.addDataToKeychain(key: PGPKeyType.PUBLIC.rawValue, data: publicKey) + AppKeychain.add(data: publicKey, for: PGPKeyType.PUBLIC.rawValue) } if let privateKey = fm.contents(atPath: Globals.pgpPrivateKeyPath) { - Utils.addDataToKeychain(key: PGPKeyType.PRIVATE.rawValue, data: privateKey) + AppKeychain.add(data: privateKey, for: PGPKeyType.PRIVATE.rawValue) } } @@ -208,7 +214,7 @@ public class PasswordStore { } private func initPGPKey(_ keyType: PGPKeyType) throws { - if let key = GopenpgpwrapperReadKey(Utils.getDataFromKeychain(for: keyType.rawValue)) { + if let key = GopenpgpwrapperReadKey(AppKeychain.get(for: keyType.rawValue)) { switch keyType { case .PUBLIC: self.publicKey = key @@ -222,13 +228,13 @@ public class PasswordStore { public func initPGPKey(from url: URL, keyType: PGPKeyType) throws { let pgpKeyData = try Data(contentsOf: url) - Utils.addDataToKeychain(key: keyType.rawValue, data: pgpKeyData) + AppKeychain.add(data: pgpKeyData, for: keyType.rawValue) try initPGPKey(keyType) } public func initPGPKey(with armorKey: String, keyType: PGPKeyType) throws { let pgpKeyData = armorKey.data(using: .ascii)! - Utils.addDataToKeychain(key: keyType.rawValue, data: pgpKeyData) + AppKeychain.add(data: pgpKeyData, for: keyType.rawValue) try initPGPKey(keyType) } @@ -744,8 +750,8 @@ public class PasswordStore { try? fm.removeItem(atPath: Globals.pgpPrivateKeyPath) try? fm.removeItem(atPath: Globals.gitSSHPrivateKeyPath) - Utils.removeAllKeychain() - + AppKeychain.removeAllContent() + deleteCoreData(entityName: "PasswordEntity") SharedDefaults.removeAll() @@ -835,9 +841,9 @@ public class PasswordStore { SharedDefaults.remove(.pgpKeySource) SharedDefaults.remove(.pgpPrivateKeyURL) SharedDefaults.remove(.pgpPublicKeyURL) - Utils.removeKeychain(name: ".pgpKeyPassphrase") - Utils.removeKeychain(name: PGPKeyType.PUBLIC.rawValue) - Utils.removeKeychain(name: PGPKeyType.PRIVATE.rawValue) + AppKeychain.removeContent(for: ".pgpKeyPassphrase") + AppKeychain.removeContent(for: PGPKeyType.PUBLIC.rawValue) + AppKeychain.removeContent(for: PGPKeyType.PRIVATE.rawValue) publicKey = nil privateKey = nil } @@ -876,8 +882,8 @@ public class PasswordStore { 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) + AppKeychain.add(data: publicKeyFileContent, for: PGPKeyType.PUBLIC.rawValue) + AppKeychain.add(data: privateKeyFileContent, for: PGPKeyType.PRIVATE.rawValue) try fm.removeItem(at: publicKeyFileUrl) try fm.removeItem(at: privateKeyFileUrl)