From d5e1237b0ccc0eeb012ebce14dff1864a229074e Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 8 Jan 2021 14:54:27 +1100 Subject: [PATCH] Allow admins to leave & fix remaining issues --- .../OWSConversationSettingsViewController.m | 2 +- .../View Controllers/EditClosedGroupVC.swift | 30 +-- Session/View Controllers/HomeVC.swift | 11 +- .../View Controllers/NewClosedGroupVC.swift | 5 - .../Database/Storage+ClosedGroups.swift | 1 - .../ClosedGroupUpdateV2.swift | 4 +- .../Meta/SessionMessagingKit.h | 1 + .../MessageReceiver+Handling.swift | 176 +------------ .../Sending & Receiving/MessageReceiver.swift | 38 ++- .../MessageSender+ClosedGroups.swift | 249 ++---------------- .../Sending & Receiving/MessageSender.swift | 5 - .../Utilities}/NSData+messagePadding.h | 0 .../Utilities}/NSData+messagePadding.m | 0 SessionProtocolKit/Meta/SessionProtocolKit.h | 2 - Signal.xcodeproj/project.pbxproj | 24 +- SignalUtilitiesKit/Configuration.swift | 2 - 16 files changed, 78 insertions(+), 472 deletions(-) rename {SessionProtocolKit => SessionMessagingKit/Utilities}/NSData+messagePadding.h (100%) rename {SessionProtocolKit => SessionMessagingKit/Utilities}/NSData+messagePadding.m (100%) diff --git a/Session/Signal/OWSConversationSettingsViewController.m b/Session/Signal/OWSConversationSettingsViewController.m index 9cc33cbf6..981688d6d 100644 --- a/Session/Signal/OWSConversationSettingsViewController.m +++ b/Session/Signal/OWSConversationSettingsViewController.m @@ -931,7 +931,7 @@ static CGRect oldframe; if (gThread.usesSharedSenderKeys) { NSString *groupPublicKey = [LKGroupUtilities getDecodedGroupID:gThread.groupModel.groupId]; [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [[SNMessageSender leaveGroupWithPublicKey:groupPublicKey transaction:transaction] retainUntilComplete]; + [SNMessageSender leaveClosedGroupWithPublicKey:groupPublicKey using:transaction error:nil]; }]; } diff --git a/Session/View Controllers/EditClosedGroupVC.swift b/Session/View Controllers/EditClosedGroupVC.swift index 3917f40e2..9c8a86306 100644 --- a/Session/View Controllers/EditClosedGroupVC.swift +++ b/Session/View Controllers/EditClosedGroupVC.swift @@ -252,28 +252,22 @@ final class EditClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelega guard members != Set(thread.groupModel.groupMemberIds) || name != thread.groupModel.groupName else { return popToConversationVC(self) } - - /* - ModalActivityIndicatorViewController.present(fromViewController: navigationController!, canCancel: false) { [weak self] _ in - Storage.writeSync { [weak self] transaction in - MessageSender.update(groupPublicKey, with: members, name: name, transaction: transaction).done(on: DispatchQueue.main) { - guard let self = self else { return } - self.dismiss(animated: true, completion: nil) // Dismiss the loader - popToConversationVC(self) - }.catch(on: DispatchQueue.main) { error in - guard let self = self else { return } - self.dismiss(animated: true, completion: nil) // Dismiss the loader - self.showError(title: "Couldn't Update Group", message: "Please check your internet connection and try again.") - } + if !members.contains(getUserHexEncodedPublicKey()) { + guard members.intersection(Set(thread.groupModel.groupMemberIds).subtracting([ getUserHexEncodedPublicKey() ])) == members else { + return showError(title: "Couldn't Update Group", message: "Can't leave while adding or removing other members.") } } - */ - Storage.write(with: { [weak self] transaction in do { - try MessageSender.updateV2(groupPublicKey, with: members, name: name, transaction: transaction) + if !members.contains(getUserHexEncodedPublicKey()) { + try MessageSender.leaveV2(groupPublicKey, using: transaction) + } else { + try MessageSender.updateV2(groupPublicKey, with: members, name: name, transaction: transaction) + } } catch { - self?.showError(title: "Couldn't Update Group", message: "Please check your internet connection and try again.") + DispatchQueue.main.async { + self?.showError(title: "Couldn't Update Group", message: "Please check your internet connection and try again.") + } } }, completion: { [weak self] in guard let self = self else { return } @@ -289,7 +283,7 @@ final class EditClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelega } private func canBeRemoved(_ publicKey: String) -> Bool { - return !isAdmin(publicKey) && !isCurrentUser(publicKey) + return !isAdmin(publicKey) || isCurrentUser(publicKey) } private func isAdmin(_ publicKey: String) -> Bool { diff --git a/Session/View Controllers/HomeVC.swift b/Session/View Controllers/HomeVC.swift index d05060d1e..5b39a0047 100644 --- a/Session/View Controllers/HomeVC.swift +++ b/Session/View Controllers/HomeVC.swift @@ -402,7 +402,11 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol guard let thread = self.thread(at: indexPath.row) else { return [] } let openGroup = Storage.shared.getOpenGroup(for: thread.uniqueId!) let delete = UITableViewRowAction(style: .destructive, title: NSLocalizedString("TXT_DELETE_TITLE", comment: "")) { [weak self] _, _ in - let alert = UIAlertController(title: NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE", comment: ""), message: NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_MESSAGE", comment: ""), preferredStyle: .alert) + var message = NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_MESSAGE", comment: "") + if let thread = thread as? TSGroupThread, thread.usesSharedSenderKeys, thread.groupModel.groupAdminIds.contains(getUserHexEncodedPublicKey()) { + message = "Because you are the creator of this group it will be deleted for everyone. This cannot be undone." + } + let alert = UIAlertController(title: NSLocalizedString("CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE", comment: ""), message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: NSLocalizedString("TXT_DELETE_TITLE", comment: ""), style: .destructive) { _ in Storage.write { transaction in Storage.shared.cancelPendingMessageSendJobs(for: thread.uniqueId!, using: transaction) @@ -420,11 +424,14 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol } else if let thread = thread as? TSGroupThread, thread.usesSharedSenderKeys == true { let groupID = thread.groupModel.groupId let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID) - let _ = MessageSender.leave(groupPublicKey, using: transaction).ensure { + do { + try MessageSender.leaveV2(groupPublicKey, using: transaction) Storage.write { transaction in thread.removeAllThreadInteractions(with: transaction) thread.remove(with: transaction) } + } catch { + // TODO: Handle } } else { thread.removeAllThreadInteractions(with: transaction) diff --git a/Session/View Controllers/NewClosedGroupVC.swift b/Session/View Controllers/NewClosedGroupVC.swift index 443ad3d3b..3250f7be3 100644 --- a/Session/View Controllers/NewClosedGroupVC.swift +++ b/Session/View Controllers/NewClosedGroupVC.swift @@ -170,11 +170,6 @@ final class NewClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelegat ModalActivityIndicatorViewController.present(fromViewController: navigationController!, canCancel: false) { [weak self] _ in var promise: Promise! Storage.writeSync { transaction in - - /* - promise = MessageSender.createClosedGroup(name: name, members: selectedContacts, transaction: transaction) - */ - promise = MessageSender.createV2ClosedGroup(name: name, members: selectedContacts, transaction: transaction) } let _ = promise.done(on: DispatchQueue.main) { thread in diff --git a/SessionMessagingKit/Database/Storage+ClosedGroups.swift b/SessionMessagingKit/Database/Storage+ClosedGroups.swift index cda71072d..76d9d89f3 100644 --- a/SessionMessagingKit/Database/Storage+ClosedGroups.swift +++ b/SessionMessagingKit/Database/Storage+ClosedGroups.swift @@ -122,7 +122,6 @@ extension Storage { var result: Set = [] Storage.read { transaction in result = result.union(Set(transaction.allKeys(inCollection: Storage.closedGroupPublicKeyCollection))) - result = result.union(Set(transaction.allKeys(inCollection: Storage.closedGroupPrivateKeyCollection))) } return result } diff --git a/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdateV2.swift b/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdateV2.swift index 7a1a480c4..5bae7d9eb 100644 --- a/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdateV2.swift +++ b/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdateV2.swift @@ -80,8 +80,8 @@ public final class ClosedGroupUpdateV2 : ControlMessage { case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins): return !publicKey.isEmpty && !name.isEmpty && !encryptionKeyPair.publicKey.isEmpty && !encryptionKeyPair.privateKey.isEmpty && !members.isEmpty && !admins.isEmpty - case .update(let name, let members): - return !name.isEmpty && !members.isEmpty + case .update(let name, _): + return !name.isEmpty case .encryptionKeyPair: return true } } diff --git a/SessionMessagingKit/Meta/SessionMessagingKit.h b/SessionMessagingKit/Meta/SessionMessagingKit.h index 6c7247ea4..ca96b4f92 100644 --- a/SessionMessagingKit/Meta/SessionMessagingKit.h +++ b/SessionMessagingKit/Meta/SessionMessagingKit.h @@ -6,6 +6,7 @@ FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[]; #import #import #import +#import #import #import #import diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index ff3cb175f..b29b84287 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -12,7 +12,6 @@ extension MessageReceiver { case let message as ReadReceipt: handleReadReceipt(message, using: transaction) case let message as TypingIndicator: handleTypingIndicator(message, using: transaction) case let message as ClosedGroupUpdateV2: handleClosedGroupUpdateV2(message, using: transaction) - case let message as ClosedGroupUpdate: handleClosedGroupUpdate(message, using: transaction) case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction) case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, openGroupID: openGroupID, isBackgroundPoll: isBackgroundPoll, using: transaction) default: fatalError() @@ -224,17 +223,6 @@ extension MessageReceiver { case .encryptionKeyPair: handleGroupEncryptionKeyPair(message, using: transaction) } } - - private static func handleClosedGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) { - switch message.kind! { - case .new: handleNewGroup(message, using: transaction) - case .info: handleGroupUpdate(message, using: transaction) - case .senderKeyRequest: handleSenderKeyRequest(message, using: transaction) - case .senderKey: handleSenderKey(message, using: transaction) - } - } - - // MARK: - V2 private static func handleNewGroupV2(_ message: ClosedGroupUpdateV2, using transaction: Any) { // Prepare @@ -286,8 +274,8 @@ extension MessageReceiver { guard Set(group.groupMemberIds).contains(message.sender!) else { return SNLog("Ignoring closed group update message from non-member.") } - // Check that the admin wasn't removed - guard members.contains(group.groupAdminIds.first!) else { + // Check that the admin wasn't removed unless the group was destroyed entirely + if !members.contains(group.groupAdminIds.first!) && !members.isEmpty { return SNLog("Ignoring invalid closed group update message.") } // Remove the group from the user's set of public keys to poll for if the current user was removed @@ -363,164 +351,4 @@ extension MessageReceiver { Storage.shared.addClosedGroupEncryptionKeyPair(keyPair, for: groupPublicKey, using: transaction) SNLog("Received a new closed group encryption key pair.") } - - - - // MARK: - V1 - - private static func handleNewGroup(_ message: ClosedGroupUpdate, using transaction: Any) { - guard case let .new(groupPublicKeyAsData, name, groupPrivateKey, senderKeys, membersAsData, adminsAsData) = message.kind else { return } - let transaction = transaction as! YapDatabaseReadWriteTransaction - let groupPublicKey = groupPublicKeyAsData.toHexString() - let members = membersAsData.map { $0.toHexString() } - let admins = adminsAsData.map { $0.toHexString() } - // Persist the ratchets - senderKeys.forEach { senderKey in - guard members.contains(senderKey.publicKey.toHexString()) else { return } - let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: []) - Storage.shared.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderKey.publicKey.toHexString(), ratchet: ratchet, using: transaction) - } - // Sort out any discrepancies between the provided sender keys and what's required - let missingSenderKeys = Set(members).subtracting(senderKeys.map { $0.publicKey.toHexString() }) - let userPublicKey = getUserHexEncodedPublicKey() - if missingSenderKeys.contains(userPublicKey) { - let userRatchet = SharedSenderKeys.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction) - let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex, publicKey: Data(hex: userPublicKey)) - members.forEach { member in - guard member != userPublicKey else { return } - let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.senderKey(groupPublicKey: Data(hex: groupPublicKey), senderKey: userSenderKey) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } - } - missingSenderKeys.subtracting([ userPublicKey ]).forEach { publicKey in - MessageSender.shared.requestSenderKey(for: groupPublicKey, senderPublicKey: publicKey, using: transaction) - } - // Create the group - let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) - let group = TSGroupModel(title: name, memberIds: members, image: nil, groupId: groupID, groupType: .closedGroup, adminIds: admins) - let thread: TSGroupThread - if let t = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID), transaction: transaction) { - thread = t - thread.setGroupModel(group, with: transaction) - } else { - thread = TSGroupThread.getOrCreateThread(with: group, transaction: transaction) - thread.usesSharedSenderKeys = true - thread.save(with: transaction) - } - // Add the group to the user's set of public keys to poll for - Storage.shared.setClosedGroupPrivateKey(groupPrivateKey.toHexString(), for: groupPublicKey, using: transaction) - // Notify the PN server - let _ = PushNotificationAPI.performOperation(.subscribe, for: groupPublicKey, publicKey: getUserHexEncodedPublicKey()) - // Notify the user - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .typeGroupUpdate) - infoMessage.save(with: transaction) - } - - private static func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) { - guard case let .info(groupPublicKeyAsData, name, senderKeys, membersAsData, adminsAsData) = message.kind else { return } - let transaction = transaction as! YapDatabaseReadWriteTransaction - let groupPublicKey = groupPublicKeyAsData.toHexString() - let members = membersAsData.map { $0.toHexString() } - let admins = adminsAsData.map { $0.toHexString() } - // Get the group - let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) - guard let thread = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID), transaction: transaction) else { - return SNLog("Ignoring closed group info message for nonexistent group.") - } - let group = thread.groupModel - // Check that the sender is a member of the group (before the update) - guard Set(group.groupMemberIds).contains(message.sender!) else { - return SNLog("Ignoring closed group info message from non-member.") - } - // Store the ratchets for any new members (it's important that this happens before the code below) - senderKeys.forEach { senderKey in - let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: []) - Storage.shared.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderKey.publicKey.toHexString(), ratchet: ratchet, using: transaction) - } - // Delete all ratchets and either: - // • Send out the user's new ratchet using established channels if other members of the group left or were removed - // • Remove the group from the user's set of public keys to poll for if the current user was among the members that were removed - let oldMembers = group.groupMemberIds - let userPublicKey = getUserHexEncodedPublicKey() - let wasUserRemoved = !members.contains(userPublicKey) - if Set(members).intersection(oldMembers) != Set(oldMembers) { - let allOldRatchets = Storage.shared.getAllClosedGroupRatchets(for: groupPublicKey) - for (senderPublicKey, oldRatchet) in allOldRatchets { - let collection = ClosedGroupRatchetCollectionType.old - Storage.shared.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderPublicKey, ratchet: oldRatchet, in: collection, using: transaction) - } - Storage.shared.removeAllClosedGroupRatchets(for: groupPublicKey, using: transaction) - if wasUserRemoved { - Storage.shared.removeClosedGroupPrivateKey(for: groupPublicKey, using: transaction) - // Notify the PN server - let _ = PushNotificationAPI.performOperation(.unsubscribe, for: groupPublicKey, publicKey: userPublicKey) - } else { - let userRatchet = SharedSenderKeys.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction) - let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex, publicKey: Data(hex: userPublicKey)) - members.forEach { member in - guard member != userPublicKey else { return } - let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.senderKey(groupPublicKey: Data(hex: groupPublicKey), senderKey: userSenderKey) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } - } - } - // Update the group - let newGroupModel = TSGroupModel(title: name, memberIds: members, image: nil, groupId: groupID, groupType: .closedGroup, adminIds: admins) - thread.setGroupModel(newGroupModel, with: transaction) - // Notify the user if needed - if Set(members) != Set(oldMembers) || Set(admins) != Set(group.groupAdminIds) || name != group.groupName { - let infoMessageType: TSInfoMessageType = wasUserRemoved ? .typeGroupQuit : .typeGroupUpdate - let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: infoMessageType, customMessage: updateInfo) - infoMessage.save(with: transaction) - } - } - - private static func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any) { - guard case let .senderKeyRequest(groupPublicKeyAsData) = message.kind else { return } - let transaction = transaction as! YapDatabaseReadWriteTransaction - let userPublicKey = getUserHexEncodedPublicKey() - let groupPublicKey = groupPublicKeyAsData.toHexString() - let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) - guard let groupThread = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID), transaction: transaction) else { - return SNLog("Ignoring closed group sender key request for nonexistent group.") - } - let group = groupThread.groupModel - // Check that the requesting user is a member of the group - let members = Set(group.groupMemberIds) - guard members.contains(message.sender!) else { - return SNLog("Ignoring closed group sender key request from non-member.") - } - // Respond to the request - SNLog("Responding to sender key request from: \(message.sender!).") - let userRatchet = Storage.shared.getClosedGroupRatchet(for: groupPublicKey, senderPublicKey: userPublicKey) - ?? SharedSenderKeys.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction) - let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex, publicKey: Data(hex: userPublicKey)) - let thread = TSContactThread.getOrCreateThread(withContactId: message.sender!, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.senderKey(groupPublicKey: Data(hex: groupPublicKey), senderKey: userSenderKey) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } - - private static func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any) { - guard case let .senderKey(groupPublicKeyAsData, senderKey) = message.kind else { return } - let groupPublicKey = groupPublicKeyAsData.toHexString() - guard senderKey.publicKey.toHexString() == message.sender! else { - return SNLog("Ignoring invalid closed group sender key.") - } - // Store the sender key - SNLog("Received a sender key from: \(message.sender!).") - let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: []) - Storage.shared.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: message.sender!, ratchet: ratchet, using: transaction) - } } diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index f5f4ee727..af6b04af6 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -71,31 +71,24 @@ public enum MessageReceiver { (plaintext, sender) = try decryptWithSessionProtocol(ciphertext: ciphertext, using: userX25519KeyPair) case .closedGroupCiphertext: guard let hexEncodedGroupPublicKey = envelope.source, SNMessagingKitConfiguration.shared.storage.isClosedGroup(hexEncodedGroupPublicKey) else { throw Error.invalidGroupPublicKey } - do { - var encryptionKeyPairs = Storage.shared.getClosedGroupEncryptionKeyPairs(for: hexEncodedGroupPublicKey) - guard !encryptionKeyPairs.isEmpty else { throw Error.noGroupKeyPair } - // Loop through all known group key pairs in reverse order (i.e. try the latest key pair first (which'll more than - // likely be the one we want) but try older ones in case that didn't work) - var encryptionKeyPair = encryptionKeyPairs.removeLast() - func decrypt() throws { - do { - (plaintext, sender) = try decryptWithSessionProtocol(ciphertext: ciphertext, using: encryptionKeyPair) - } catch { - if !encryptionKeyPairs.isEmpty { - encryptionKeyPair = encryptionKeyPairs.removeLast() - try decrypt() - } else { - throw error - } + var encryptionKeyPairs = Storage.shared.getClosedGroupEncryptionKeyPairs(for: hexEncodedGroupPublicKey) + guard !encryptionKeyPairs.isEmpty else { throw Error.noGroupKeyPair } + // Loop through all known group key pairs in reverse order (i.e. try the latest key pair first (which'll more than + // likely be the one we want) but try older ones in case that didn't work) + var encryptionKeyPair = encryptionKeyPairs.removeLast() + func decrypt() throws { + do { + (plaintext, sender) = try decryptWithSessionProtocol(ciphertext: ciphertext, using: encryptionKeyPair) + } catch { + if !encryptionKeyPairs.isEmpty { + encryptionKeyPair = encryptionKeyPairs.removeLast() + try decrypt() + } else { + throw error } } - try decrypt() - } catch { - // Fall back on the V1 method - guard let privateKey = SNMessagingKitConfiguration.shared.storage.getClosedGroupPrivateKey(for: hexEncodedGroupPublicKey) else { throw Error.noGroupKeyPair } - let keyPair = try ECKeyPair(publicKeyData: Data(hex: hexEncodedGroupPublicKey.removing05PrefixIfNeeded()), privateKeyData: Data(hex: privateKey)) - (plaintext, sender) = try decryptWithSessionProtocol(ciphertext: ciphertext, using: keyPair) } + try decrypt() groupPublicKey = envelope.source default: throw Error.unknownEnvelopeType } @@ -117,7 +110,6 @@ public enum MessageReceiver { if let readReceipt = ReadReceipt.fromProto(proto) { return readReceipt } if let typingIndicator = TypingIndicator.fromProto(proto) { return typingIndicator } if let closedGroupUpdate = ClosedGroupUpdateV2.fromProto(proto) { return closedGroupUpdate } - if let closedGroupUpdate = ClosedGroupUpdate.fromProto(proto) { return closedGroupUpdate } if let expirationTimerUpdate = ExpirationTimerUpdate.fromProto(proto) { return expirationTimerUpdate } if let visibleMessage = VisibleMessage.fromProto(proto) { return visibleMessage } return nil diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift index 054a49c4c..0af0165e0 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift @@ -1,9 +1,7 @@ import PromiseKit import SessionProtocolKit -extension MessageSender : SharedSenderKeysDelegate { - - // MARK: - V2 +extension MessageSender { public static func createV2ClosedGroup(name: String, members: Set, transaction: YapDatabaseReadWriteTransaction) -> Promise { // Prepare @@ -62,28 +60,33 @@ extension MessageSender : SharedSenderKeysDelegate { let oldMembers = Set(group.groupMemberIds) let newMembers = members.subtracting(oldMembers) let membersAsData = members.map { Data(hex: $0) } + let removedMembers = oldMembers.subtracting(members) let admins = group.groupAdminIds let adminsAsData = admins.map { Data(hex: $0) } + let isUserLeaving = !members.contains(userPublicKey) + let wasAnyUserRemoved = !removedMembers.isEmpty + let isCurrentUserAdmin = group.groupAdminIds.contains(getUserHexEncodedPublicKey()) + // Check preconditions guard let encryptionKeyPair = Storage.shared.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { SNLog("Couldn't get key pair for closed group.") throw Error.noKeyPair } - let removedMembers = oldMembers.subtracting(members) - guard !removedMembers.contains(admins.first!) else { - SNLog("Can't remove admin from closed group.") + if removedMembers.contains(admins.first!) && !members.isEmpty { + SNLog("Can't remove admin from closed group without removing everyone.") throw Error.invalidClosedGroupUpdate } - let isUserLeaving = removedMembers.contains(userPublicKey) - if isUserLeaving && (removedMembers.count != 1 || !newMembers.isEmpty) { - SNLog("Can't remove self and add or remove others simultaneously.") - throw Error.invalidClosedGroupUpdate + if isUserLeaving && !members.isEmpty { + guard removedMembers.count == 1 && newMembers.isEmpty else { + SNLog("Can't remove self and add or remove others simultaneously.") + throw Error.invalidClosedGroupUpdate + } } // Send the update to the group let mainClosedGroupUpdate = ClosedGroupUpdateV2(kind: .update(name: name, members: membersAsData)) if isUserLeaving { let _ = MessageSender.sendNonDurably(mainClosedGroupUpdate, in: thread, using: transaction).done { SNMessagingKitConfiguration.shared.storage.write { transaction in - // Remove the group private key and unsubscribe from PNs + // Remove the group from the database and unsubscribe from PNs Storage.shared.removeAllClosedGroupEncryptionKeyPairs(for: groupPublicKey, using: transaction) Storage.shared.removeClosedGroupPublicKey(groupPublicKey, using: transaction) let _ = PushNotificationAPI.performOperation(.unsubscribe, for: groupPublicKey, publicKey: userPublicKey) @@ -92,8 +95,6 @@ extension MessageSender : SharedSenderKeysDelegate { } else { MessageSender.send(mainClosedGroupUpdate, in: thread, using: transaction) // Generate and distribute a new encryption key pair if needed - let wasAnyUserRemoved = !removedMembers.isEmpty - let isCurrentUserAdmin = group.groupAdminIds.contains(getUserHexEncodedPublicKey()) if wasAnyUserRemoved && isCurrentUserAdmin { try generateAndSendNewEncryptionKeyPair(for: groupPublicKey, to: members.subtracting(newMembers), using: transaction) } @@ -115,7 +116,8 @@ extension MessageSender : SharedSenderKeysDelegate { let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .typeGroupUpdate, customMessage: updateInfo) infoMessage.save(with: transaction) } - + + @objc(leaveClosedGroupWithPublicKey:using:error:) public static func leaveV2(_ groupPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) throws { let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) let threadID = TSGroupThread.threadId(fromGroupId: groupID) @@ -124,8 +126,14 @@ extension MessageSender : SharedSenderKeysDelegate { throw Error.noThread } let group = thread.groupModel - var newMembers = Set(group.groupMemberIds) - newMembers.remove(getUserHexEncodedPublicKey()) + let isCurrentUserAdmin = group.groupAdminIds.contains(getUserHexEncodedPublicKey()) + var newMembers: Set + if !isCurrentUserAdmin { + newMembers = Set(group.groupMemberIds) + newMembers.remove(getUserHexEncodedPublicKey()) + } else { + newMembers = [] // If the admin leaves the group is destroyed + } return try updateV2(groupPublicKey, with: newMembers, name: group.groupName!, transaction: transaction) } @@ -160,213 +168,4 @@ extension MessageSender : SharedSenderKeysDelegate { } } } - - - - // MARK: - V1 - - public static func createClosedGroup(name: String, members: Set, transaction: YapDatabaseReadWriteTransaction) -> Promise { - // Prepare - var members = members - let userPublicKey = getUserHexEncodedPublicKey() - // Generate a key pair for the group - let groupKeyPair = Curve25519.generateKeyPair() - let groupPublicKey = groupKeyPair.hexEncodedPublicKey // Includes the "05" prefix - // Ensure the current user is included in the member list - members.insert(userPublicKey) - let membersAsData = members.map { Data(hex: $0) } - // Create ratchets for all members - let senderKeys: [ClosedGroupSenderKey] = members.map { publicKey in - let ratchet = SharedSenderKeys.generateRatchet(for: groupPublicKey, senderPublicKey: publicKey, using: transaction) - return ClosedGroupSenderKey(chainKey: Data(hex: ratchet.chainKey), keyIndex: ratchet.keyIndex, publicKey: Data(hex: publicKey)) - } - // Create the group - let admins = [ userPublicKey ] - let adminsAsData = admins.map { Data(hex: $0) } - let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) - let group = TSGroupModel(title: name, memberIds: [String](members), image: nil, groupId: groupID, groupType: .closedGroup, adminIds: admins) - let thread = TSGroupThread.getOrCreateThread(with: group, transaction: transaction) - thread.usesSharedSenderKeys = true - thread.save(with: transaction) - // Send a closed group update message to all members using established channels - var promises: [Promise] = [] - for member in members { - guard member != userPublicKey else { continue } - let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.new(groupPublicKey: Data(hex: groupPublicKey), name: name, - groupPrivateKey: groupKeyPair.privateKey, senderKeys: senderKeys, members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - let promise = MessageSender.sendNonDurably(closedGroupUpdate, in: thread, using: transaction) - promises.append(promise) - } - // Add the group to the user's set of public keys to poll for - Storage.shared.setClosedGroupPrivateKey(groupKeyPair.privateKey.toHexString(), for: groupPublicKey, using: transaction) - // Notify the PN server - promises.append(PushNotificationAPI.performOperation(.subscribe, for: groupPublicKey, publicKey: userPublicKey)) - // Notify the user - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .typeGroupUpdate) - infoMessage.save(with: transaction) - // Return - return when(fulfilled: promises).map2 { thread } - } - - /// - Note: The returned promise is only relevant for group leaving. - public static func update(_ groupPublicKey: String, with members: Set, name: String, transaction: YapDatabaseReadWriteTransaction) -> Promise { - let (promise, seal) = Promise.pending() - let userPublicKey = getUserHexEncodedPublicKey() - let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) - guard let thread = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID), transaction: transaction) else { - SNLog("Can't update nonexistent closed group.") - return Promise(error: Error.noThread) - } - let group = thread.groupModel - let oldMembers = Set(group.groupMemberIds) - let newMembers = members.subtracting(oldMembers) - let membersAsData = members.map { Data(hex: $0) } - let admins = group.groupAdminIds - let adminsAsData = admins.map { Data(hex: $0) } - guard let groupPrivateKey = Storage.shared.getClosedGroupPrivateKey(for: groupPublicKey) else { - SNLog("Couldn't get private key for closed group.") - return Promise(error: Error.noKeyPair) - } - let wasAnyUserRemoved = Set(members).intersection(oldMembers) != oldMembers - let removedMembers = oldMembers.subtracting(members) - let isUserLeaving = removedMembers.contains(userPublicKey) - var newSenderKeys: [ClosedGroupSenderKey] = [] - if wasAnyUserRemoved { - if isUserLeaving && removedMembers.count != 1 { - SNLog("Can't remove self and others simultaneously.") - return Promise(error: Error.invalidClosedGroupUpdate) - } - // Send the update to the existing members using established channels (don't include new ratchets as everyone should regenerate new ratchets individually) - let promises: [Promise] = oldMembers.map { member in - let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: [], - members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - return MessageSender.sendNonDurably(closedGroupUpdate, in: thread, using: transaction) - } - when(resolved: promises).done2 { _ in seal.fulfill(()) }.catch2 { seal.reject($0) } - let _ = promise.done { - SNMessagingKitConfiguration.shared.storage.writeSync { transaction in - let allOldRatchets = Storage.shared.getAllClosedGroupRatchets(for: groupPublicKey) - for (senderPublicKey, oldRatchet) in allOldRatchets { - let collection = ClosedGroupRatchetCollectionType.old - Storage.shared.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderPublicKey, ratchet: oldRatchet, in: collection, using: transaction) - } - // Delete all ratchets (it's important that this happens * after * sending out the update) - Storage.shared.removeAllClosedGroupRatchets(for: groupPublicKey, using: transaction) - // Remove the group from the user's set of public keys to poll for if the user is leaving. Otherwise generate a new ratchet and - // send it out to all members (minus the removed ones) using established channels. - if isUserLeaving { - Storage.shared.removeClosedGroupPrivateKey(for: groupPublicKey, using: transaction) - // Notify the PN server - let _ = PushNotificationAPI.performOperation(.unsubscribe, for: groupPublicKey, publicKey: userPublicKey) - } else { - // Send closed group update messages to any new members using established channels - for member in newMembers { - let transaction = transaction as! YapDatabaseReadWriteTransaction - let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.new(groupPublicKey: Data(hex: groupPublicKey), name: name, - groupPrivateKey: Data(hex: groupPrivateKey), senderKeys: [], members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } - // Send out the user's new ratchet to all members (minus the removed ones) using established channels - let userRatchet = SharedSenderKeys.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction) - let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex, publicKey: Data(hex: userPublicKey)) - for member in members { - let transaction = transaction as! YapDatabaseReadWriteTransaction - guard member != userPublicKey else { continue } - let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.senderKey(groupPublicKey: Data(hex: groupPublicKey), senderKey: userSenderKey) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } - } - } - } - } else if !newMembers.isEmpty { - seal.fulfill(()) - // Generate ratchets for any new members - newSenderKeys = newMembers.map { publicKey in - let ratchet = SharedSenderKeys.generateRatchet(for: groupPublicKey, senderPublicKey: publicKey, using: transaction) - return ClosedGroupSenderKey(chainKey: Data(hex: ratchet.chainKey), keyIndex: ratchet.keyIndex, publicKey: Data(hex: publicKey)) - } - // Send a closed group update message to the existing members with the new members' ratchets (this message is aimed at the group) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: newSenderKeys, - members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - // Send closed group update messages to the new members using established channels - var allSenderKeys = Storage.shared.getAllClosedGroupSenderKeys(for: groupPublicKey) - allSenderKeys.formUnion(newSenderKeys) - for member in newMembers { - let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.new(groupPublicKey: Data(hex: groupPublicKey), name: name, - groupPrivateKey: Data(hex: groupPrivateKey), senderKeys: [ClosedGroupSenderKey](allSenderKeys), members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } - } else { - seal.fulfill(()) - let allSenderKeys = Storage.shared.getAllClosedGroupSenderKeys(for: groupPublicKey) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, - senderKeys: [ClosedGroupSenderKey](allSenderKeys), members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } - // Update the group - let newGroupModel = TSGroupModel(title: name, memberIds: [String](members), image: nil, groupId: groupID, groupType: .closedGroup, adminIds: admins) - thread.setGroupModel(newGroupModel, with: transaction) - // Notify the user - let updateInfo = group.getInfoStringAboutUpdate(to: newGroupModel) - let infoMessage = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageType: .typeGroupUpdate, customMessage: updateInfo) - infoMessage.save(with: transaction) - // Return - return promise - } - - /// The returned promise is fulfilled when the group update message has been sent. It doesn't wait for the user's new ratchet to be distributed. - @objc(leaveGroupWithPublicKey:transaction:) - public static func objc_leave(_ groupPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise { - return AnyPromise.from(leave(groupPublicKey, using: transaction)) - } - - /// The returned promise is fulfilled when the group update message has been sent. It doesn't wait for the user's new ratchet to be distributed. - public static func leave(_ groupPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) -> Promise { - let userPublicKey = getUserHexEncodedPublicKey() - let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) - guard let thread = TSGroupThread.fetch(uniqueId: TSGroupThread.threadId(fromGroupId: groupID), transaction: transaction) else { - SNLog("Can't leave nonexistent closed group.") - return Promise(error: Error.noThread) - } - let group = thread.groupModel - var newMembers = Set(group.groupMemberIds) - newMembers.remove(userPublicKey) - return update(groupPublicKey, with: newMembers, name: group.groupName!, transaction: transaction) - } - - public func requestSenderKey(for groupPublicKey: String, senderPublicKey: String, using transaction: Any) { // FIXME: This should be static - SNLog("Requesting sender key for group public key: \(groupPublicKey), sender public key: \(senderPublicKey).") - let transaction = transaction as! YapDatabaseReadWriteTransaction - let thread = TSContactThread.getOrCreateThread(withContactId: senderPublicKey, transaction: transaction) - thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdate.Kind.senderKeyRequest(groupPublicKey: Data(hex: groupPublicKey)) - let closedGroupUpdate = ClosedGroupUpdate() - closedGroupUpdate.kind = closedGroupUpdateKind - MessageSender.send(closedGroupUpdate, in: thread, using: transaction) - } } diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index 012178298..170fd473f 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -176,11 +176,6 @@ public final class MessageSender : NSObject { switch destination { case .contact(let publicKey): ciphertext = try encryptWithSessionProtocol(plaintext, for: publicKey) case .closedGroup(let groupPublicKey): - - /* - ciphertext = try encryptWithSessionProtocol(plaintext, for: groupPublicKey) - */ - guard let encryptionKeyPair = Storage.shared.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { throw Error.noKeyPair } ciphertext = try encryptWithSessionProtocol(plaintext, for: encryptionKeyPair.hexEncodedPublicKey) case .openGroup(_, _): preconditionFailure() diff --git a/SessionProtocolKit/NSData+messagePadding.h b/SessionMessagingKit/Utilities/NSData+messagePadding.h similarity index 100% rename from SessionProtocolKit/NSData+messagePadding.h rename to SessionMessagingKit/Utilities/NSData+messagePadding.h diff --git a/SessionProtocolKit/NSData+messagePadding.m b/SessionMessagingKit/Utilities/NSData+messagePadding.m similarity index 100% rename from SessionProtocolKit/NSData+messagePadding.m rename to SessionMessagingKit/Utilities/NSData+messagePadding.m diff --git a/SessionProtocolKit/Meta/SessionProtocolKit.h b/SessionProtocolKit/Meta/SessionProtocolKit.h index e5f9c3595..c1fcd3157 100644 --- a/SessionProtocolKit/Meta/SessionProtocolKit.h +++ b/SessionProtocolKit/Meta/SessionProtocolKit.h @@ -2,5 +2,3 @@ FOUNDATION_EXPORT double SessionProtocolKitVersionNumber; FOUNDATION_EXPORT const unsigned char SessionProtocolKitVersionString[]; - -#import diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 3aaa2d9cf..63e972a49 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -317,6 +317,11 @@ C31FFE57254A5FFE00F19441 /* KeyPairUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */; }; C329FEEC24F7277900B1C64C /* LightModeSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C329FEEB24F7277900B1C64C /* LightModeSheet.swift */; }; C32A025A25A7FC55000ED5D4 /* ClosedGroupsV2Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32A025925A7FC55000ED5D4 /* ClosedGroupsV2Migration.swift */; }; + C32A026325A801AA000ED5D4 /* NSData+messagePadding.m in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D4825589FF20043A11F /* NSData+messagePadding.m */; }; + C32A026C25A801AF000ED5D4 /* NSData+messagePadding.h in Headers */ = {isa = PBXBuildFile; fileRef = C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C32A027D25A80423000ED5D4 /* SessionProtocolKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A8622553B41A00C340D1 /* SessionProtocolKit.framework */; }; + C32A027E25A80428000ED5D4 /* SessionProtocolKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A8622553B41A00C340D1 /* SessionProtocolKit.framework */; }; + C32A027F25A80432000ED5D4 /* SessionProtocolKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A8622553B41A00C340D1 /* SessionProtocolKit.framework */; }; C32C598A256D0664003C73A2 /* SNProtoEnvelope+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */; }; C32C599E256DB02B003C73A2 /* TypingIndicators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA87255A57FC00E217F9 /* TypingIndicators.swift */; }; C32C59C0256DB41F003C73A2 /* TSThread.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAD3255A580300E217F9 /* TSThread.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -453,7 +458,6 @@ C33FD9AF255A548A00E217F9 /* SignalUtilitiesKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FD9AD255A548A00E217F9 /* SignalUtilitiesKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; C33FD9B3255A548A00E217F9 /* SignalUtilitiesKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C33FD9AB255A548A00E217F9 /* SignalUtilitiesKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; C33FD9C2255A54EF00E217F9 /* SessionMessagingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A6F025539DE700C340D1 /* SessionMessagingKit.framework */; }; - C33FD9C3255A54EF00E217F9 /* SessionProtocolKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A8622553B41A00C340D1 /* SessionProtocolKit.framework */; }; C33FD9C4255A54EF00E217F9 /* SessionSnodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A59F255385C100C340D1 /* SessionSnodeKit.framework */; }; C33FD9C5255A54EF00E217F9 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; }; C33FDC27255A581F00E217F9 /* YapDatabase+Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA6D255A57FA00E217F9 /* YapDatabase+Promise.swift */; }; @@ -545,7 +549,6 @@ C37F5385255B94F6002AEA92 /* SelectRecipientViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF34E255B6DC8007E1867 /* SelectRecipientViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; C37F5396255B95BD002AEA92 /* OWSAnyTouchGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = C38EF302255B6DBE007E1867 /* OWSAnyTouchGestureRecognizer.h */; settings = {ATTRIBUTES = (Public, ); }; }; C37F5414255BAFA7002AEA92 /* SignalUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C33FD9AB255A548A00E217F9 /* SignalUtilitiesKit.framework */; }; - C37F54CB255BB53F002AEA92 /* SessionProtocolKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A8622553B41A00C340D1 /* SessionProtocolKit.framework */; }; C37F54DC255BB84A002AEA92 /* SessionSnodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A59F255385C100C340D1 /* SessionSnodeKit.framework */; }; C38D5E8D2575011E00B6A65C /* MessageSender+ClosedGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38D5E8C2575011E00B6A65C /* MessageSender+ClosedGroups.swift */; }; C38EF00C255B61CC007E1867 /* SignalUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C33FD9AB255A548A00E217F9 /* SignalUtilitiesKit.framework */; }; @@ -705,8 +708,6 @@ C3A71D0B2558989C0043A11F /* MessageWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D0A2558989C0043A11F /* MessageWrapper.swift */; }; C3A71D1E25589AC30043A11F /* WebSocketProto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D1C25589AC30043A11F /* WebSocketProto.swift */; }; C3A71D1F25589AC30043A11F /* WebSocketResources.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D1D25589AC30043A11F /* WebSocketResources.pb.swift */; }; - C3A71D5425589FF30043A11F /* NSData+messagePadding.m in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D4825589FF20043A11F /* NSData+messagePadding.m */; }; - C3A71D5A25589FF30043A11F /* NSData+messagePadding.h in Headers */ = {isa = PBXBuildFile; fileRef = C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */; settings = {ATTRIBUTES = (Public, ); }; }; C3A71F892558BA9F0043A11F /* Mnemonic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71F882558BA9F0043A11F /* Mnemonic.swift */; }; C3A7211A2558BCA10043A11F /* DiffieHellman.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A71D662558A0170043A11F /* DiffieHellman.swift */; }; C3A721382558BDFA0043A11F /* OpenGroupMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A721342558BDF90043A11F /* OpenGroupMessage.swift */; }; @@ -758,7 +759,6 @@ C3C2A7852553AAF300C340D1 /* SessionProtos.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A7832553AAF300C340D1 /* SessionProtos.pb.swift */; }; C3C2A8662553B41A00C340D1 /* SessionProtocolKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C3C2A8642553B41A00C340D1 /* SessionProtocolKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; C3C2A86A2553B41A00C340D1 /* SessionProtocolKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A8622553B41A00C340D1 /* SessionProtocolKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C3C2AAC82553C25300C340D1 /* SessionProtocolKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A8622553B41A00C340D1 /* SessionProtocolKit.framework */; }; C3C2ABD22553C6C900C340D1 /* Data+SecureRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2ABD12553C6C900C340D1 /* Data+SecureRandom.swift */; }; C3C2AC2E2553CBEB00C340D1 /* String+Trimming.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2AC2D2553CBEB00C340D1 /* String+Trimming.swift */; }; C3C2AC372553CCE600C340D1 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; }; @@ -1877,9 +1877,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C32A027E25A80428000ED5D4 /* SessionProtocolKit.framework in Frameworks */, C38EF48A255B7E3F007E1867 /* SessionUIKit.framework in Frameworks */, C33FD9C2255A54EF00E217F9 /* SessionMessagingKit.framework in Frameworks */, - C33FD9C3255A54EF00E217F9 /* SessionProtocolKit.framework in Frameworks */, C33FD9C4255A54EF00E217F9 /* SessionSnodeKit.framework in Frameworks */, C33FD9C5255A54EF00E217F9 /* SessionUtilitiesKit.framework in Frameworks */, B3E0C9C6F1633B1ABCE5AD0B /* Pods_SignalUtilitiesKit.framework in Frameworks */, @@ -1907,8 +1907,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C32A027D25A80423000ED5D4 /* SessionProtocolKit.framework in Frameworks */, 5DF9AB212C6DB1E8BE70EFF6 /* Pods_SessionMessagingKit.framework in Frameworks */, - C3C2AAC82553C25300C340D1 /* SessionProtocolKit.framework in Frameworks */, C3C2A70B25539E1E00C340D1 /* SessionSnodeKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1926,8 +1926,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C32A027F25A80432000ED5D4 /* SessionProtocolKit.framework in Frameworks */, C37F54DC255BB84A002AEA92 /* SessionSnodeKit.framework in Frameworks */, - C37F54CB255BB53F002AEA92 /* SessionProtocolKit.framework in Frameworks */, C37F5414255BAFA7002AEA92 /* SignalUtilitiesKit.framework in Frameworks */, 455A16DD1F1FEA0000F86704 /* Metal.framework in Frameworks */, 455A16DE1F1FEA0000F86704 /* MetalKit.framework in Frameworks */, @@ -3162,6 +3162,8 @@ C33FDB7F255A581100E217F9 /* FullTextSearchFinder.swift */, C33FDBC1255A581700E217F9 /* General.swift */, C3A71D0A2558989C0043A11F /* MessageWrapper.swift */, + C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */, + C3A71D4825589FF20043A11F /* NSData+messagePadding.m */, C38EF2F5255B6DBC007E1867 /* OWSAudioPlayer.h */, C38EF2F7255B6DBC007E1867 /* OWSAudioPlayer.m */, C38EF281255B6D84007E1867 /* OWSAudioSession.swift */, @@ -3324,8 +3326,6 @@ B8CA010A25A293530091AF73 /* ClosedGroupRatchet.swift */, B8CA010025A293260091AF73 /* ClosedGroupSenderKey.swift */, B8CA011425A293800091AF73 /* Configuration.swift */, - C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */, - C3A71D4825589FF20043A11F /* NSData+messagePadding.m */, B8CA011E25A2939F0091AF73 /* SharedSenderKeys.swift */, B8CA014025A293EE0091AF73 /* Storage.swift */, ); @@ -3669,6 +3669,7 @@ C32C5EF7256DF567003C73A2 /* TSDatabaseView.h in Headers */, C3A3A0B3256E17F2004D228D /* SSKJobRecord.h in Headers */, B8856ED7256F1EB4001CE70E /* OWSPreferences.h in Headers */, + C32A026C25A801AF000ED5D4 /* NSData+messagePadding.h in Headers */, C32C5BE6256DC891003C73A2 /* OWSReadReceiptManager.h in Headers */, C32C5EC3256DE133003C73A2 /* OWSQuotedReplyModel.h in Headers */, C32C5BF8256DC8F6003C73A2 /* OWSDisappearingMessagesJob.h in Headers */, @@ -3702,7 +3703,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C3A71D5A25589FF30043A11F /* NSData+messagePadding.h in Headers */, C3C2A8662553B41A00C340D1 /* SessionProtocolKit.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4740,6 +4740,7 @@ C3C2A74D2553A39700C340D1 /* VisibleMessage.swift in Sources */, C32C5AAD256DBE8F003C73A2 /* TSInfoMessage.m in Sources */, C32C5A13256DB7A5003C73A2 /* PushNotificationAPI.swift in Sources */, + C32A026325A801AA000ED5D4 /* NSData+messagePadding.m in Sources */, C352A3932557883D00338F3E /* JobDelegate.swift in Sources */, C32C5B84256DC54F003C73A2 /* SSKEnvironment.m in Sources */, C3A3A108256E1A5C004D228D /* OWSIncomingMessageFinder.m in Sources */, @@ -4868,7 +4869,6 @@ files = ( B8CA010125A293260091AF73 /* ClosedGroupSenderKey.swift in Sources */, B8CA011525A293800091AF73 /* Configuration.swift in Sources */, - C3A71D5425589FF30043A11F /* NSData+messagePadding.m in Sources */, B8CA011F25A2939F0091AF73 /* SharedSenderKeys.swift in Sources */, B8CA010B25A293530091AF73 /* ClosedGroupRatchet.swift in Sources */, B8CA014125A293EE0091AF73 /* Storage.swift in Sources */, diff --git a/SignalUtilitiesKit/Configuration.swift b/SignalUtilitiesKit/Configuration.swift index 540664d79..b69c8dddd 100644 --- a/SignalUtilitiesKit/Configuration.swift +++ b/SignalUtilitiesKit/Configuration.swift @@ -1,5 +1,4 @@ import SessionMessagingKit -import SessionProtocolKit import SessionSnodeKit extension OWSPrimaryStorage : OWSPrimaryStorageProtocol { } @@ -10,7 +9,6 @@ public final class Configuration : NSObject { @objc public static func performMainSetup() { SNMessagingKit.configure(storage: Storage.shared) SNSnodeKit.configure(storage: Storage.shared) - SNProtocolKit.configure(storage: Storage.shared, sharedSenderKeysDelegate: MessageSender.shared) SNUtilitiesKit.configure(owsPrimaryStorage: OWSPrimaryStorage.shared(), maxFileSize: UInt(Double(FileServerAPI.maxFileSize) / FileServerAPI.fileSizeORMultiplier)) } }