Fix Noise session persistence during peer ID rotation

- Add session migration when peer IDs rotate
- Sessions now follow peers across ID changes via fingerprint
- Add migratePeerSession to NoiseEncryptionService
- Add migrateSession to NoiseSessionManager
- Integrate migration in BluetoothMeshService updatePeerBinding

This fixes the issue where established Noise sessions were lost
when peer IDs rotated, causing "No Noise session" errors and
requiring re-handshake.
This commit is contained in:
jack
2025-07-22 11:01:24 +02:00
parent 83a808fce6
commit 0be35a5378
3 changed files with 34 additions and 0 deletions
+13
View File
@@ -259,6 +259,19 @@ 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)
SecurityLogger.log("Migrated Noise session from \(oldPeerID) to \(newPeerID)", category: SecurityLogger.noise, level: .info)
}
}
}
func getEstablishedSessions() -> [String: NoiseSession] {
return managerQueue.sync {
return sessions.filter { $0.value.isEstablished() }
@@ -364,6 +364,9 @@ class BluetoothMeshService: NSObject {
// Notify about the change if it's a rotation
if let oldID = oldPeerID {
// Migrate Noise session to new peer ID
self.noiseService.migratePeerSession(from: oldID, to: newPeerID, fingerprint: fingerprint)
self.notifyPeerIDChange(oldPeerID: oldID, newPeerID: newPeerID, fingerprint: fingerprint)
}
}
@@ -279,6 +279,24 @@ class NoiseEncryptionService {
}
}
/// 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) {