From 48b3f498a99f4143d5960e3af7f4795eb3064073 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 21 Jun 2017 20:19:23 -0400 Subject: [PATCH] WIP: adapt to verification proto changes // FREEBIE --- src/Devices/OWSVerificationStateSyncMessage.h | 13 +- src/Devices/OWSVerificationStateSyncMessage.m | 144 +++++++++++------- src/Messages/OWSIdentityManager.h | 4 +- src/Messages/OWSIdentityManager.m | 142 ++++++++--------- src/Messages/TSMessagesManager.m | 10 +- 5 files changed, 173 insertions(+), 140 deletions(-) diff --git a/src/Devices/OWSVerificationStateSyncMessage.h b/src/Devices/OWSVerificationStateSyncMessage.h index 1cb7040d0..f485ab525 100644 --- a/src/Devices/OWSVerificationStateSyncMessage.h +++ b/src/Devices/OWSVerificationStateSyncMessage.h @@ -9,12 +9,15 @@ NS_ASSUME_NONNULL_BEGIN @interface OWSVerificationStateSyncMessage : OWSOutgoingSyncMessage -- (void)addVerificationState:(OWSVerificationState)verificationState - identityKey:(NSData *)identityKey - recipientId:(NSString *)recipientId; +- (instancetype)initWithVerificationState:(OWSVerificationState)verificationState + identityKey:(NSData *)identityKey + verificationForRecipientId:(NSString *)recipientId; -// Returns the list of recipient ids referenced in this message. -- (NSArray *)recipientIds; +//// Returns the list of recipient ids referenced in this message. +//- (NSArray *)recipientIds; + +// This is a clunky name, but we want to differentiate it from `recipientIdentifier` inherited from `TSOutgoingMessage` +@property (nonatomic, readonly) NSString *verificationForRecipientId; @end diff --git a/src/Devices/OWSVerificationStateSyncMessage.m b/src/Devices/OWSVerificationStateSyncMessage.m index a3d2c8900..e5d459e8d 100644 --- a/src/Devices/OWSVerificationStateSyncMessage.m +++ b/src/Devices/OWSVerificationStateSyncMessage.m @@ -9,99 +9,125 @@ NS_ASSUME_NONNULL_BEGIN -@interface OWSVerificationStateTuple : NSObject - -@property (nonatomic) OWSVerificationState verificationState; -@property (nonatomic) NSData *identityKey; -@property (nonatomic) NSString *recipientId; - -@end - -#pragma mark - - -@implementation OWSVerificationStateTuple - -@end +//@interface OWSVerificationStateTuple : NSObject +// +//@property (nonatomic) OWSVerificationState verificationState; +//@property (nonatomic) NSData *identityKey; +//@property (nonatomic) NSString *recipientId; +// +//@end +// +//#pragma mark - +// +//@implementation OWSVerificationStateTuple +// +//@end #pragma mark - @interface OWSVerificationStateSyncMessage () -@property (nonatomic, readonly) NSMutableArray *tuples; +//@property (nonatomic, readonly) NSMutableArray *tuples; +@property (nonatomic, readonly) OWSVerificationState verificationState; +@property (nonatomic, readonly) NSData *identityKey; @end #pragma mark - @implementation OWSVerificationStateSyncMessage +// +//- (instancetype)init +//{ +// self = [super init]; +// if (!self) { +// return self; +// } +// +// _tuples = [NSMutableArray new]; +// +// return self; +//} -- (instancetype)init +- (instancetype)initWithVerificationState:(OWSVerificationState)verificationState + identityKey:(NSData *)identityKey + verificationForRecipientId:(NSString *)verificationForRecipientId { + + OWSAssert(identityKey.length == kIdentityKeyLength); + OWSAssert(verificationForRecipientId.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. + OWSAssert(verificationState != OWSVerificationStateNoLongerVerified); + self = [super init]; if (!self) { return self; } - - _tuples = [NSMutableArray new]; - - return self; -} -- (void)addVerificationState:(OWSVerificationState)verificationState - identityKey:(NSData *)identityKey - recipientId:(NSString *)recipientId -{ - OWSAssert(identityKey.length == kIdentityKeyLength); - OWSAssert(recipientId.length > 0); - OWSAssert(self.tuples); - - OWSVerificationStateTuple *tuple = [OWSVerificationStateTuple new]; - tuple.verificationState = verificationState; - tuple.identityKey = identityKey; - tuple.recipientId = recipientId; - [self.tuples addObject:tuple]; + _verificationState = verificationState; + _identityKey = identityKey; + _verificationForRecipientId = verificationForRecipientId; + + return self; } - (OWSSignalServiceProtosSyncMessage *)buildSyncMessage { - OWSAssert(self.tuples.count > 0); - + // OWSAssert(self.tuples.count > 0); + OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new]; - for (OWSVerificationStateTuple *tuple in self.tuples) { - OWSSignalServiceProtosSyncMessageVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosSyncMessageVerifiedBuilder new]; - verifiedBuilder.destination = tuple.recipientId; - verifiedBuilder.identityKey = tuple.identityKey; - switch (tuple.verificationState) { + + // for (OWSVerificationStateTuple *tuple in self.tuples) { + // OWSSignalServiceProtosVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosVerifiedBuilder new]; + // verifiedBuilder.destination = tuple.recipientId; + // verifiedBuilder.identityKey = tuple.identityKey; + // switch (tuple.verificationState) { + // case OWSVerificationStateDefault: + // verifiedBuilder.state = OWSSignalServiceProtosVerifiedStateDefault; + // break; + // case OWSVerificationStateVerified: + // verifiedBuilder.state = OWSSignalServiceProtosVerifiedStateVerified; + // break; + // case OWSVerificationStateNoLongerVerified: + // verifiedBuilder.state = OWSSignalServiceProtosVerifiedStateUnverified; + // break; + // } + // [syncMessageBuilder addVerified:[verifiedBuilder build]]; + // } + // + + OWSSignalServiceProtosVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosVerifiedBuilder new]; + verifiedBuilder.destination = self.verificationForRecipientId; + verifiedBuilder.identityKey = self.identityKey; + verifiedBuilder.state = ^{ + switch (self.verificationState) { case OWSVerificationStateDefault: - verifiedBuilder.state = OWSSignalServiceProtosSyncMessageVerifiedStateDefault; - break; + return OWSSignalServiceProtosVerifiedStateDefault; case OWSVerificationStateVerified: - verifiedBuilder.state = OWSSignalServiceProtosSyncMessageVerifiedStateVerified; - break; + return OWSSignalServiceProtosVerifiedStateVerified; case OWSVerificationStateNoLongerVerified: - verifiedBuilder.state = OWSSignalServiceProtosSyncMessageVerifiedStateUnverified; - break; + return OWSSignalServiceProtosVerifiedStateUnverified; } - [syncMessageBuilder addVerified:[verifiedBuilder build]]; - } + }(); // Add 1-512 bytes of random padding bytes. size_t paddingLengthBytes = arc4random_uniform(512) + 1; - [syncMessageBuilder setPadding:[Cryptography generateRandomBytes:paddingLengthBytes]]; + syncMessageBuilder.padding = [Cryptography generateRandomBytes:paddingLengthBytes]; return [syncMessageBuilder build]; } -- (NSArray *)recipientIds -{ - NSMutableArray *result = [NSMutableArray new]; - for (OWSVerificationStateTuple *tuple in self.tuples) { - OWSAssert(tuple.recipientId.length > 0); - [result addObject:tuple.recipientId]; - } - - return [result copy]; -} +//- (NSArray *)recipientIds +//{ +// NSMutableArray *result = [NSMutableArray new]; +// for (OWSVerificationStateTuple *tuple in self.tuples) { +// OWSAssert(tuple.recipientId.length > 0); +// [result addObject:tuple.recipientId]; +// } +// +// return [result copy]; +//} @end diff --git a/src/Messages/OWSIdentityManager.h b/src/Messages/OWSIdentityManager.h index e22f06975..3ec904518 100644 --- a/src/Messages/OWSIdentityManager.h +++ b/src/Messages/OWSIdentityManager.h @@ -17,7 +17,7 @@ extern NSString *const kNSNotificationName_IdentityStateDidChange; extern const NSUInteger kIdentityKeyLength; @class OWSRecipientIdentity; -@class OWSSignalServiceProtosSyncMessageVerified; +@class OWSSignalServiceProtosVerified; // This class can be safely accessed and used from any thread. @interface OWSIdentityManager : NSObject @@ -49,7 +49,7 @@ extern const NSUInteger kIdentityKeyLength; // Will try to send a sync message with all verification states. - (void)syncAllVerificationStates; -- (void)processIncomingSyncMessage:(NSArray *)verifieds; +- (void)processIncomingSyncMessage:(OWSSignalServiceProtosVerified *)verified; @end diff --git a/src/Messages/OWSIdentityManager.m b/src/Messages/OWSIdentityManager.m index 643494797..24e600848 100644 --- a/src/Messages/OWSIdentityManager.m +++ b/src/Messages/OWSIdentityManager.m @@ -455,7 +455,7 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa }]; }]; - OWSVerificationStateSyncMessage *message = [OWSVerificationStateSyncMessage new]; + NSMutableArray *messages = [NSMutableArray new]; for (NSString *recipientId in recipientIds) { OWSRecipientIdentity *recipientIdentity = [OWSRecipientIdentity fetchObjectWithUniqueID:recipientId]; if (!recipientIdentity) { @@ -483,13 +483,17 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa recipientId); continue; } - [message addVerificationState:recipientIdentity.verificationState - identityKey:identityKey - recipientId:recipientId]; + OWSVerificationStateSyncMessage *message = [[OWSVerificationStateSyncMessage alloc] + initWithVerificationState:recipientIdentity.verificationState + identityKey:identityKey + verificationForRecipientId:recipientIdentity.recipientId]; + [messages addObject:message]; } - if (message.recipientIds.count > 0) { + if (messages.count > 0) { dispatch_async(dispatch_get_main_queue(), ^{ - [self sendSyncVerificationStateMessage:message]; + for (OWSVerificationStateSyncMessage *message in messages) { + [self sendSyncVerificationStateMessage:message]; + } }); } } @@ -501,8 +505,8 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @synchronized(self) { - OWSVerificationStateSyncMessage *message = - [OWSVerificationStateSyncMessage new]; + + NSMutableArray *messages = [NSMutableArray new]; [OWSRecipientIdentity enumerateCollectionObjectsUsingBlock:^(OWSRecipientIdentity *recipientIdentity, BOOL *stop) { OWSAssert(recipientIdentity); OWSAssert(recipientIdentity.recipientId.length > 0); @@ -523,13 +527,17 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa return; } - [message addVerificationState:recipientIdentity.verificationState - identityKey:identityKey - recipientId:recipientIdentity.recipientId]; + OWSVerificationStateSyncMessage *message = [[OWSVerificationStateSyncMessage alloc] + initWithVerificationState:recipientIdentity.verificationState + identityKey:identityKey + verificationForRecipientId:recipientIdentity.recipientId]; + [messages addObject:message]; }]; - if (message.recipientIds.count > 0) { + if (messages.count > 0) { dispatch_async(dispatch_get_main_queue(), ^{ - [self sendSyncVerificationStateMessage:message]; + for (OWSVerificationStateSyncMessage *message in messages) { + [self sendSyncVerificationStateMessage:message]; + } }); } } @@ -539,7 +547,7 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa - (void)sendSyncVerificationStateMessage:(OWSVerificationStateSyncMessage *)message { OWSAssert(message); - OWSAssert(message.recipientIds.count > 0); + OWSAssert(message.verificationForRecipientId.length > 0); OWSAssert([NSThread isMainThread]); [self.messageSender sendMessage:message @@ -547,7 +555,7 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa DDLogInfo(@"%@ Successfully sent verification state sync message", self.tag); // Record that this verification state was successfully synced. - [self clearSyncMessageForRecipientIds:message.recipientIds]; + [self clearSyncMessageForRecipientId:message.verificationForRecipientId]; } failure:^(NSError *error) { DDLogError(@"%@ Failed to send verification state sync message with error: %@", self.tag, error); @@ -557,66 +565,62 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa - (void)clearSyncMessageForRecipientId:(NSString *)recipientId { OWSAssert(recipientId.length > 0); - - [self clearSyncMessageForRecipientIds:@[recipientId]]; + // + // [self clearSyncMessageForRecipientIds:@[recipientId]]; + //} + // + //- (void)clearSyncMessageForRecipientIds:(NSArray *)recipientIds + //{ + // OWSAssert(recipientIds.count > 0); + // + // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + // @synchronized(self) + // { + // for (NSString *recipientId in recipientIds) { + [self.storageManager removeObjectForKey:recipientId + inCollection:OWSIdentityManager_QueuedVerificationStateSyncMessages]; + // } + // } + // }); } -- (void)clearSyncMessageForRecipientIds:(NSArray *)recipientIds +- (void)processIncomingSyncMessage:(OWSSignalServiceProtosVerified *)verified { - OWSAssert(recipientIds.count > 0); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - @synchronized(self) - { - for (NSString *recipientId in recipientIds) { - [self.storageManager removeObjectForKey:recipientId - inCollection:OWSIdentityManager_QueuedVerificationStateSyncMessages]; - } - } - }); -} - -- (void)processIncomingSyncMessage:(NSArray *)verifieds -{ - for (OWSSignalServiceProtosSyncMessageVerified *verified in verifieds) { - NSString *recipientId = verified.destination; - if (recipientId.length < 1) { - OWSFail(@"Verification state sync message missing recipientId."); - continue; - } - NSData *rawIdentityKey = verified.identityKey; - if (rawIdentityKey.length != kIdentityKeyLength) { - OWSFail(@"Verification state sync message for recipient: %@ with malformed identityKey: %@", - recipientId, - rawIdentityKey); - continue; - } - NSData *identityKey = [rawIdentityKey removeKeyType]; - - switch (verified.state) { - case OWSSignalServiceProtosSyncMessageVerifiedStateDefault: - [self tryToApplyVerificationStateFromSyncMessage:OWSVerificationStateDefault - recipientId:recipientId - identityKey:identityKey - overwriteOnConflict:NO]; - break; - case OWSSignalServiceProtosSyncMessageVerifiedStateVerified: - [self tryToApplyVerificationStateFromSyncMessage:OWSVerificationStateVerified - recipientId:recipientId - identityKey:identityKey - overwriteOnConflict:YES]; - break; - case OWSSignalServiceProtosSyncMessageVerifiedStateUnverified: - OWSFail(@"Verification state sync message for recipientId: %@ has unexpected value: %@.", - recipientId, - OWSVerificationStateToString(OWSVerificationStateNoLongerVerified)); - continue; - } + NSString *recipientId = verified.destination; + if (recipientId.length < 1) { + OWSFail(@"Verification state sync message missing recipientId."); + return; } - - if (verifieds.count > 0) { - [self fireIdentityStateChangeNotification]; + NSData *rawIdentityKey = verified.identityKey; + if (rawIdentityKey.length != kIdentityKeyLength) { + OWSFail(@"Verification state sync message for recipient: %@ with malformed identityKey: %@", + recipientId, + rawIdentityKey); + return; + } + NSData *identityKey = [rawIdentityKey removeKeyType]; + + switch (verified.state) { + case OWSSignalServiceProtosVerifiedStateDefault: + [self tryToApplyVerificationStateFromSyncMessage:OWSVerificationStateDefault + recipientId:recipientId + identityKey:identityKey + overwriteOnConflict:NO]; + break; + case OWSSignalServiceProtosVerifiedStateVerified: + [self tryToApplyVerificationStateFromSyncMessage:OWSVerificationStateVerified + recipientId:recipientId + identityKey:identityKey + overwriteOnConflict:YES]; + break; + case OWSSignalServiceProtosVerifiedStateUnverified: + OWSFail(@"Verification state sync message for recipientId: %@ has unexpected value: %@.", + recipientId, + OWSVerificationStateToString(OWSVerificationStateNoLongerVerified)); + return; } + [self fireIdentityStateChangeNotification]; } - (void)tryToApplyVerificationStateFromSyncMessage:(OWSVerificationState)verificationState diff --git a/src/Messages/TSMessagesManager.m b/src/Messages/TSMessagesManager.m index 74a8d7f46..49078e6e3 100644 --- a/src/Messages/TSMessagesManager.m +++ b/src/Messages/TSMessagesManager.m @@ -219,8 +219,9 @@ NS_ASSUME_NONNULL_BEGIN [description appendString:@"Blocked"]; } else if (syncMessage.read.count > 0) { [description appendString:@"ReadReceipt"]; - } else if (syncMessage.verified.count > 0){ - NSString *verifiedString = [NSString stringWithFormat:@"Verifications: (%lu)", (unsigned long)syncMessage.verified.count]; + } else if (syncMessage.hasVerified) { + NSString *verifiedString = + [NSString stringWithFormat:@"Verification for: %@", syncMessage.verified.destination]; [description appendString:verifiedString]; } else { // Shouldn't happen @@ -687,9 +688,8 @@ NS_ASSUME_NONNULL_BEGIN [[OWSReadReceiptsProcessor alloc] initWithReadReceiptProtos:syncMessage.read storageManager:self.storageManager]; [readReceiptsProcessor process]; - } else if (syncMessage.verified.count > 0) { - DDLogInfo(@"%@ Received %ld verification state(s)", self.tag, (u_long)syncMessage.verified.count); - + } else if (syncMessage.hasVerified) { + DDLogInfo(@"%@ Received verification state for %@", self.tag, syncMessage.verified.destination); [[OWSIdentityManager sharedManager] processIncomingSyncMessage:syncMessage.verified]; } else { DDLogWarn(@"%@ Ignoring unsupported sync message.", self.tag);