Put Keychain related methods to separate class

This commit is contained in:
Danny Moesch 2019-06-25 22:44:19 +02:00 committed by Mingshen Sun
parent e4e4c6daff
commit 441a7f1e9b
5 changed files with 76 additions and 52 deletions

View file

@ -11,6 +11,7 @@
301F6463216162550071A4CE /* AdditionField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6462216162550071A4CE /* AdditionField.swift */; }; 301F6463216162550071A4CE /* AdditionField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6462216162550071A4CE /* AdditionField.swift */; };
301F6468216165290071A4CE /* ConstantsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6467216165290071A4CE /* ConstantsTest.swift */; }; 301F6468216165290071A4CE /* ConstantsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6467216165290071A4CE /* ConstantsTest.swift */; };
301F646D216166AA0071A4CE /* AdditionFieldTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F646C216166AA0071A4CE /* AdditionFieldTest.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 */; }; 302E85612125ECC70031BA64 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85602125ECC70031BA64 /* Parser.swift */; };
302E85632125EE550031BA64 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85622125EE550031BA64 /* Constants.swift */; }; 302E85632125EE550031BA64 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85622125EE550031BA64 /* Constants.swift */; };
30697C2A21F63C5A0064FCAC /* NotificationNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30697C2321F63C580064FCAC /* NotificationNames.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 = "<group>"; }; 301F6467216165290071A4CE /* ConstantsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsTest.swift; sourceTree = "<group>"; };
301F646C216166AA0071A4CE /* AdditionFieldTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionFieldTest.swift; sourceTree = "<group>"; }; 301F646C216166AA0071A4CE /* AdditionFieldTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionFieldTest.swift; sourceTree = "<group>"; };
302202EE222F14E400555236 /* SearchBarScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarScope.swift; sourceTree = "<group>"; }; 302202EE222F14E400555236 /* SearchBarScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarScope.swift; sourceTree = "<group>"; };
302B2C9722C2BDE700D831EE /* AppKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppKeychain.swift; sourceTree = "<group>"; };
302E85602125ECC70031BA64 /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; }; 302E85602125ECC70031BA64 /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
302E85622125EE550031BA64 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; }; 302E85622125EE550031BA64 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
30697C2321F63C580064FCAC /* NotificationNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNames.swift; sourceTree = "<group>"; }; 30697C2321F63C580064FCAC /* NotificationNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNames.swift; sourceTree = "<group>"; };
@ -565,6 +567,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
30697C2921F63C590064FCAC /* AppError.swift */, 30697C2921F63C590064FCAC /* AppError.swift */,
302B2C9722C2BDE700D831EE /* AppKeychain.swift */,
30697C2821F63C590064FCAC /* DefaultsKeys.swift */, 30697C2821F63C590064FCAC /* DefaultsKeys.swift */,
30697C2521F63C590064FCAC /* FileManagerExtension.swift */, 30697C2521F63C590064FCAC /* FileManagerExtension.swift */,
30697C2421F63C590064FCAC /* Globals.swift */, 30697C2421F63C590064FCAC /* Globals.swift */,
@ -1054,6 +1057,7 @@
30697C2F21F63C5A0064FCAC /* DefaultsKeys.swift in Sources */, 30697C2F21F63C5A0064FCAC /* DefaultsKeys.swift in Sources */,
30A1D2A821B2D53200E2D1F7 /* PasswordChange.swift in Sources */, 30A1D2A821B2D53200E2D1F7 /* PasswordChange.swift in Sources */,
30697C3E21F63C990064FCAC /* String+Utilities.swift in Sources */, 30697C3E21F63C990064FCAC /* String+Utilities.swift in Sources */,
302B2C9822C2BDE700D831EE /* AppKeychain.swift in Sources */,
30697C3B21F63C990064FCAC /* String+Localization.swift in Sources */, 30697C3B21F63C990064FCAC /* String+Localization.swift in Sources */,
302E85612125ECC70031BA64 /* Parser.swift in Sources */, 302E85612125ECC70031BA64 /* Parser.swift in Sources */,
30697C4621F63CAB0064FCAC /* GitCredential.swift in Sources */, 30697C4621F63CAB0064FCAC /* GitCredential.swift in Sources */,

View file

@ -90,8 +90,14 @@ class PGPKeyArmorSettingTableViewController: AutoCellHeightUITableViewController
override func viewDidLoad() { override func viewDidLoad() {
super.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 pgpPassphrase = passwordStore.pgpKeyPassphrase
scanPublicKeyCell?.textLabel?.text = "ScanPublicKeyQrCodes".localize() scanPublicKeyCell?.textLabel?.text = "ScanPublicKeyQrCodes".localize()

View file

@ -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()
}
}

View file

