diff options
| author | jack <jackjackbits@users.noreply.github.com> | 2025-08-12 10:15:05 +0200 |
|---|---|---|
| committer | jack <jackjackbits@users.noreply.github.com> | 2025-08-12 10:15:05 +0200 |
| commit | 63f05b5d7ead1f04ebaea8f9035aaea245cfd6ed (patch) | |
| tree | 593d38d9d333d13c71548a3a02b7f63a1addfd00 | |
| parent | a36eda3fbe56e91c39af33cbba55d2113ad0930d (diff) | |
refactor: remove all dead legacy and migration code
- Remove unused migrateSession() functions (never called in production)
- NoiseSession.migrateSession() - 13 lines
- NoiseEncryptionService.migratePeerSession() - 18 lines
- Test for migration functionality - 17 lines
- Remove unnecessary keychain cleanup code (no legacy data existed)
- cleanupLegacyKeychainItems() - 62 lines
- aggressiveCleanupLegacyItems() - 72 lines
- resetCleanupFlag() - 4 lines
- Simplified panic mode to just use deleteAllKeychainData()
Total removed: 194 lines of dead/unnecessary code
Analysis revealed:
- KeychainManager introduced July 5, 2025
- Cleanup code added July 15, 2025 (10 days later)
- Legacy service names were never used in production
- Migration functions were incomplete implementation never called
- Peer ID rotation remains active (not legacy)
| -rw-r--r-- | bitchat/Noise/NoiseSession.swift | 13 | ||||
| -rw-r--r-- | bitchat/Services/KeychainManager.swift | 145 | ||||
| -rw-r--r-- | bitchat/Services/NoiseEncryptionService.swift | 18 | ||||
| -rw-r--r-- | bitchat/ViewModels/ChatViewModel.swift | 5 | ||||
| -rw-r--r-- | bitchatTests/Noise/NoiseProtocolTests.swift | 17 |
5 files changed, 2 insertions, 196 deletions
diff --git a/bitchat/Noise/NoiseSession.swift b/bitchat/Noise/NoiseSession.swift index bc327b5..005710a 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 5eee249..e863392 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 09c9fe7..5cd6ae3 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 6298db8..0827639 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 f54275d..be82ac7 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 { |
