diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index fcb9b3d61..0e6d2903f 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -7679,7 +7679,7 @@ CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 468; + CURRENT_PROJECT_VERSION = 471; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -7757,7 +7757,7 @@ CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution"; - CURRENT_PROJECT_VERSION = 468; + CURRENT_PROJECT_VERSION = 471; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; diff --git a/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift b/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift index d193d9a5d..2a52fb797 100644 --- a/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift +++ b/SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift @@ -439,6 +439,11 @@ public enum PushNotificationAPI { @discardableResult private static func getOrGenerateEncryptionKey(using dependencies: Dependencies) throws -> Data { do { + try Singleton.keychain.migrateLegacyKeyIfNeeded( + legacyKey: "PNEncryptionKeyKey", + legacyService: "PNKeyChainService", + toKey: .pushNotificationEncryptionKey + ) var encryptionKey: Data = try Singleton.keychain.data(forKey: .pushNotificationEncryptionKey) defer { encryptionKey.resetBytes(in: 0.. Data { + try Singleton.keychain.migrateLegacyKeyIfNeeded( + legacyKey: "GRDBDatabaseCipherKeySpec", + legacyService: "TSKeyChainService", + toKey: .dbCipherKeySpec + ) return try Singleton.keychain.data(forKey: .dbCipherKeySpec) } diff --git a/SessionUtilitiesKit/Utilities/KeychainStorageType.swift b/SessionUtilitiesKit/Utilities/KeychainStorageType.swift index c14befd9c..24c8301e5 100644 --- a/SessionUtilitiesKit/Utilities/KeychainStorageType.swift +++ b/SessionUtilitiesKit/Utilities/KeychainStorageType.swift @@ -35,6 +35,8 @@ public protocol KeychainStorageType { func remove(key: KeychainStorage.DataKey) throws func removeAll() throws + + func migrateLegacyKeyIfNeeded(legacyKey: String, legacyService: String?, toKey key: KeychainStorage.DataKey) throws } // MARK: - KeychainStorage @@ -112,6 +114,47 @@ public class KeychainStorage: KeychainStorageType { ) } } + + public func migrateLegacyKeyIfNeeded(legacyKey: String, legacyService: String?, toKey key: KeychainStorage.DataKey) throws { + // If we already have a value for the given key then do nothing (assume the existing + // value is correct) + guard (try? data(forKey: key)) == nil else { return } + + var query: [String: Any] = [ + KeychainSwiftConstants.klass : kSecClassGenericPassword, + KeychainSwiftConstants.attrAccount : legacyKey, + KeychainSwiftConstants.matchLimit : kSecMatchLimitOne + ] + query[KeychainSwiftConstants.returnData] = kCFBooleanTrue + + if let legacyService: String = legacyService { + query[(kSecAttrService as String)] = legacyService + } + + if let accessGroup: String = keychain.accessGroup { + query[KeychainSwiftConstants.accessGroup] = accessGroup + } + + if keychain.synchronizable { + query[KeychainSwiftConstants.attrSynchronizable] = kSecAttrSynchronizableAny + } + + var result: AnyObject? + let lastResultCode = withUnsafeMutablePointer(to: &result) { + SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) + } + + guard + lastResultCode == noErr, + let resultData: Data = result as? Data + else { return } + + // Store the data in the new location + try set(data: resultData, forKey: key) + + // Remove the data from the old location + SecItemDelete(query as CFDictionary) + } } // MARK: - Keys