diff --git a/bitchat/Noise/NoiseSession.swift b/bitchat/Noise/NoiseSession.swift index bc327b50..005710a1 100644 --- a/bitchat/Noise/NoiseSession.swift +++ b/bitchat/Noise/NoiseSession.swift @@ -296,19 +296,6 @@ class NoiseSessionManager { } } - func migrateSession(from oldPeerID: String, to newPeerID: String) { - managerQueue.sync(flags: .barrier) { - // Check if we have a session for the old peer ID - if let session = sessions[oldPeerID] { - // Move the session to the new peer ID - sessions[newPeerID] = session - _ = sessions.removeValue(forKey: oldPeerID) - - SecureLogger.log("Migrated Noise session from \(oldPeerID) to \(newPeerID)", category: SecureLogger.noise, level: .info) - } - } - } - func getEstablishedSessions() -> [String: NoiseSession] { return managerQueue.sync { return sessions.filter { $0.value.isEstablished() } diff --git a/bitchat/Services/KeychainManager.swift b/bitchat/Services/KeychainManager.swift index 5eee249c..e8633928 100644 --- a/bitchat/Services/KeychainManager.swift +++ b/bitchat/Services/KeychainManager.swift @@ -17,73 +17,7 @@ class KeychainManager { private let service = "chat.bitchat" private let appGroup = "group.chat.bitchat" - private init() { - // Clean up legacy keychain items on first run - cleanupLegacyKeychainItems() - } - - private func cleanupLegacyKeychainItems() { - // Check if we've already done cleanup - let cleanupKey = "bitchat.keychain.cleanup.v2" - if UserDefaults.standard.bool(forKey: cleanupKey) { - return - } - - - // List of old service names to migrate from - let legacyServices = [ - "com.bitchat.passwords", - "com.bitchat.deviceidentity", - "com.bitchat.noise.identity", - "chat.bitchat.passwords", - "bitchat.keychain" - ] - - var migratedItems = 0 - - // Try to migrate identity keys - for oldService in legacyServices { - // Check for noise identity key - let query: [String: Any] = [ - kSecClass as String: kSecClassGenericPassword, - kSecAttrService as String: oldService, - kSecAttrAccount as String: "identity_noiseStaticKey", - kSecReturnData as String: true - ] - - var result: AnyObject? - let status = SecItemCopyMatching(query as CFDictionary, &result) - - if status == errSecSuccess, let data = result as? Data { - // Save to new service - if saveIdentityKey(data, forKey: "noiseStaticKey") { - migratedItems += 1 - SecureLogger.logKeyOperation("migrate", keyType: "noiseStaticKey", success: true) - } - // Delete from old service - let deleteQuery: [String: Any] = [ - kSecClass as String: kSecClassGenericPassword, - kSecAttrService as String: oldService, - kSecAttrAccount as String: "identity_noiseStaticKey" - ] - SecItemDelete(deleteQuery as CFDictionary) - } - } - - // Clean up all other legacy items - for oldService in legacyServices { - let deleteQuery: [String: Any] = [ - kSecClass as String: kSecClassGenericPassword, - kSecAttrService as String: oldService - ] - - SecItemDelete(deleteQuery as CFDictionary) - } - - - // Mark cleanup as done - UserDefaults.standard.set(true, forKey: cleanupKey) - } + private init() {} private func isSandboxed() -> Bool { @@ -240,11 +174,6 @@ class KeychainManager { return status == errSecSuccess || status == errSecItemNotFound } - // Force cleanup to run again (for development/testing) - func resetCleanupFlag() { - UserDefaults.standard.removeObject(forKey: "bitchat.keychain.cleanup.v2") - } - // Delete ALL keychain data for panic mode func deleteAllKeychainData() -> Bool { @@ -384,76 +313,4 @@ class KeychainManager { let key = "identity_noiseStaticKey" return retrieveData(forKey: key) != nil } - - // Aggressive cleanup for legacy items - can be called manually - func aggressiveCleanupLegacyItems() -> Int { - var deletedCount = 0 - - // List of KNOWN bitchat service names from our development history - let knownBitchatServices = [ - "com.bitchat.passwords", - "com.bitchat.deviceidentity", - "com.bitchat.noise.identity", - "chat.bitchat.passwords", - "bitchat.keychain", - "Bitchat", - "BitChat" - ] - - // First, delete all items from known legacy services - for legacyService in knownBitchatServices { - let deleteQuery: [String: Any] = [ - kSecClass as String: kSecClassGenericPassword, - kSecAttrService as String: legacyService - ] - - let status = SecItemDelete(deleteQuery as CFDictionary) - if status == errSecSuccess { - deletedCount += 1 - } - } - - // Now search for items that have our specific account patterns with bitchat service names - let searchQuery: [String: Any] = [ - kSecClass as String: kSecClassGenericPassword, - kSecMatchLimit as String: kSecMatchLimitAll, - kSecReturnAttributes as String: true - ] - - var result: AnyObject? - let status = SecItemCopyMatching(searchQuery as CFDictionary, &result) - - if status == errSecSuccess, let items = result as? [[String: Any]] { - for item in items { - let account = item[kSecAttrAccount as String] as? String ?? "" - let service = item[kSecAttrService as String] as? String ?? "" - - // ONLY delete if service name contains "bitchat" somewhere - // This ensures we never touch other apps' keychain items - var shouldDelete = false - - // Check if service contains "bitchat" (case insensitive) but NOT our current service - let serviceLower = service.lowercased() - if service != self.service && serviceLower.contains("bitchat") { - shouldDelete = true - } - - if shouldDelete { - // Build precise delete query - let deleteQuery: [String: Any] = [ - kSecClass as String: kSecClassGenericPassword, - kSecAttrService as String: service, - kSecAttrAccount as String: account - ] - - let deleteStatus = SecItemDelete(deleteQuery as CFDictionary) - if deleteStatus == errSecSuccess { - deletedCount += 1 - } - } - } - } - - return deletedCount - } } \ No newline at end of file diff --git a/bitchat/Services/NoiseEncryptionService.swift b/bitchat/Services/NoiseEncryptionService.swift index 09c9fe70..5cd6ae3b 100644 --- a/bitchat/Services/NoiseEncryptionService.swift +++ b/bitchat/Services/NoiseEncryptionService.swift @@ -419,24 +419,6 @@ class NoiseEncryptionService { SecureLogger.logSecurityEvent(.sessionExpired(peerID: peerID)) } - /// Migrate session when peer ID changes - func migratePeerSession(from oldPeerID: String, to newPeerID: String, fingerprint: String) { - // First update the fingerprint mappings - serviceQueue.sync(flags: .barrier) { - // Remove old mapping - if let oldFingerprint = peerFingerprints[oldPeerID], oldFingerprint == fingerprint { - peerFingerprints.removeValue(forKey: oldPeerID) - } - - // Add new mapping - peerFingerprints[newPeerID] = fingerprint - fingerprintToPeerID[fingerprint] = newPeerID - } - - // Migrate the session in session manager - sessionManager.migrateSession(from: oldPeerID, to: newPeerID) - } - // MARK: - Private Helpers private func handleSessionEstablished(peerID: String, remoteStaticKey: Curve25519.KeyAgreement.PublicKey) { diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 6298db83..08276393 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -1474,10 +1474,7 @@ class ChatViewModel: ObservableObject, BitchatDelegate { privateChats.removeAll() unreadPrivateMessages.removeAll() - // First run aggressive cleanup to get rid of all legacy items - _ = KeychainManager.shared.aggressiveCleanupLegacyItems() - - // Then delete all current keychain data + // Delete all keychain data _ = KeychainManager.shared.deleteAllKeychainData() // Clear UserDefaults identity fallbacks diff --git a/bitchatTests/Noise/NoiseProtocolTests.swift b/bitchatTests/Noise/NoiseProtocolTests.swift index f54275de..be82ac7d 100644 --- a/bitchatTests/Noise/NoiseProtocolTests.swift +++ b/bitchatTests/Noise/NoiseProtocolTests.swift @@ -226,23 +226,6 @@ final class NoiseProtocolTests: XCTestCase { XCTAssertEqual(decrypted, plaintext) } - func testSessionMigration() throws { - let manager = NoiseSessionManager(localStaticKey: aliceKey) - - // Create and establish a session - _ = try manager.initiateHandshake(with: TestConstants.testPeerID2) - - // Migrate to new peer ID - let newPeerID = TestConstants.testPeerID3 - manager.migrateSession(from: TestConstants.testPeerID2, to: newPeerID) - - // Old peer ID should not have session - XCTAssertNil(manager.getSession(for: TestConstants.testPeerID2)) - - // New peer ID should have the session - XCTAssertNotNil(manager.getSession(for: newPeerID)) - } - // MARK: - Security Tests func testTamperedCiphertextDetection() throws {