Merge pull request #257 from loki-project/shared-sender-keys

Remaining Shared Sender Keys Bits & Pieces Part 1/2
pull/260/head
Niels Andriesse 5 years ago committed by GitHub
commit 9ea2718d5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -174,7 +174,7 @@ final class NewClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelegat
guard selectedContacts.count >= 1 else {
return showError(title: "Please pick at least 1 group member")
}
guard selectedContacts.count < 50 else { // Minus one because we're going to include self later
guard selectedContacts.count < ClosedGroupsProtocol.groupSizeLimit else { // Minus one because we're going to include self later
return showError(title: NSLocalizedString("vc_create_closed_group_too_many_group_members_error", comment: ""))
}
let selectedContacts = self.selectedContacts

@ -683,22 +683,25 @@ const CGFloat kIconViewLength = 24;
[weakSelf showGroupMembersView];
}]
];
[mainSection addItem:[OWSTableItem
itemWithCustomCellBlock:^{
UITableViewCell *cell =
[weakSelf disclosureCellWithName:NSLocalizedString(@"LEAVE_GROUP_ACTION",
@"table cell label in conversation settings")
iconName:@"table_ic_group_leave"
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(
OWSConversationSettingsViewController, @"leave_group")];
cell.userInteractionEnabled = !weakSelf.hasLeftGroup;
return cell;
}
actionBlock:^{
[weakSelf didTapLeaveGroup];
}]
];
NSString *userPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
if ([((TSGroupThread *)self.thread).groupModel.groupMemberIds containsObject:userPublicKey]) {
[mainSection addItem:[OWSTableItem
itemWithCustomCellBlock:^{
UITableViewCell *cell =
[weakSelf disclosureCellWithName:NSLocalizedString(@"LEAVE_GROUP_ACTION",
@"table cell label in conversation settings")
iconName:@"table_ic_group_leave"
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(
OWSConversationSettingsViewController, @"leave_group")];
cell.userInteractionEnabled = !weakSelf.hasLeftGroup;
return cell;
}
actionBlock:^{
[weakSelf didTapLeaveGroup];
}]
];
}
}

@ -285,8 +285,7 @@ public enum OnionRequestAPI {
let url = "\(guardSnode.address):\(guardSnode.port)/onion_req"
let finalEncryptionResult = intermediate.finalEncryptionResult
let onion = finalEncryptionResult.ciphertext
let requestSizeLimit = Double(FileServerAPI.maxFileSize) / FileServerAPI.fileSizeORMultiplier
if case Destination.server = destination, Double(onion.count) > 0.75 * requestSizeLimit {
if case Destination.server = destination, Double(onion.count) > 0.75 * Double(FileServerAPI.maxFileSize) {
print("[Loki] Approaching request size limit: ~\(onion.count) bytes.")
}
let parameters: JSON = [

@ -13,6 +13,7 @@ import PromiseKit
@objc(LKClosedGroupsProtocol)
public final class ClosedGroupsProtocol : NSObject {
public static let isSharedSenderKeysEnabled = false
public static let groupSizeLimit = 10
// MARK: - Sending
@ -54,6 +55,7 @@ public final class ClosedGroupsProtocol : NSObject {
// Send a closed group update message to all members (and their linked devices) using established channels
var promises: [Promise<Void>] = []
for member in members { // Not `membersAndLinkedDevices` as this internally takes care of multi device already
guard member != userPublicKey else { continue }
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
thread.save(with: transaction)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.new(groupPublicKey: Data(hex: groupPublicKey), name: name,
@ -182,6 +184,7 @@ public final class ClosedGroupsProtocol : NSObject {
let userRatchet = SharedSenderKeysImplementation.shared.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 { // This internally takes care of multi device
guard member != userPublicKey else { continue }
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
thread.save(with: transaction)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.senderKey(groupPublicKey: Data(hex: groupPublicKey), senderKey: userSenderKey)
@ -201,6 +204,7 @@ public final class ClosedGroupsProtocol : NSObject {
}
public static func requestSenderKey(for groupPublicKey: String, senderPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) {
print("[Loki] Requesting sender key for group public key: \(groupPublicKey), sender public key: \(senderPublicKey).")
// Establish session if needed
SessionManagementProtocol.sendSessionRequestIfNeeded(to: senderPublicKey, using: transaction)
// Send the request
@ -286,7 +290,7 @@ public final class ClosedGroupsProtocol : NSObject {
}
let group = thread.groupModel
// Check that the sender is a member of the group (before the update)
var membersAndLinkedDevices: Set<String> = Set(group.groupMemberIds)
var membersAndLinkedDevices: Set<String> = Set(members)
for member in group.groupMemberIds {
let deviceLinks = OWSPrimaryStorage.shared().getDeviceLinks(for: member, in: transaction)
membersAndLinkedDevices.formUnion(deviceLinks.flatMap { [ $0.master.publicKey, $0.slave.publicKey ] })
@ -315,6 +319,7 @@ public final class ClosedGroupsProtocol : NSObject {
let userRatchet = SharedSenderKeysImplementation.shared.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 {
guard member != userPublicKey else { continue }
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
thread.save(with: transaction)
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.senderKey(groupPublicKey: Data(hex: groupPublicKey), senderKey: userSenderKey)
@ -354,6 +359,7 @@ public final class ClosedGroupsProtocol : NSObject {
return print("[Loki] Ignoring closed group sender key request from non-member.")
}
// Respond to the request
print("[Loki] Responding to sender key request from: \(senderPublicKey).")
SessionManagementProtocol.sendSessionRequestIfNeeded(to: senderPublicKey, using: transaction) // This internally takes care of multi device
let userRatchet = SharedSenderKeysImplementation.shared.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction)
let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex, publicKey: Data(hex: userPublicKey))
@ -389,6 +395,7 @@ public final class ClosedGroupsProtocol : NSObject {
return print("[Loki] Ignoring invalid closed group sender key.")
}
// Store the sender key
print("[Loki] Received a sender key from: \(senderPublicKey).")
let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: [])
Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderPublicKey, ratchet: ratchet, using: transaction)
}

@ -133,7 +133,17 @@ public final class SharedSenderKeysImplementation : NSObject, SharedSenderKeysPr
}
public func encrypt(_ plaintext: Data, for groupPublicKey: String, senderPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) throws -> (ivAndCiphertext: Data, keyIndex: UInt) {
let ratchet = try stepRatchetOnce(for: groupPublicKey, senderPublicKey: senderPublicKey, using: transaction)
let ratchet: ClosedGroupRatchet
do {
ratchet = try stepRatchetOnce(for: groupPublicKey, senderPublicKey: senderPublicKey, using: transaction)
} catch {
// FIXME: It'd be cleaner to handle this in OWSMessageDecrypter (where all the other decryption errors are handled), but this was a lot more
// convenient because there's an easy way to get the sender public key from here.
if case RatchetingError.loadingFailed(_, _) = error {
ClosedGroupsProtocol.requestSenderKey(for: groupPublicKey, senderPublicKey: senderPublicKey, using: transaction)
}
throw error
}
let iv = Data.getSecureRandomData(ofSize: SharedSenderKeysImplementation.ivSize)!
let gcm = GCM(iv: iv.bytes, tagLength: Int(SharedSenderKeysImplementation.gcmTagSize), mode: .combined)
let messageKey = ratchet.messageKeys.last!

Loading…
Cancel
Save