From 705e5f939d825df55c186665b6a732ef3cfcf2e4 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Fri, 10 May 2019 16:32:20 +1000 Subject: [PATCH] Set pre key bundle in FriendRequestMessage and EndSessionMessage. Updated PreKey Operations to not contact signal servers. --- Pods | 2 +- .../src/Account/CreatePreKeysOperation.swift | 12 +++++++++++ .../src/Account/PreKeyRefreshOperation.swift | 20 +++++++++++++++++++ .../Account/RotateSignedKeyOperation.swift | 14 +++++++++++++ .../src/Loki/Extensions/ECKeyPair.swift | 1 + .../Loki/Extensions/OWSPrimaryStorage+Loki.m | 18 ++++++++++++----- ...rotoPrekeyBundleMessage+PreKeyBundle.swift | 16 +++++++++++++++ .../Loki/Messages/OWSFriendRequestMessage.h | 1 + .../Loki/Messages/OWSFriendRequestMessage.m | 19 +++++++++++++++--- .../Interactions/OWSEndSessionMessage.m | 18 ++++++++++++++--- .../Messages/Interactions/TSOutgoingMessage.h | 2 +- .../Messages/Interactions/TSOutgoingMessage.m | 4 ++-- .../src/Messages/OWSMessageSender.m | 8 ++++++++ 13 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 SignalServiceKit/src/Loki/Extensions/SSKProtoPrekeyBundleMessage+PreKeyBundle.swift diff --git a/Pods b/Pods index 21ee23a8e..aa0882607 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 21ee23a8e22e91459835b682d821f862f75be233 +Subproject commit aa0882607c603f6ef576c9538e2f6481d09fd0ce diff --git a/SignalServiceKit/src/Account/CreatePreKeysOperation.swift b/SignalServiceKit/src/Account/CreatePreKeysOperation.swift index 80449ca89..b9fd4c487 100644 --- a/SignalServiceKit/src/Account/CreatePreKeysOperation.swift +++ b/SignalServiceKit/src/Account/CreatePreKeysOperation.swift @@ -26,6 +26,17 @@ public class CreatePreKeysOperation: OWSOperation { if self.identityKeyManager.identityKeyPair() == nil { self.identityKeyManager.generateNewIdentityKey() } + + let signedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord() + signedPreKeyRecord.markAsAcceptedByService() + self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) + self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) + + Logger.debug("done") + self.reportSuccess() + + /* Loki: Original Code + * ================== let identityKey: Data = self.identityKeyManager.identityKeyPair()!.publicKey let signedPreKeyRecord: SignedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord() let preKeyRecords: [PreKeyRecord] = self.primaryStorage.generatePreKeyRecords() @@ -45,5 +56,6 @@ public class CreatePreKeysOperation: OWSOperation { }.catch { error in self.reportError(error) }.retainUntilComplete() + */ } } diff --git a/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift b/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift index 5d928eef7..c883b6b3c 100644 --- a/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift +++ b/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift @@ -36,6 +36,25 @@ public class RefreshPreKeysOperation: OWSOperation { return } + guard self.primaryStorage.currentSignedPrekeyId() == nil else { + Logger.debug("Already have a signed prekey set") + self.reportSuccess() + return + } + + let signedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord() + signedPreKeyRecord.markAsAcceptedByService() + self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) + self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) + + TSPreKeyManager.clearPreKeyUpdateFailureCount() + TSPreKeyManager.clearSignedPreKeyRecords() + + Logger.debug("done") + self.reportSuccess() + + /* Loki: Original Code + * ============= firstly { self.accountServiceClient.getPreKeysCount() }.then(on: DispatchQueue.global()) { preKeysCount -> Promise in @@ -68,6 +87,7 @@ public class RefreshPreKeysOperation: OWSOperation { }.catch { error in self.reportError(error) }.retainUntilComplete() + */ } public override func didSucceed() { diff --git a/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift b/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift index 018fbdab3..a004fdaf2 100644 --- a/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift +++ b/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift @@ -26,7 +26,20 @@ public class RotateSignedPreKeyOperation: OWSOperation { Logger.debug("skipping - not registered") return } + + let signedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord() + signedPreKeyRecord.markAsAcceptedByService() + self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) + self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) + + TSPreKeyManager.clearPreKeyUpdateFailureCount() + TSPreKeyManager.clearSignedPreKeyRecords() + + Logger.debug("done") + self.reportSuccess() + /* Loki: Original Code + * ========= let signedPreKeyRecord: SignedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord() self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) @@ -46,6 +59,7 @@ public class RotateSignedPreKeyOperation: OWSOperation { }.catch { error in self.reportError(error) }.retainUntilComplete() + */ } override public func didFail(error: Error) { diff --git a/SignalServiceKit/src/Loki/Extensions/ECKeyPair.swift b/SignalServiceKit/src/Loki/Extensions/ECKeyPair.swift index cd0d4d88e..d96aa0b06 100644 --- a/SignalServiceKit/src/Loki/Extensions/ECKeyPair.swift +++ b/SignalServiceKit/src/Loki/Extensions/ECKeyPair.swift @@ -7,6 +7,7 @@ public extension ECKeyPair { @objc var hexEncodedPublicKey: String { // Prefixing with "05" is necessary for what seems to be a sort of Signal public key versioning system + // Ref: [NSData prependKeyType] in AxolotKit return "05" + publicKey.map { String(format: "%02hhx", $0) }.joined() } diff --git a/SignalServiceKit/src/Loki/Extensions/OWSPrimaryStorage+Loki.m b/SignalServiceKit/src/Loki/Extensions/OWSPrimaryStorage+Loki.m index 8e7aa84a9..ad27c72c7 100644 --- a/SignalServiceKit/src/Loki/Extensions/OWSPrimaryStorage+Loki.m +++ b/SignalServiceKit/src/Loki/Extensions/OWSPrimaryStorage+Loki.m @@ -4,7 +4,9 @@ #import "OWSDevice.h" #import "OWSIdentityManager.h" #import "TSAccountManager.h" +#import "TSPreKeyManager.h" #import "YapDatabaseConnection+OWS.h" +#import #define LokiPreKeyContactCollection @"LokiPreKeyContactCollection" #define LokiPreKeyBundleCollection @"LokiPreKeyBundleCollection" @@ -53,22 +55,28 @@ # pragma mark - PreKeyBundle - (PreKeyBundle *)generatePreKeyBundleForContact:(NSString *)pubKey { + // Check prekeys to make sure we have them for this function + [TSPreKeyManager checkPreKeys]; + ECKeyPair *_Nullable myKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair]; OWSAssertDebug(myKeyPair); - SignedPreKeyRecord *signedPreKey = [self currentSignedPreKey]; - PreKeyRecord *preKey = [self getPreKeyForContact:pubKey]; + SignedPreKeyRecord *_Nullable signedPreKey = [self currentSignedPreKey]; + if (!signedPreKey) { + OWSFailDebug(@"Signed prekey is null"); + } + PreKeyRecord *preKey = [self getPreKeyForContact:pubKey]; uint32_t registrationId = [[TSAccountManager sharedInstance] getOrGenerateRegistrationId]; PreKeyBundle *bundle = [[PreKeyBundle alloc] initWithRegistrationId:registrationId deviceId:OWSDevicePrimaryDeviceId preKeyId:preKey.Id - preKeyPublic:preKey.keyPair.publicKey - signedPreKeyPublic:signedPreKey.keyPair.publicKey + preKeyPublic:preKey.keyPair.publicKey.prependKeyType + signedPreKeyPublic:signedPreKey.keyPair.publicKey.prependKeyType signedPreKeyId:signedPreKey.Id signedPreKeySignature:signedPreKey.signature - identityKey:myKeyPair.publicKey]; + identityKey:myKeyPair.publicKey.prependKeyType]; return bundle; } diff --git a/SignalServiceKit/src/Loki/Extensions/SSKProtoPrekeyBundleMessage+PreKeyBundle.swift b/SignalServiceKit/src/Loki/Extensions/SSKProtoPrekeyBundleMessage+PreKeyBundle.swift new file mode 100644 index 000000000..38cc82c5b --- /dev/null +++ b/SignalServiceKit/src/Loki/Extensions/SSKProtoPrekeyBundleMessage+PreKeyBundle.swift @@ -0,0 +1,16 @@ +public extension SSKProtoPrekeyBundleMessage { + + @objc public class func builder(fromPreKeyBundle preKeyBundle: PreKeyBundle) -> SSKProtoPrekeyBundleMessageBuilder { + let builder = self.builder() + + builder.setIdentityKey(preKeyBundle.identityKey) + builder.setPrekeyID(UInt32(preKeyBundle.preKeyId)) + builder.setPrekey(preKeyBundle.preKeyPublic) + builder.setSignedKeyID(UInt32(preKeyBundle.signedPreKeyId)) + builder.setSignedKey(preKeyBundle.signedPreKeyPublic) + builder.setSignature(preKeyBundle.signedPreKeySignature) + + return builder + } + +} diff --git a/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.h b/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.h index 432706588..7b7b6c23d 100644 --- a/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.h +++ b/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.h @@ -1,3 +1,4 @@ +#import #import "TSOutgoingMessage.h" NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.m b/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.m index 7047661d4..f72a51f7b 100644 --- a/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.m +++ b/SignalServiceKit/src/Loki/Messages/OWSFriendRequestMessage.m @@ -1,11 +1,24 @@ #import "OWSFriendRequestMessage.h" +#import "OWSPrimaryStorage+Loki.h" +#import "SignalRecipient.h" +#import @implementation OWSFriendRequestMessage -- (SSKProtoContentBuilder *)contentBuilder { - SSKProtoContentBuilder *contentBuilder = super.contentBuilder; +- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient { + SSKProtoContentBuilder *contentBuilder = [super contentBuilder:recipient]; - // TODO: Attach pre-key bundle here + PreKeyBundle *bundle = [[OWSPrimaryStorage sharedManager] generatePreKeyBundleForContact:recipient.recipientId]; + SSKProtoPrekeyBundleMessageBuilder *preKeyBuilder = [SSKProtoPrekeyBundleMessage builderFromPreKeyBundle:bundle]; + + // Build the pre key bundle message + NSError *error; + SSKProtoPrekeyBundleMessage *_Nullable message = [preKeyBuilder buildAndReturnError:&error]; + if (error || !message) { + OWSFailDebug(@"Failed to build preKeyBundle for %@: %@", recipient.recipientId, error); + } else { + [contentBuilder setPrekeyBundleMessage:message]; + } return contentBuilder; } diff --git a/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m b/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m index 632379907..46b010ca7 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m @@ -3,6 +3,8 @@ // #import "OWSEndSessionMessage.h" +#import "OWSPrimaryStorage+Loki.h" +#import "SignalRecipient.h" #import NS_ASSUME_NONNULL_BEGIN @@ -46,10 +48,20 @@ NS_ASSUME_NONNULL_BEGIN return builder; } -- (SSKProtoContentBuilder *)contentBuilder { - SSKProtoContentBuilder *builder = [super contentBuilder]; +- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient { + SSKProtoContentBuilder *builder = [super contentBuilder:recipient]; - // TODO Loki: Attach pre-key bundle here + PreKeyBundle *bundle = [[OWSPrimaryStorage sharedManager] generatePreKeyBundleForContact:recipient.recipientId]; + SSKProtoPrekeyBundleMessageBuilder *preKeyBuilder = [SSKProtoPrekeyBundleMessage builderFromPreKeyBundle:bundle]; + + // Build the pre key bundle message + NSError *error; + SSKProtoPrekeyBundleMessage *_Nullable message = [preKeyBuilder buildAndReturnError:&error]; + if (error || !message) { + OWSFailDebug(@"Failed to build preKeyBundle for %@: %@", recipient.recipientId, error); + } else { + [builder setPrekeyBundleMessage:message]; + } return builder; } diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h index 41e188eec..93adadaba 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h @@ -159,7 +159,7 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { * Intermediate protobuf representation * Subclasses can augment if they want to manipulate the content message before building. */ -- (SSKProtoContentBuilder *)contentBuilder; +- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient; /** * Should this message be synced to the users other registered devices? This is diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index 7accba352..eed46d2b5 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -1113,7 +1113,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt return dataProto; } -- (SSKProtoContentBuilder *)contentBuilder +- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient { return SSKProtoContent.builder; } @@ -1127,7 +1127,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt return nil; } - SSKProtoContentBuilder *contentBuilder = [self contentBuilder]; + SSKProtoContentBuilder *contentBuilder = [self contentBuilder:recipient]; [contentBuilder setDataMessage:dataMessage]; NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error]; if (error || !contentData) { diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 03a315239..4247bf716 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -22,6 +22,7 @@ #import "OWSPrimaryStorage+PreKeyStore.h" #import "OWSPrimaryStorage+SignedPreKeyStore.h" #import "OWSPrimaryStorage+sessionStore.h" +#import "OWSPrimaryStorage+Loki.h" #import "OWSPrimaryStorage.h" #import "OWSRequestFactory.h" #import "OWSUploadOperation.h" @@ -1614,7 +1615,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (canSafelyBeDiscarded) { OWSRaiseException(NoSessionForTransientMessageException, @"No session for transient message."); } + + PreKeyBundle *_Nullable bundle = [[OWSPrimaryStorage sharedManager] getPreKeyBundleForContact:recipientId]; + __block NSException *_Nullable exception; + /** Loki: Original code + * ================== __block dispatch_semaphore_t sema = dispatch_semaphore_create(0); __block PreKeyBundle *_Nullable bundle; __block NSException *_Nullable exception; @@ -1642,6 +1648,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (exception) { @throw exception; } + *============ + */ if (!bundle) { NSString *missingPrekeyBundleException = @"missingPrekeyBundleException";