@ -6,40 +6,8 @@
// Copyright © 2017 Bob Sun. All rights reserved. // Copyright © 2017 Bob Sun. All rights reserved.
// //
import Foundation
import SwiftyUserDefaults
import KeychainAccess
public class Utils { 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?) { public static func copyToPasteboard(textToCopy: String?) {
guard textToCopy != nil else { guard textToCopy != nil else {
return return

View file

@ -49,28 +49,34 @@ public class PasswordStore {
public var pgpKeyPassphrase: String? { public var pgpKeyPassphrase: String? {
set { set {
Utils.addPasswordToKeychain(name: "pgpKeyPassphrase", password: newValue) if newValue != nil {
AppKeychain.add(string: newValue!, for: "pgpKeyPassphrase")
}
} }
get { get {
return Utils.getPasswordFromKeychain(name: "pgpKeyPassphrase") return AppKeychain.get(for: "pgpKeyPassphrase")
} }
} }
public var gitPassword: String? { public var gitPassword: String? {
set { set {
Utils.addPasswordToKeychain(name: "gitPassword", password: newValue) if newValue != nil {
AppKeychain.add(string: newValue!, for: "gitPassword")
}
} }
get { get {
return Utils.getPasswordFromKeychain(name: "gitPassword") return AppKeychain.get(for: "gitPassword")
} }
} }
public var gitSSHPrivateKeyPassphrase: String? { public var gitSSHPrivateKeyPassphrase: String? {
set { set {
Utils.addPasswordToKeychain(name: "gitSSHPrivateKeyPassphrase", password: newValue) if newValue != nil {
AppKeychain.add(string: newValue!, for: "gitSSHPrivateKeyPassphrase")
}
} }
get { get {
return Utils.getPasswordFromKeychain(name: "gitSSHPrivateKeyPassphrase") return AppKeychain.get(for: "gitSSHPrivateKeyPassphrase")
} }
} }
@ -186,10 +192,10 @@ public class PasswordStore {
private func importExistingKeysIntoKeychain() { private func importExistingKeysIntoKeychain() {
if let publicKey = fm.contents(atPath: Globals.pgpPublicKeyPath) { 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) { 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 { 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 { switch keyType {
case .PUBLIC: case .PUBLIC:
self.publicKey = key self.publicKey = key
@ -222,13 +228,13 @@ public class PasswordStore {
public func initPGPKey(from url: URL, keyType: PGPKeyType) throws { public func initPGPKey(from url: URL, keyType: PGPKeyType) throws {
let pgpKeyData = try Data(contentsOf: url) let pgpKeyData = try Data(contentsOf: url)
Utils.addDataToKeychain(key: keyType.rawValue, data: pgpKeyData) AppKeychain.add(data: pgpKeyData, for: keyType.rawValue)
try initPGPKey(keyType) try initPGPKey(keyType)
} }
public func initPGPKey(with armorKey: String, keyType: PGPKeyType) throws { public func initPGPKey(with armorKey: String, keyType: PGPKeyType) throws {
let pgpKeyData = armorKey.data(using: .ascii)! let pgpKeyData = armorKey.data(using: .ascii)!
Utils.addDataToKeychain(key: keyType.rawValue, data: pgpKeyData) AppKeychain.add(data: pgpKeyData, for: keyType.rawValue)
try initPGPKey(keyType) try initPGPKey(keyType)
} }
@ -744,7 +750,7 @@ public class PasswordStore {
try? fm.removeItem(atPath: Globals.pgpPrivateKeyPath) try? fm.removeItem(atPath: Globals.pgpPrivateKeyPath)
try? fm.removeItem(atPath: Globals.gitSSHPrivateKeyPath) try? fm.removeItem(atPath: Globals.gitSSHPrivateKeyPath)
Utils.removeAllKeychain() AppKeychain.removeAllContent()
deleteCoreData(entityName: "PasswordEntity") deleteCoreData(entityName: "PasswordEntity")
@ -835,9 +841,9 @@ public class PasswordStore {
SharedDefaults.remove(.pgpKeySource) SharedDefaults.remove(.pgpKeySource)
SharedDefaults.remove(.pgpPrivateKeyURL) SharedDefaults.remove(.pgpPrivateKeyURL)
SharedDefaults.remove(.pgpPublicKeyURL) SharedDefaults.remove(.pgpPublicKeyURL)
Utils.removeKeychain(name: ".pgpKeyPassphrase") AppKeychain.removeContent(for: ".pgpKeyPassphrase")
Utils.removeKeychain(name: PGPKeyType.PUBLIC.rawValue) AppKeychain.removeContent(for: PGPKeyType.PUBLIC.rawValue)
Utils.removeKeychain(name: PGPKeyType.PRIVATE.rawValue) AppKeychain.removeContent(for: PGPKeyType.PRIVATE.rawValue)
publicKey = nil publicKey = nil
privateKey = nil privateKey = nil
} }
@ -876,8 +882,8 @@ public class PasswordStore {
let publicKeyFileContent = try Data(contentsOf: publicKeyFileUrl) let publicKeyFileContent = try Data(contentsOf: publicKeyFileUrl)
let privateKeyFileContent = try Data(contentsOf: privateKeyFileUrl) let privateKeyFileContent = try Data(contentsOf: privateKeyFileUrl)
Utils.addDataToKeychain(key: PGPKeyType.PUBLIC.rawValue, data: publicKeyFileContent) AppKeychain.add(data: publicKeyFileContent, for: PGPKeyType.PUBLIC.rawValue)
Utils.addDataToKeychain(key: PGPKeyType.PRIVATE.rawValue, data: privateKeyFileContent) AppKeychain.add(data: privateKeyFileContent, for: PGPKeyType.PRIVATE.rawValue)
try fm.removeItem(at: publicKeyFileUrl) try fm.removeItem(at: publicKeyFileUrl)
try fm.removeItem(at: privateKeyFileUrl) try fm.removeItem(at: privateKeyFileUrl)