From acf0345aafdea7d2f568c7417f6e5cad177cc410 Mon Sep 17 00:00:00 2001 From: dankito Date: Wed, 14 Oct 2020 02:12:36 +0200 Subject: [PATCH] Implemented deleting all keychain items after re-installing app --- .../BankingiOSApp.xcodeproj/project.pbxproj | 18 +++++++ .../Security/AuthenticationService.swift | 53 ++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj index c6d5dfa2..3f4cc39a 100644 --- a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj +++ b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj @@ -50,6 +50,8 @@ 3684EB90250B7F560001139E /* BankingUiCommon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3684EB8E250B7F3C0001139E /* BankingUiCommon.framework */; }; 3684EB92250FD4AF0001139E /* LabelledValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3684EB91250FD4AF0001139E /* LabelledValue.swift */; }; 3684EB94250FD75B0001139E /* CustomUITextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3684EB93250FD75B0001139E /* CustomUITextField.swift */; }; + 36B70FA52536611000734588 /* CryptoSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 36B70FA42536611000734588 /* CryptoSwift */; }; + 36B70FAA2536695800734588 /* Stopwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B70FA92536695800734588 /* Stopwatch.swift */; }; 36B8A4482503D12100C15359 /* ProtectAppSettingsDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A4472503D12100C15359 /* ProtectAppSettingsDialog.swift */; }; 36B8A44B2503D1E800C15359 /* BiometricAuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A44A2503D1E800C15359 /* BiometricAuthenticationService.swift */; }; 36B8A44D2503D96D00C15359 /* AuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B8A44C2503D96D00C15359 /* AuthenticationService.swift */; }; @@ -307,6 +309,7 @@ 361A0CD0252AA1AB007E25DD /* Security.framework in Frameworks */, 3684EB90250B7F560001139E /* BankingUiCommon.framework in Frameworks */, 36BCF86924BA550D005BEC29 /* BankFinder.framework in Frameworks */, + 36B70FA52536611000734588 /* CryptoSwift in Frameworks */, 36BCF85E24BA4DA8005BEC29 /* MultiplatformUtils.framework in Frameworks */, 36FC92D024B39C47002B12E9 /* fints4k.framework in Frameworks */, 36BCF87024BB0F8A005BEC29 /* fints4kBankingClient.framework in Frameworks */, @@ -652,6 +655,7 @@ name = BankingiOSApp; packageProductDependencies = ( 36BE06BF24D07CCD00CBBB68 /* SwiftSoup */, + 36B70FA42536611000734588 /* CryptoSwift */, ); productName = BankingiOSApp; productReference = 36FC929824B39A05002B12E9 /* Bankmeister.app */; @@ -732,6 +736,7 @@ mainGroup = 36FC928F24B39A05002B12E9; packageReferences = ( 36BE06BE24D07CCC00CBBB68 /* XCRemoteSwiftPackageReference "SwiftSoup" */, + 36B70FA32536611000734588 /* XCRemoteSwiftPackageReference "CryptoSwift" */, ); productRefGroup = 36FC929924B39A05002B12E9 /* Products */; projectDirPath = ""; @@ -1367,6 +1372,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 36B70FA32536611000734588 /* XCRemoteSwiftPackageReference "CryptoSwift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/krzyzanowskim/CryptoSwift.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.3.2; + }; + }; 36BE06BE24D07CCC00CBBB68 /* XCRemoteSwiftPackageReference "SwiftSoup" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/scinfu/SwiftSoup.git"; @@ -1378,6 +1391,11 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 36B70FA42536611000734588 /* CryptoSwift */ = { + isa = XCSwiftPackageProductDependency; + package = 36B70FA32536611000734588 /* XCRemoteSwiftPackageReference "CryptoSwift" */; + productName = CryptoSwift; + }; 36BE06BF24D07CCD00CBBB68 /* SwiftSoup */ = { isa = XCSwiftPackageProductDependency; package = 36BE06BE24D07CCC00CBBB68 /* XCRemoteSwiftPackageReference "SwiftSoup" */; diff --git a/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift b/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift index 7b34aa00..3c237e93 100644 --- a/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift +++ b/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift @@ -19,6 +19,11 @@ class AuthenticationService { init(_ persistence: IBankingPersistence) { self.persistence = persistence + if UserDefaults.standard.bool(forKey: "hasAppBeenStartedBefore", defaultValue: false) == false { // when uninstalling app key chain items aren't deleted -> delete them after reinstall + deleteAllKeyChainItems() + UserDefaults.standard.setValue(true, forKey: "hasAppBeenStartedBefore") + } + if let type = readAuthenticationType() { self.authenticationType = type @@ -26,7 +31,7 @@ class AuthenticationService { openDatabase(false, nil) } } - else { // first app run, no authentication type persisted yet -> set to .unprotected + else { // first app run, no authentication type persisted yet -> set default password removeAppProtection() openDatabase(false, nil) } @@ -162,6 +167,16 @@ class AuthenticationService { self.authenticationType = type } + private func deleteAuthenticationTypeKeychainItem() { + do { + let item = createAuthenticationTypeKeychainItem() + + try item.deleteItem() + } catch { + NSLog("Could not delete authentication type keychain item: \(error)") + } + } + private func createAuthenticationTypeKeychainItem() -> KeychainPasswordItem { return KeychainPasswordItem(Self.AuthenticationTypeKeychainAccountName) } @@ -229,6 +244,32 @@ class AuthenticationService { return nil } + @discardableResult + private func deleteDefaultPassword(_ useBiometricAuthentication: Bool) -> Bool { + do { + let passwordItem = createDefaultPasswordKeychainItem(useBiometricAuthentication) + + return deleteDefaultPassword(passwordItem) + } catch { + NSLog("Could not delete default password: \(error)") + } + + return false + } + + @discardableResult + private func deleteDefaultPassword(_ passwordItem: KeychainPasswordItem) -> Bool { + do { + try? passwordItem.deleteItem() + + return true + } catch { + NSLog("Could not delete default password: \(error)") + } + + return false + } + private func createDefaultPasswordKeychainItem(_ useBiometricAuthentication: Bool) -> KeychainPasswordItem { var accessControl: SecAccessControl? = nil var context: LAContext? = nil @@ -294,6 +335,16 @@ class AuthenticationService { } + private func deleteAllKeyChainItems() { + deleteAuthenticationTypeKeychainItem() + + deleteDefaultPassword(false) // TODO: which boolean value to set here? does it make any difference if it comes to deleting the key chain item?a + deleteDefaultPassword(true) + + deleteLoginPassword() + } + + private func generateRandomPassword(_ passwordLength: Int) -> String { let dictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789§±!@#$%^&*-_=+;:|/?.>,<"