Эх сурвалжийг харах

implement access policy update scheme for already created account passwords

cyberta 3 жил өмнө
parent
commit
125975f7c6

+ 33 - 1
DcCore/DcCore/Helper/KeychainManager.swift

@@ -15,6 +15,11 @@ public class KeychainManager {
     private static let sharedKeychainGroup = "\(KcM.teamId).group.chat.delta.ios"
 
     public static func getAccountSecret(accountID: Int) throws -> String {
+        if let buildVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? Int,
+           buildVersion <= 74 {
+            upgradeAccountSecret(id: accountID)
+        }
+
         do {
             return try queryAccountSecret(id: accountID)
         } catch KeychainError.noPassword {
@@ -40,6 +45,32 @@ public class KeychainManager {
         return String((0..<36).map { _ in letters.randomElement()! })
     }
 
+    private static func upgradeAccountSecret(id: Int) {
+        let query: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
+                                    kSecAttrAccount as String: "\(id)",
+                                    kSecMatchLimit as String: kSecMatchLimitOne,
+                                    kSecAttrAccessGroup as String: KcM.sharedKeychainGroup as AnyObject,
+                                    kSecReturnAttributes as String: true,
+                                    kSecReturnData as String: true,
+                                    kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked]
+        var item: CFTypeRef?
+        let status = SecItemCopyMatching(query as CFDictionary, &item)
+        if status == errSecSuccess {
+            let attributes: [String: Any] = [kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock]
+            let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
+            switch status {
+            case errSecSuccess:
+                print("successfully upgraded access policy upgrade for account \(id).")
+            case errSecItemNotFound:
+                print("no access policy upgrade for account \(id) needed.")
+            case errSecInteractionNotAllowed:
+                print("Keychain not yet available. (\(status))")
+            default:
+                print("Failed to upgrade access policy for account id \(id) (\(status))")
+            }
+        }
+    }
+
     private static func addAccountSecret(id: Int) throws -> String {
         let keychainItemQuery = [
           kSecValueData: createRandomPassword().data(using: .utf8)!,
@@ -64,7 +95,8 @@ public class KeychainManager {
                                     kSecMatchLimit as String: kSecMatchLimitOne,
                                     kSecAttrAccessGroup as String: KcM.sharedKeychainGroup as AnyObject,
                                     kSecReturnAttributes as String: true,
-                                    kSecReturnData as String: true]
+                                    kSecReturnData as String: true,
+                                    kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock]
         var item: CFTypeRef?
         let status = SecItemCopyMatching(query as CFDictionary, &item)
         switch status {