From 9be05f98e988fb0df90c0e6f4e3df0ec67ead1ce Mon Sep 17 00:00:00 2001 From: islam <2553451+qalandarov@users.noreply.github.com> Date: Thu, 18 Sep 2025 01:49:37 +0100 Subject: [PATCH] Update `NoiseRateLimiter` to use `Peer` --- .../Noise/NoiseSecurityConsiderations.swift | 26 +++++++++---------- bitchat/Services/NoiseEncryptionService.swift | 8 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/bitchat/Noise/NoiseSecurityConsiderations.swift b/bitchat/Noise/NoiseSecurityConsiderations.swift index fd747c17..c451b599 100644 --- a/bitchat/Noise/NoiseSecurityConsiderations.swift +++ b/bitchat/Noise/NoiseSecurityConsiderations.swift @@ -132,8 +132,8 @@ final class SecureNoiseSession: NoiseSession { // MARK: - Rate Limiter final class NoiseRateLimiter { - private var handshakeTimestamps: [String: [Date]] = [:] // peerID -> timestamps - private var messageTimestamps: [String: [Date]] = [:] // peerID -> timestamps + private var handshakeTimestamps: [Peer: [Date]] = [:] // Peer -> timestamps + private var messageTimestamps: [Peer: [Date]] = [:] // Peer -> timestamps // Global rate limiting private var globalHandshakeTimestamps: [Date] = [] @@ -141,7 +141,7 @@ final class NoiseRateLimiter { private let queue = DispatchQueue(label: "chat.bitchat.noise.ratelimit", attributes: .concurrent) - func allowHandshake(from peerID: String) -> Bool { + func allowHandshake(from peer: Peer) -> Bool { return queue.sync(flags: .barrier) { let now = Date() let oneMinuteAgo = now.addingTimeInterval(-60) @@ -154,23 +154,23 @@ final class NoiseRateLimiter { } // Check per-peer rate limit - var timestamps = handshakeTimestamps[peerID] ?? [] + var timestamps = handshakeTimestamps[peer] ?? [] timestamps = timestamps.filter { $0 > oneMinuteAgo } if timestamps.count >= NoiseSecurityConstants.maxHandshakesPerMinute { - SecureLogger.warning("Per-peer handshake rate limit exceeded for \(peerID): \(timestamps.count)/\(NoiseSecurityConstants.maxHandshakesPerMinute) per minute", category: .security) + SecureLogger.warning("Per-peer handshake rate limit exceeded for \(peer.id): \(timestamps.count)/\(NoiseSecurityConstants.maxHandshakesPerMinute) per minute", category: .security) return false } // Record new handshake timestamps.append(now) - handshakeTimestamps[peerID] = timestamps + handshakeTimestamps[peer] = timestamps globalHandshakeTimestamps.append(now) return true } } - func allowMessage(from peerID: String) -> Bool { + func allowMessage(from peer: Peer) -> Bool { return queue.sync(flags: .barrier) { let now = Date() let oneSecondAgo = now.addingTimeInterval(-1) @@ -183,26 +183,26 @@ final class NoiseRateLimiter { } // Check per-peer rate limit - var timestamps = messageTimestamps[peerID] ?? [] + var timestamps = messageTimestamps[peer] ?? [] timestamps = timestamps.filter { $0 > oneSecondAgo } if timestamps.count >= NoiseSecurityConstants.maxMessagesPerSecond { - SecureLogger.warning("Per-peer message rate limit exceeded for \(peerID): \(timestamps.count)/\(NoiseSecurityConstants.maxMessagesPerSecond) per second", category: .security) + SecureLogger.warning("Per-peer message rate limit exceeded for \(peer.id): \(timestamps.count)/\(NoiseSecurityConstants.maxMessagesPerSecond) per second", category: .security) return false } // Record new message timestamps.append(now) - messageTimestamps[peerID] = timestamps + messageTimestamps[peer] = timestamps globalMessageTimestamps.append(now) return true } } - func reset(for peerID: String) { + func reset(for peer: Peer) { queue.async(flags: .barrier) { - self.handshakeTimestamps.removeValue(forKey: peerID) - self.messageTimestamps.removeValue(forKey: peerID) + self.handshakeTimestamps.removeValue(forKey: peer) + self.messageTimestamps.removeValue(forKey: peer) } } diff --git a/bitchat/Services/NoiseEncryptionService.swift b/bitchat/Services/NoiseEncryptionService.swift index 69b24fd1..600b5116 100644 --- a/bitchat/Services/NoiseEncryptionService.swift +++ b/bitchat/Services/NoiseEncryptionService.swift @@ -400,7 +400,7 @@ final class NoiseEncryptionService { } // Check rate limit - guard rateLimiter.allowHandshake(from: peerID) else { + guard rateLimiter.allowHandshake(from: Peer(str: peerID)) else { SecureLogger.warning(.authenticationFailed(peerID: "Rate limited: \(peerID)")) throw NoiseSecurityError.rateLimitExceeded } @@ -429,7 +429,7 @@ final class NoiseEncryptionService { } // Check rate limit - guard rateLimiter.allowHandshake(from: peerID) else { + guard rateLimiter.allowHandshake(from: Peer(str: peerID)) else { SecureLogger.warning(.authenticationFailed(peerID: "Rate limited: \(peerID)")) throw NoiseSecurityError.rateLimitExceeded } @@ -463,7 +463,7 @@ final class NoiseEncryptionService { } // Check rate limit - guard rateLimiter.allowMessage(from: peerID) else { + guard rateLimiter.allowMessage(from: Peer(str: peerID)) else { throw NoiseSecurityError.rateLimitExceeded } @@ -485,7 +485,7 @@ final class NoiseEncryptionService { } // Check rate limit - guard rateLimiter.allowMessage(from: peerID) else { + guard rateLimiter.allowMessage(from: Peer(str: peerID)) else { throw NoiseSecurityError.rateLimitExceeded }