From 8d814a52107443a02f4a29b032d6c6f3e191dca6 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 2 Aug 2018 13:29:24 -0400 Subject: [PATCH] Code generate Swift wrappers for protocol buffers. --- .../src/Devices/OWSContactsOutputStream.m | 16 ++- .../Devices/OWSVerificationStateSyncMessage.m | 36 +++---- .../Attachments/TSAttachmentPointer.m | 1 + .../Messages/Attachments/TSAttachmentStream.h | 2 +- .../Messages/Attachments/TSAttachmentStream.m | 11 ++- .../DeviceSyncing/OWSOutgoingSyncMessage.m | 2 +- .../DeviceSyncing/OWSSyncContactsMessage.m | 8 +- .../DeviceSyncing/OWSSyncGroupsMessage.m | 9 +- .../OWSSyncGroupsRequestMessage.m | 11 ++- .../src/Messages/Interactions/OWSContact.m | 10 +- ...DisappearingMessagesConfigurationMessage.m | 2 +- .../Interactions/OWSEndSessionMessage.m | 2 +- .../Messages/Interactions/TSOutgoingMessage.h | 2 +- .../Messages/Interactions/TSOutgoingMessage.m | 51 +++++++--- .../Messages/Interactions/TSQuotedMessage.m | 4 +- .../src/Messages/OWSIdentityManager.m | 1 + .../src/Messages/OWSOutgoingCallMessage.m | 6 +- .../src/Messages/OWSProfileKeyMessage.m | 12 ++- SignalServiceKit/src/Protocols/ProtoBuf+OWS.h | 32 ------ SignalServiceKit/src/Protocols/ProtoBuf+OWS.m | 97 ------------------- SignalServiceKit/src/Protocols/ProtoUtils.h | 27 ++++++ SignalServiceKit/src/Protocols/ProtoUtils.m | 94 ++++++++++++++++++ .../src/Security/OWSRecipientIdentity.h | 9 +- .../src/Security/OWSRecipientIdentity.m | 37 +++++++ 24 files changed, 287 insertions(+), 195 deletions(-) delete mode 100644 SignalServiceKit/src/Protocols/ProtoBuf+OWS.h delete mode 100644 SignalServiceKit/src/Protocols/ProtoBuf+OWS.m create mode 100644 SignalServiceKit/src/Protocols/ProtoUtils.h create mode 100644 SignalServiceKit/src/Protocols/ProtoUtils.m diff --git a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m index 4baf91b57..03702a5c5 100644 --- a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m +++ b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m @@ -39,18 +39,14 @@ disappearingMessagesConfiguration:(nullable OWSDisappearingMessagesConfiguration #endif if (recipientIdentity != nil) { - SSKProtoVerifiedBuilder *verifiedBuilder = [SSKProtoVerifiedBuilder new]; - verifiedBuilder.destination = recipientIdentity.recipientId; - verifiedBuilder.identityKey = [recipientIdentity.identityKey prependKeyType]; - verifiedBuilder.state = OWSVerificationStateToProtoState(recipientIdentity.verificationState); - - NSError *error; - SSKProtoVerified *_Nullable verified = [verifiedBuilder buildAndReturnError:&error]; - if (error || !verified) { - OWSFail(@"%@ could not build protobuf: %@", self.logTag, error); + SSKProtoVerified *_Nullable verified = BuildVerifiedProto(recipientIdentity.recipientId, + [recipientIdentity.identityKey prependKeyType], + recipientIdentity.verificationState, + 0); + if (!verified) { + OWSFail(@"%@ could not build protobuf.", self.logTag); return; } - contactBuilder.verified = verified; } diff --git a/SignalServiceKit/src/Devices/OWSVerificationStateSyncMessage.m b/SignalServiceKit/src/Devices/OWSVerificationStateSyncMessage.m index 44a16a930..c668b2171 100644 --- a/SignalServiceKit/src/Devices/OWSVerificationStateSyncMessage.m +++ b/SignalServiceKit/src/Devices/OWSVerificationStateSyncMessage.m @@ -63,24 +63,17 @@ NS_ASSUME_NONNULL_BEGIN // will figure that out on it's own. OWSAssert(self.verificationState != OWSVerificationStateNoLongerVerified); - SSKProtoVerifiedBuilder *verifiedBuilder = [SSKProtoVerifiedBuilder new]; - verifiedBuilder.destination = self.verificationForRecipientId; - verifiedBuilder.identityKey = self.identityKey; - verifiedBuilder.state = OWSVerificationStateToProtoState(self.verificationState); - - OWSAssert(self.paddingBytesLength != 0); - // We add the same amount of padding in the VerificationStateSync message and it's coresponding NullMessage so that // the sync message is indistinguishable from an outgoing Sent transcript corresponding to the NullMessage. We pad // the NullMessage so as to obscure it's content. The sync message (like all sync messages) will be *additionally* // padded by the superclass while being sent. The end result is we send a NullMessage of a non-distinct size, and a // verification sync which is ~1-512 bytes larger then that. - verifiedBuilder.nullMessage = [Cryptography generateRandomBytes:self.paddingBytesLength]; + OWSAssert(self.paddingBytesLength != 0); - NSError *error; - SSKProtoVerified *_Nullable verifiedProto = [verifiedBuilder buildAndReturnError:&error]; - if (error || !verifiedProto) { - OWSFail(@"%@ could not build protobuf: %@", self.logTag, error); + SSKProtoVerified *_Nullable verifiedProto = BuildVerifiedProto( + self.verificationForRecipientId, self.identityKey, self.verificationState, self.paddingBytesLength); + if (!verifiedProto) { + OWSFail(@"%@ could not build protobuf.", self.logTag); return nil; } @@ -98,12 +91,19 @@ NS_ASSUME_NONNULL_BEGIN // will figure that out on it's own. OWSAssert(self.verificationState != OWSVerificationStateNoLongerVerified); - SSKProtoVerifiedBuilder *verifiedBuilder = [SSKProtoVerifiedBuilder new]; - verifiedBuilder.destination = self.verificationForRecipientId; - verifiedBuilder.identityKey = self.identityKey; - verifiedBuilder.state = OWSVerificationStateToProtoState(self.verificationState); - - return [verifiedBuilder build].data.length; + SSKProtoVerified *_Nullable verifiedProto + = BuildVerifiedProto(self.verificationForRecipientId, self.identityKey, self.verificationState, 0); + if (!verifiedProto) { + OWSFail(@"%@ could not build protobuf.", self.logTag); + return 0; + } + NSError *error; + NSData *_Nullable verifiedData = [verifiedProto serializedDataAndReturnError:&error]; + if (error || !verifiedData) { + OWSFail(@"%@ could not serialize protobuf.", self.logTag); + return 0; + } + return verifiedData.length; } @end diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m index ef19ef974..0f1eb84a0 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentPointer.m @@ -3,6 +3,7 @@ // #import "TSAttachmentPointer.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h index bc73c6bce..4a3d7ceff 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h @@ -92,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable SSKProtoAttachmentPointer *)buildProtoForAttachmentId:(nullable NSString *)attachmentId; -- (SSKProtoAttachmentPointer *)buildProto; +- (nullable SSKProtoAttachmentPointer *)buildProto; @end diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index 1094bcd91..c111185ff 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -9,6 +9,7 @@ #import "TSAttachmentPointer.h" #import #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -787,7 +788,7 @@ NS_ASSUME_NONNULL_BEGIN } -- (SSKProtoAttachmentPointer *)buildProto +- (nullable SSKProtoAttachmentPointer *)buildProto { SSKProtoAttachmentPointerBuilder *builder = [SSKProtoAttachmentPointerBuilder new]; @@ -816,7 +817,13 @@ NS_ASSUME_NONNULL_BEGIN } } - return [builder build]; + NSError *error; + SSKProtoAttachmentPointer *_Nullable attachmentProto = [builder buildAndReturnError:&error]; + if (error || !attachmentProto) { + OWSFail(@"%@ could not build protobuf: %@", self.logTag, error); + return nil; + } + return attachmentProto; } @end diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m index b5596ac91..d973b2299 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m @@ -5,7 +5,7 @@ #import "OWSOutgoingSyncMessage.h" #import "Cryptography.h" #import "NSDate+OWS.h" -#import "ProtoBuf+OWS.h" +#import "ProtoUtils.h" #import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m index 4eca88bce..53592f334 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m @@ -56,8 +56,12 @@ NS_ASSUME_NONNULL_BEGIN (unsigned long)self.attachmentIds.count); } - SSKProtoAttachmentPointer *attachmentProto = + SSKProtoAttachmentPointer *_Nullable attachmentProto = [TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject]; + if (!attachmentProto) { + OWSFail(@"%@ could not build protobuf.", self.logTag); + return nil; + } SSKProtoSyncMessageContactsBuilder *contactsBuilder = [SSKProtoSyncMessageContactsBuilder new]; @@ -70,8 +74,8 @@ NS_ASSUME_NONNULL_BEGIN OWSFail(@"%@ could not build protobuf: %@", self.logTag, error); return nil; } + SSKProtoSyncMessageBuilder *syncMessageBuilder = [SSKProtoSyncMessageBuilder new]; [syncMessageBuilder setContacts:contactsProto]; - return syncMessageBuilder; } diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m index a964eb25a..c7bd39091 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m @@ -28,12 +28,17 @@ NS_ASSUME_NONNULL_BEGIN - (nullable SSKProtoSyncMessageBuilder *)syncMessageBuilder { - if (self.attachmentIds.count != 1) { DDLogError(@"expected sync groups message to have exactly one attachment, but found %lu", (unsigned long)self.attachmentIds.count); } - SSKProtoAttachmentPointer *attachmentProto = [TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject]; + + SSKProtoAttachmentPointer *_Nullable attachmentProto = + [TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject]; + if (!attachmentProto) { + OWSFail(@"%@ could not build protobuf.", self.logTag); + return nil; + } SSKProtoSyncMessageGroupsBuilder *groupsBuilder = [SSKProtoSyncMessageGroupsBuilder new]; diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsRequestMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsRequestMessage.m index f92d4e15f..f51b4f040 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsRequestMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsRequestMessage.m @@ -57,15 +57,22 @@ NS_ASSUME_NONNULL_BEGIN return YES; } -- (SSKProtoDataMessageBuilder *)dataMessageBuilder +- (nullable SSKProtoDataMessageBuilder *)dataMessageBuilder { SSKProtoGroupContextBuilder *groupContextBuilder = [SSKProtoGroupContextBuilder new]; [groupContextBuilder setType:SSKProtoGroupContextTypeRequestInfo]; [groupContextBuilder setId:self.groupId]; + NSError *error; + SSKProtoGroupContext *_Nullable groupContextProto = [groupContextBuilder buildAndReturnError:&error]; + if (error || !groupContextProto) { + OWSFail(@"%@ could not build protobuf: %@", self.logTag, error); + return nil; + } + SSKProtoDataMessageBuilder *builder = [SSKProtoDataMessageBuilder new]; [builder setTimestamp:self.timestamp]; - [builder setGroupBuilder:groupContextBuilder]; + [builder setGroup:groupContextProto]; return builder; } diff --git a/SignalServiceKit/src/Messages/Interactions/OWSContact.m b/SignalServiceKit/src/Messages/Interactions/OWSContact.m index 13f67c3b1..e7b89d9a5 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSContact.m +++ b/SignalServiceKit/src/Messages/Interactions/OWSContact.m @@ -899,10 +899,16 @@ NSString *NSStringForContactAddressType(OWSContactAddressType value) } if (contact.avatarAttachmentId != nil) { + SSKProtoAttachmentPointer *_Nullable attachmentProto = + [TSAttachmentStream buildProtoForAttachmentId:contact.avatarAttachmentId]; + if (!attachmentProto) { + OWSFail(@"%@ could not build protobuf: %@", self.logTag, error); + return nil; + } + SSKProtoDataMessageContactAvatarBuilder *avatarBuilder = [SSKProtoDataMessageContactAvatarBuilder new]; - avatarBuilder.avatar = - [TSAttachmentStream buildProtoForAttachmentId:contact.avatarAttachmentId]; + avatarBuilder.avatar = attachmentProto; SSKProtoDataMessageContactAvatar *_Nullable avatarProto = [avatarBuilder buildAndReturnError:&error]; if (error || !avatarProto) { OWSFail(@"%@ could not build protobuf: %@", self.logTag, error); diff --git a/SignalServiceKit/src/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m b/SignalServiceKit/src/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m index d0ea4d17d..c52cf7374 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN } -- (SSKProtoDataMessageBuilder *)dataMessageBuilder +- (nullable SSKProtoDataMessageBuilder *)dataMessageBuilder { SSKProtoDataMessageBuilder *dataMessageBuilder = [super dataMessageBuilder]; [dataMessageBuilder setTimestamp:self.timestamp]; diff --git a/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m b/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m index 8dab2fccc..c996ee4c8 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/OWSEndSessionMessage.m @@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN return NO; } -- (SSKProtoDataMessageBuilder *)dataMessageBuilder +- (nullable SSKProtoDataMessageBuilder *)dataMessageBuilder { SSKProtoDataMessageBuilder *builder = [super dataMessageBuilder]; [builder setTimestamp:self.timestamp]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h index 62f254bf1..94ba60837 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h @@ -136,7 +136,7 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { * Intermediate protobuf representation * Subclasses can augment if they want to manipulate the data message before building. */ -- (SSKProtoDataMessageBuilder *)dataMessageBuilder; +- (nullable SSKProtoDataMessageBuilder *)dataMessageBuilder; /** * 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 12c9b1abe..15cfc7bc2 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -9,7 +9,7 @@ #import "OWSMessageSender.h" #import "OWSOutgoingSyncMessage.h" #import "OWSPrimaryStorage.h" -#import "ProtoBuf+OWS.h" +#import "ProtoUtils.h" #import "SignalRecipient.h" #import "TSAccountManager.h" #import "TSAttachmentStream.h" @@ -802,7 +802,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt } #pragma mark - -- (SSKProtoDataMessageBuilder *)dataMessageBuilder +- (nullable SSKProtoDataMessageBuilder *)dataMessageBuilder { TSThread *thread = self.thread; OWSAssert(thread); @@ -810,7 +810,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt SSKProtoDataMessageBuilder *builder = [SSKProtoDataMessageBuilder new]; [builder setTimestamp:self.timestamp]; - if ([self.body lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) { [builder setBody:self.body]; } else { @@ -840,10 +839,16 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt case TSGroupMessageNew: { if (gThread.groupModel.groupImage != nil && self.attachmentIds.count == 1) { attachmentWasGroupAvatar = YES; - [groupBuilder setAvatar:[TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject]]; + SSKProtoAttachmentPointer *_Nullable attachmentProto = + [TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject]; + if (!attachmentProto) { + OWSFail(@"%@ could not build protobuf.", self.logTag); + return nil; + } + [groupBuilder setAvatar:attachmentProto]; } - [groupBuilder setMembersArray:gThread.groupModel.groupMemberIds]; + [groupBuilder setMembers:gThread.groupModel.groupMemberIds]; [groupBuilder setName:gThread.groupModel.groupName]; [groupBuilder setType:SSKProtoGroupContextTypeUpdate]; break; @@ -853,22 +858,41 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt break; } [groupBuilder setId:gThread.groupModel.groupId]; - [builder setGroup:groupBuilder.build]; + + NSError *error; + SSKProtoGroupContext *_Nullable groupContextProto = [groupBuilder buildAndReturnError:&error]; + if (error || !groupContextProto) { + OWSFail(@"%@ could not build protobuf: %@.", self.logTag, error); + return nil; + } + [builder setGroup:groupContextProto]; } // Message Attachments if (!attachmentWasGroupAvatar) { NSMutableArray *attachments = [NSMutableArray new]; for (NSString *attachmentId in self.attachmentIds) { - [attachments addObject:[TSAttachmentStream buildProtoForAttachmentId:attachmentId]]; + SSKProtoAttachmentPointer *_Nullable attachmentProto = + [TSAttachmentStream buildProtoForAttachmentId:attachmentId]; + if (!attachmentProto) { + OWSFail(@"%@ could not build protobuf.", self.logTag); + return nil; + } + [attachments addObject:attachmentProto]; } - [builder setAttachmentsArray:attachments]; + [builder setAttachments:attachments]; } // Quoted Reply SSKProtoDataMessageQuoteBuilder *_Nullable quotedMessageBuilder = self.quotedMessageBuilder; if (quotedMessageBuilder) { - [builder setQuoteBuilder:quotedMessageBuilder]; + NSError *error; + SSKProtoDataMessageQuote *_Nullable quoteProto = [quotedMessageBuilder buildAndReturnError:&error]; + if (error || !quoteProto) { + OWSFail(@"%@ could not build protobuf: %@.", self.logTag, error); + return nil; + } + [builder setQuote:quoteProto]; } // Contact Share @@ -941,8 +965,13 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt - (nullable SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId { OWSAssert(self.thread); - SSKProtoDataMessageBuilder *builder = [self dataMessageBuilder]; - [builder addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId]; + SSKProtoDataMessageBuilder *_Nullable builder = [self dataMessageBuilder]; + if (!builder) { + OWSFail(@"%@ could not build protobuf.", self.logTag); + return nil; + } + + [ProtoUtils addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId dataMessageBuilder:builder]; NSError *error; SSKProtoDataMessage *_Nullable dataProto = [builder buildAndReturnError:&error]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m index 525c73564..7fda9969d 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m @@ -115,13 +115,13 @@ NS_ASSUME_NONNULL_BEGIN SSKProtoDataMessageQuote *quoteProto = [dataMessage quote]; - if (![quoteProto hasId] || [quoteProto id] == 0) { + if (quoteProto.id == 0) { OWSFail(@"%@ quoted message missing id", self.logTag); return nil; } uint64_t timestamp = [quoteProto id]; - if (![quoteProto hasAuthor] || [quoteProto author].length == 0) { + if (quoteProto.author.length == 0) { OWSFail(@"%@ quoted message missing author", self.logTag); return nil; } diff --git a/SignalServiceKit/src/Messages/OWSIdentityManager.m b/SignalServiceKit/src/Messages/OWSIdentityManager.m index 728b5742a..827ff161c 100644 --- a/SignalServiceKit/src/Messages/OWSIdentityManager.m +++ b/SignalServiceKit/src/Messages/OWSIdentityManager.m @@ -26,6 +26,7 @@ #import "YapDatabaseTransaction+OWS.h" #import #import +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m b/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m index c7c5fe5b9..d907c19cd 100644 --- a/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m +++ b/SignalServiceKit/src/Messages/OWSOutgoingCallMessage.m @@ -9,7 +9,7 @@ #import "OWSCallHangupMessage.h" #import "OWSCallIceUpdateMessage.h" #import "OWSCallOfferMessage.h" -#import "ProtoBuf+OWS.h" +#import "ProtoUtils.h" #import "SignalRecipient.h" #import "TSContactThread.h" #import @@ -193,8 +193,8 @@ NS_ASSUME_NONNULL_BEGIN [builder setBusy:proto]; } - [builder addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId]; - + [ProtoUtils addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId callMessageBuilder:builder]; + NSError *error; SSKProtoCallMessage *_Nullable result = [builder buildAndReturnError:&error]; if (error || !result) { diff --git a/SignalServiceKit/src/Messages/OWSProfileKeyMessage.m b/SignalServiceKit/src/Messages/OWSProfileKeyMessage.m index 291fc3a1b..b40652dc8 100644 --- a/SignalServiceKit/src/Messages/OWSProfileKeyMessage.m +++ b/SignalServiceKit/src/Messages/OWSProfileKeyMessage.m @@ -4,7 +4,7 @@ #import "OWSProfileKeyMessage.h" #import "ProfileManagerProtocol.h" -#import "ProtoBuf+OWS.h" +#import "ProtoUtils.h" #import "TextSecureKitEnv.h" #import @@ -44,10 +44,14 @@ NS_ASSUME_NONNULL_BEGIN - (nullable SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId { OWSAssert(self.thread); - - SSKProtoDataMessageBuilder *builder = [self dataMessageBuilder]; + + SSKProtoDataMessageBuilder *_Nullable builder = [self dataMessageBuilder]; + if (!builder) { + OWSFail(@"%@ could not build protobuf.", self.logTag); + return nil; + } [builder setTimestamp:self.timestamp]; - [builder addLocalProfileKey]; + [ProtoUtils addLocalProfileKeyToDataMessageBuilder:builder]; [builder setFlags:SSKProtoDataMessageFlagsProfileKeyUpdate]; if (recipientId.length > 0) { diff --git a/SignalServiceKit/src/Protocols/ProtoBuf+OWS.h b/SignalServiceKit/src/Protocols/ProtoBuf+OWS.h deleted file mode 100644 index c4f77eabd..000000000 --- a/SignalServiceKit/src/Protocols/ProtoBuf+OWS.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import "SignalServiceKit-Swift.h" - -NS_ASSUME_NONNULL_BEGIN - -@class TSThread; - -//@interface PBGeneratedMessageBuilder (OWS) -// -//@end - -#pragma mark - - -@interface SSKProtoDataMessageBuilder (OWS) - -- (void)addLocalProfileKeyIfNecessary:(TSThread *)thread recipientId:(NSString *_Nullable)recipientId; -- (void)addLocalProfileKey; - -@end - -#pragma mark - - -@interface SSKProtoCallMessageBuilder (OWS) - -- (void)addLocalProfileKeyIfNecessary:(TSThread *)thread recipientId:(NSString *)recipientId; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Protocols/ProtoBuf+OWS.m b/SignalServiceKit/src/Protocols/ProtoBuf+OWS.m deleted file mode 100644 index 0459a1219..000000000 --- a/SignalServiceKit/src/Protocols/ProtoBuf+OWS.m +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import "ProtoBuf+OWS.h" -#import "Cryptography.h" -#import "ProfileManagerProtocol.h" -#import "TSThread.h" -#import "TextSecureKitEnv.h" - -NS_ASSUME_NONNULL_BEGIN - -//@implementation PBGeneratedMessageBuilder (OWS) -// -//- (BOOL)shouldMessageHaveLocalProfileKey:(TSThread *)thread recipientId:(NSString *_Nullable)recipientId -//{ -// OWSAssert(thread); -// -// id profileManager = [TextSecureKitEnv sharedEnv].profileManager; -// -// // For 1:1 threads, we want to include the profile key IFF the -// // contact is in the whitelist. -// // -// // For Group threads, we want to include the profile key IFF the -// // recipient OR the group is in the whitelist. -// if (recipientId.length > 0 && [profileManager isUserInProfileWhitelist:recipientId]) { -// return YES; -// } else if ([profileManager isThreadInProfileWhitelist:thread]) { -// return YES; -// } -// -// return NO; -//} -// -//- (OWSAES256Key *)localProfileKey -//{ -// id profileManager = [TextSecureKitEnv sharedEnv].profileManager; -// return profileManager.localProfileKey; -//} -// -//@end - -#pragma mark - - -@implementation SSKProtoDataMessageBuilder (OWS) - -- (void)addLocalProfileKeyIfNecessary:(TSThread *)thread recipientId:(NSString *_Nullable)recipientId -{ - OWSAssert(thread); - - if ([self shouldMessageHaveLocalProfileKey:thread recipientId:recipientId]) { - [self setProfileKey:self.localProfileKey.keyData]; - - if (recipientId.length > 0) { - // Once we've shared our profile key with a user (perhaps due to being - // a member of a whitelisted group), make sure they're whitelisted. - id profileManager = [TextSecureKitEnv sharedEnv].profileManager; - // FIXME PERF avoid this dispatch. It's going to happen for *each* recipient in a group message. - dispatch_async(dispatch_get_main_queue(), ^{ - [profileManager addUserToProfileWhitelist:recipientId]; - }); - } - } -} - -- (void)addLocalProfileKey -{ - [self setProfileKey:self.localProfileKey.keyData]; -} - -@end - -#pragma mark - - -@implementation SSKProtoCallMessageBuilder (OWS) - -- (void)addLocalProfileKeyIfNecessary:(TSThread *)thread recipientId:(NSString *)recipientId -{ - OWSAssert(thread); - OWSAssert(recipientId.length > 0); - - if ([self shouldMessageHaveLocalProfileKey:thread recipientId:recipientId]) { - [self setProfileKey:self.localProfileKey.keyData]; - - // Once we've shared our profile key with a user (perhaps due to being - // a member of a whitelisted group), make sure they're whitelisted. - id profileManager = [TextSecureKitEnv sharedEnv].profileManager; - // FIXME PERF avoid this dispatch. It's going to happen for *each* recipient in a group message. - dispatch_async(dispatch_get_main_queue(), ^{ - [profileManager addUserToProfileWhitelist:recipientId]; - }); - } -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Protocols/ProtoUtils.h b/SignalServiceKit/src/Protocols/ProtoUtils.h new file mode 100644 index 000000000..82c257338 --- /dev/null +++ b/SignalServiceKit/src/Protocols/ProtoUtils.h @@ -0,0 +1,27 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +@class SSKProtoCallMessageBuilder; +@class SSKProtoDataMessageBuilder; +@class TSThread; + +@interface ProtoUtils : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (void)addLocalProfileKeyIfNecessary:(TSThread *)thread + recipientId:(NSString *_Nullable)recipientId + dataMessageBuilder:(SSKProtoDataMessageBuilder *)dataMessageBuilder; + ++ (void)addLocalProfileKeyToDataMessageBuilder:(SSKProtoDataMessageBuilder *)dataMessageBuilder; + ++ (void)addLocalProfileKeyIfNecessary:(TSThread *)thread + recipientId:(NSString *)recipientId + callMessageBuilder:(SSKProtoCallMessageBuilder *)callMessageBuilder; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Protocols/ProtoUtils.m b/SignalServiceKit/src/Protocols/ProtoUtils.m new file mode 100644 index 000000000..df34a1e73 --- /dev/null +++ b/SignalServiceKit/src/Protocols/ProtoUtils.m @@ -0,0 +1,94 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "ProtoUtils.h" +#import "Cryptography.h" +#import "ProfileManagerProtocol.h" +#import "TSThread.h" +#import "TextSecureKitEnv.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation ProtoUtils + ++ (BOOL)shouldMessageHaveLocalProfileKey:(TSThread *)thread recipientId:(NSString *_Nullable)recipientId +{ + OWSAssert(thread); + + id profileManager = [TextSecureKitEnv sharedEnv].profileManager; + + // For 1:1 threads, we want to include the profile key IFF the + // contact is in the whitelist. + // + // For Group threads, we want to include the profile key IFF the + // recipient OR the group is in the whitelist. + if (recipientId.length > 0 && [profileManager isUserInProfileWhitelist:recipientId]) { + return YES; + } else if ([profileManager isThreadInProfileWhitelist:thread]) { + return YES; + } + + return NO; +} + ++ (OWSAES256Key *)localProfileKey +{ + id profileManager = [TextSecureKitEnv sharedEnv].profileManager; + return profileManager.localProfileKey; +} + ++ (void)addLocalProfileKeyIfNecessary:(TSThread *)thread + recipientId:(NSString *_Nullable)recipientId + dataMessageBuilder:(SSKProtoDataMessageBuilder *)dataMessageBuilder +{ + OWSAssert(thread); + OWSAssert(dataMessageBuilder); + + if ([self shouldMessageHaveLocalProfileKey:thread recipientId:recipientId]) { + [dataMessageBuilder setProfileKey:self.localProfileKey.keyData]; + + if (recipientId.length > 0) { + // Once we've shared our profile key with a user (perhaps due to being + // a member of a whitelisted group), make sure they're whitelisted. + id profileManager = [TextSecureKitEnv sharedEnv].profileManager; + // FIXME PERF avoid this dispatch. It's going to happen for *each* recipient in a group message. + dispatch_async(dispatch_get_main_queue(), ^{ + [profileManager addUserToProfileWhitelist:recipientId]; + }); + } + } +} + ++ (void)addLocalProfileKeyToDataMessageBuilder:(SSKProtoDataMessageBuilder *)dataMessageBuilder +{ + OWSAssert(dataMessageBuilder); + + [dataMessageBuilder setProfileKey:self.localProfileKey.keyData]; +} + ++ (void)addLocalProfileKeyIfNecessary:(TSThread *)thread + recipientId:(NSString *)recipientId + callMessageBuilder:(SSKProtoCallMessageBuilder *)callMessageBuilder +{ + OWSAssert(thread); + OWSAssert(recipientId.length > 0); + OWSAssert(callMessageBuilder); + + if ([self shouldMessageHaveLocalProfileKey:thread recipientId:recipientId]) { + [callMessageBuilder setProfileKey:self.localProfileKey.keyData]; + + // Once we've shared our profile key with a user (perhaps due to being + // a member of a whitelisted group), make sure they're whitelisted. + id profileManager = [TextSecureKitEnv sharedEnv].profileManager; + // FIXME PERF avoid this dispatch. It's going to happen for *each* recipient in a group message. + dispatch_async(dispatch_get_main_queue(), ^{ + [profileManager addUserToProfileWhitelist:recipientId]; + }); + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Security/OWSRecipientIdentity.h b/SignalServiceKit/src/Security/OWSRecipientIdentity.h index e05112828..57408cae6 100644 --- a/SignalServiceKit/src/Security/OWSRecipientIdentity.h +++ b/SignalServiceKit/src/Security/OWSRecipientIdentity.h @@ -2,8 +2,6 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -//#import -#import "SignalServiceKit-Swift.h" #import "TSYapDatabaseObject.h" NS_ASSUME_NONNULL_BEGIN @@ -14,8 +12,13 @@ typedef NS_ENUM(NSUInteger, OWSVerificationState) { OWSVerificationStateNoLongerVerified, }; +@class SSKProtoVerified; + NSString *OWSVerificationStateToString(OWSVerificationState verificationState); -SSKProtoVerifiedState OWSVerificationStateToProtoState(OWSVerificationState verificationState); +SSKProtoVerified *_Nullable BuildVerifiedProto(NSString *destinationRecipientId, + NSData *identityKey, + OWSVerificationState verificationState, + NSUInteger paddingBytesLength); @interface OWSRecipientIdentity : TSYapDatabaseObject diff --git a/SignalServiceKit/src/Security/OWSRecipientIdentity.m b/SignalServiceKit/src/Security/OWSRecipientIdentity.m index 34f1d27fb..3c3ccf244 100644 --- a/SignalServiceKit/src/Security/OWSRecipientIdentity.m +++ b/SignalServiceKit/src/Security/OWSRecipientIdentity.m @@ -3,8 +3,11 @@ // #import "OWSRecipientIdentity.h" +#import "Cryptography.h" +#import "OWSIdentityManager.h" #import "OWSPrimaryStorage+SessionStore.h" #import "OWSPrimaryStorage.h" +#import #import NS_ASSUME_NONNULL_BEGIN @@ -33,6 +36,40 @@ SSKProtoVerifiedState OWSVerificationStateToProtoState(OWSVerificationState veri } } +SSKProtoVerified *_Nullable BuildVerifiedProto(NSString *destinationRecipientId, + NSData *identityKey, + OWSVerificationState verificationState, + NSUInteger paddingBytesLength) +{ + OWSCAssert(identityKey.length == kIdentityKeyLength); + OWSCAssert(destinationRecipientId.length > 0); + // we only sync user's marking as un/verified. Never sync the conflicted state, the sibling device + // will figure that out on it's own. + OWSCAssert(verificationState != OWSVerificationStateNoLongerVerified); + + SSKProtoVerifiedBuilder *verifiedBuilder = [SSKProtoVerifiedBuilder new]; + verifiedBuilder.destination = destinationRecipientId; + verifiedBuilder.identityKey = identityKey; + verifiedBuilder.state = OWSVerificationStateToProtoState(verificationState); + + if (paddingBytesLength > 0) { + // We add the same amount of padding in the VerificationStateSync message and it's coresponding NullMessage so + // that the sync message is indistinguishable from an outgoing Sent transcript corresponding to the NullMessage. + // We pad the NullMessage so as to obscure it's content. The sync message (like all sync messages) will be + // *additionally* padded by the superclass while being sent. The end result is we send a NullMessage of a + // non-distinct size, and a verification sync which is ~1-512 bytes larger then that. + verifiedBuilder.nullMessage = [Cryptography generateRandomBytes:paddingBytesLength]; + } + + NSError *error; + SSKProtoVerified *_Nullable verifiedProto = [verifiedBuilder buildAndReturnError:&error]; + if (error || !verifiedProto) { + OWSCFail(@"%@ could not build protobuf: %@", @"[BuildVerifiedProto]", error); + return nil; + } + return verifiedProto; +} + @interface OWSRecipientIdentity () @property (atomic) OWSVerificationState verificationState;