diff --git a/SignalServiceKit/src/Loki/Protocol/Closed Groups/SharedSenderKeysImplementation.swift b/SignalServiceKit/src/Loki/Protocol/Closed Groups/SharedSenderKeysImplementation.swift index 427e4dc6f..21724bf07 100644 --- a/SignalServiceKit/src/Loki/Protocol/Closed Groups/SharedSenderKeysImplementation.swift +++ b/SignalServiceKit/src/Loki/Protocol/Closed Groups/SharedSenderKeysImplementation.swift @@ -40,11 +40,13 @@ public final class SharedSenderKeysImplementation : NSObject { public enum RatchetingError : LocalizedError { case loadingFailed(groupPublicKey: String, senderPublicKey: String) case messageKeyMissing(targetKeyIndex: UInt, groupPublicKey: String, senderPublicKey: String) + case generic public var errorDescription: String? { switch self { case .loadingFailed(let groupPublicKey, let senderPublicKey): return "Couldn't get ratchet for closed group with public key: \(groupPublicKey), sender public key: \(senderPublicKey)." case .messageKeyMissing(let targetKeyIndex, let groupPublicKey, let senderPublicKey): return "Couldn't find message key for old key index: \(targetKeyIndex), public key: \(groupPublicKey), sender public key: \(senderPublicKey)." + case .generic: return "An error occurred" } } } @@ -66,7 +68,8 @@ public final class SharedSenderKeysImplementation : NSObject { let nextMessageKey = try HMAC(key: Data(hex: ratchet.chainKey).bytes, variant: .sha256).authenticate([ UInt8(1) ]) let nextChainKey = try HMAC(key: Data(hex: ratchet.chainKey).bytes, variant: .sha256).authenticate([ UInt8(2) ]) let nextKeyIndex = ratchet.keyIndex + 1 - return ClosedGroupRatchet(chainKey: nextChainKey.toHexString(), keyIndex: nextKeyIndex, messageKeys: [ nextMessageKey.toHexString() ]) + let messageKeys = ratchet.messageKeys + [ nextMessageKey.toHexString() ] + return ClosedGroupRatchet(chainKey: nextChainKey.toHexString(), keyIndex: nextKeyIndex, messageKeys: messageKeys) } /// - Note: Sync. Don't call from the main thread. @@ -110,19 +113,16 @@ public final class SharedSenderKeysImplementation : NSObject { return ratchet } else { var currentKeyIndex = ratchet.keyIndex - var current = ratchet - var messageKeys: [String] = [] + var result = ratchet while currentKeyIndex < targetKeyIndex { do { - current = try step(current) - messageKeys += current.messageKeys - currentKeyIndex = current.keyIndex + result = try step(result) + currentKeyIndex = result.keyIndex } catch { print("[Loki] Couldn't step ratchet due to error: \(error).") throw error } } - let result = ClosedGroupRatchet(chainKey: current.chainKey, keyIndex: current.keyIndex, messageKeys: messageKeys) // Includes any skipped message keys let collection: Storage.ClosedGroupRatchetCollectionType = (isRetry) ? .old : .current Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderPublicKey, ratchet: result, in: collection, using: transaction) return result @@ -182,20 +182,31 @@ public final class SharedSenderKeysImplementation : NSObject { let iv = ivAndCiphertext[0.. 16 { // Pick an arbitrary number of message keys to try; this helps resolve issues caused by messages arriving out of order + lastNMessageKeys = [String](messageKeys[messageKeys.index(messageKeys.endIndex, offsetBy: -16).. Bool {