Merge branch 'mkirk/verification-sync'

pull/1/head
Michael Kirk 8 years ago
commit 8fda18a8e3

@ -34,6 +34,24 @@ message Content {
optional DataMessage dataMessage = 1;
optional SyncMessage syncMessage = 2;
optional CallMessage callMessage = 3;
optional NullMessage nullMessage = 4;
}
message NullMessage {
optional bytes padding = 1;
}
message Verified {
enum State {
DEFAULT = 0;
VERIFIED = 1;
UNVERIFIED = 2;
}
optional string destination = 1;
optional bytes identityKey = 2;
optional State state = 3;
optional bytes nullMessage = 4;
}
message CallMessage {
@ -124,25 +142,13 @@ message SyncMessage {
optional uint64 timestamp = 2;
}
message Verified {
enum State {
DEFAULT = 0;
VERIFIED = 1;
UNVERIFIED = 2;
}
optional string destination = 1;
optional bytes identityKey = 2;
optional State state = 3;
}
optional Sent sent = 1;
optional Contacts contacts = 2;
optional Groups groups = 3;
optional Request request = 4;
repeated Read read = 5;
optional Blocked blocked = 6;
repeated Verified verified = 7;
optional Verified verified = 7;
optional bytes padding = 8;
}
@ -186,6 +192,7 @@ message ContactDetails {
optional string name = 2;
optional Avatar avatar = 3;
optional string color = 4;
optional Verified verified = 5;
}
message GroupDetails {

@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder
{
OWSSignalServiceProtosSyncMessageBlockedBuilder *blockedPhoneNumbersBuilder =
[OWSSignalServiceProtosSyncMessageBlockedBuilder new];
@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
[syncMessageBuilder setBlocked:[blockedPhoneNumbersBuilder build]];
return [syncMessageBuilder build];
return syncMessageBuilder;
}
@end

@ -7,10 +7,12 @@
NS_ASSUME_NONNULL_BEGIN
@class SignalAccount;
@class OWSRecipientIdentity;
@interface OWSContactsOutputStream : OWSChunkedOutputStream
- (void)writeSignalAccount:(SignalAccount *)signalAccount;
- (void)writeSignalAccount:(SignalAccount *)signalAccount
recipientIdentity:(nullable OWSRecipientIdentity *)recipientIdentity;
@end

@ -7,6 +7,7 @@
#import "MIMETypeUtil.h"
#import "OWSSignalServiceProtos.pb.h"
#import "SignalAccount.h"
#import "OWSRecipientIdentity.h"
#import <ProtocolBuffers/CodedOutputStream.h>
NS_ASSUME_NONNULL_BEGIN
@ -14,14 +15,23 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSContactsOutputStream
- (void)writeSignalAccount:(SignalAccount *)signalAccount
recipientIdentity:(nullable OWSRecipientIdentity *)recipientIdentity
{
OWSAssert(signalAccount);
OWSAssert(signalAccount.contact);
OWSSignalServiceProtosContactDetailsBuilder *contactBuilder = [OWSSignalServiceProtosContactDetailsBuilder new];
[contactBuilder setName:signalAccount.contact.fullName];
[contactBuilder setNumber:signalAccount.recipientId];
if (recipientIdentity != nil) {
OWSSignalServiceProtosVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosVerifiedBuilder new];
verifiedBuilder.destination = recipientIdentity.recipientId;
verifiedBuilder.identityKey = recipientIdentity.identityKey;
verifiedBuilder.state = OWSVerificationStateToProtoState(recipientIdentity.verificationState);
contactBuilder.verifiedBuilder = verifiedBuilder;
}
NSData *avatarPng;
if (signalAccount.contact.image) {
OWSSignalServiceProtosContactDetailsAvatarBuilder *avatarBuilder =

@ -1,4 +1,6 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSReadReceiptsMessage.h"
#import "OWSReadReceipt.h"
@ -26,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder
{
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
for (OWSReadReceipt *readReceipt in self.readReceipts) {
@ -37,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
[syncMessageBuilder addRead:[readProtoBuilder build]];
}
return [syncMessageBuilder build];
return syncMessageBuilder;
}
@end

@ -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<NSString *> *)recipientIds;
// This is a clunky name, but we want to differentiate it from `recipientIdentifier` inherited from `TSOutgoingMessage`
@property (nonatomic, readonly) NSString *verificationForRecipientId;
@property (nonatomic, readonly) size_t paddingBytesLength;
@property (nonatomic, readonly) size_t unpaddedVerifiedLength;
@end

@ -9,25 +9,12 @@
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
#pragma mark -
@interface OWSVerificationStateSyncMessage ()
@property (nonatomic, readonly) NSMutableArray<OWSVerificationStateTuple *> *tuples;
@property (nonatomic, readonly) OWSVerificationState verificationState;
@property (nonatomic, readonly) NSData *identityKey;
@end
@ -35,72 +22,78 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSVerificationStateSyncMessage
- (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;
}
_verificationState = verificationState;
_identityKey = identityKey;
_verificationForRecipientId = verificationForRecipientId;
_tuples = [NSMutableArray new];
// This sync message should be 1-512 bytes longer than the corresponding NullMessage
// we store this values so the corresponding NullMessage can subtract it from the total length.
_paddingBytesLength = arc4random_uniform(512) + 1;
return self;
}
- (void)addVerificationState:(OWSVerificationState)verificationState
identityKey:(NSData *)identityKey
recipientId:(NSString *)recipientId
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder
{
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];
}
OWSAssert(self.identityKey.length == kIdentityKeyLength);
OWSAssert(self.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(self.verificationState != OWSVerificationStateNoLongerVerified);
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
{
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) {
case OWSVerificationStateDefault:
verifiedBuilder.state = OWSSignalServiceProtosSyncMessageVerifiedStateDefault;
break;
case OWSVerificationStateVerified:
verifiedBuilder.state = OWSSignalServiceProtosSyncMessageVerifiedStateVerified;
break;
case OWSVerificationStateNoLongerVerified:
verifiedBuilder.state = OWSSignalServiceProtosSyncMessageVerifiedStateUnverified;
break;
}
[syncMessageBuilder addVerified:[verifiedBuilder build]];
}
// Add 1-512 bytes of random padding bytes.
size_t paddingLengthBytes = arc4random_uniform(512) + 1;
[syncMessageBuilder setPadding:[Cryptography generateRandomBytes:paddingLengthBytes]];
OWSSignalServiceProtosVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosVerifiedBuilder new];
verifiedBuilder.destination = self.verificationForRecipientId;
verifiedBuilder.identityKey = self.identityKey;
verifiedBuilder.state = OWSVerificationStateToProtoState(self.verificationState);
return [syncMessageBuilder build];
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];
syncMessageBuilder.verifiedBuilder = verifiedBuilder;
return syncMessageBuilder;
}
- (NSArray<NSString *> *)recipientIds
- (size_t)unpaddedVerifiedLength
{
NSMutableArray<NSString *> *result = [NSMutableArray new];
for (OWSVerificationStateTuple *tuple in self.tuples) {
OWSAssert(tuple.recipientId.length > 0);
[result addObject:tuple.recipientId];
}
OWSAssert(self.identityKey.length == kIdentityKeyLength);
OWSAssert(self.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(self.verificationState != OWSVerificationStateNoLongerVerified);
OWSSignalServiceProtosVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosVerifiedBuilder new];
verifiedBuilder.destination = self.verificationForRecipientId;
verifiedBuilder.identityKey = self.identityKey;
verifiedBuilder.state = OWSVerificationStateToProtoState(self.verificationState);
return [result copy];
return [verifiedBuilder build].data.length;
}
@end

@ -1,4 +1,6 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSOutgoingSentMessageTranscript.h"
#import "OWSSignalServiceProtos.pb.h"
@ -37,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder
{
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
@ -49,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
[syncMessageBuilder setSentBuilder:sentBuilder];
return [syncMessageBuilder build];
return syncMessageBuilder;
}
@end

@ -4,6 +4,7 @@
#import "OWSOutgoingSyncMessage.h"
#import "OWSSignalServiceProtos.pb.h"
#import "Cryptography.h"
NS_ASSUME_NONNULL_BEGIN
@ -21,13 +22,22 @@ NS_ASSUME_NONNULL_BEGIN
return NO;
}
// This method should not be overridden, since we want to add random padding to *every* sync message
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
{
NSAssert(NO, @"buildSyncMessage must be overridden in subclass");
OWSSignalServiceProtosSyncMessageBuilder *builder = [self syncMessageBuilder];
// Add a random 1-512 bytes to obscure sync message type
size_t paddingBytesLength = arc4random_uniform(512) + 1;
builder.padding = [Cryptography generateRandomBytes:paddingBytesLength];
return [builder build];
}
// e.g.
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
return [syncMessageBuilder build];
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder
{
OWSFail(@"Abstract method should be overridden in subclass.");
return [OWSSignalServiceProtosSyncMessageBuilder new];
}
- (NSData *)buildPlainTextData

@ -1,4 +1,6 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSOutgoingSyncMessage.h"
@ -6,10 +8,13 @@ NS_ASSUME_NONNULL_BEGIN
@class YapDatabaseReadWriteTransaction;
@protocol ContactsManagerProtocol;
@class OWSIdentityManager;
@interface OWSSyncContactsMessage : OWSOutgoingSyncMessage
- (instancetype)initWithContactsManager:(id<ContactsManagerProtocol>)contactsManager;
- (instancetype)initWithContactsManager:(id<ContactsManagerProtocol>)contactsManager
identityManager:(OWSIdentityManager *)identityManager;
- (NSData *)buildPlainTextAttachmentData;
@end

@ -8,6 +8,7 @@
#import "NSDate+millisecondTimeStamp.h"
#import "OWSContactsOutputStream.h"
#import "OWSSignalServiceProtos.pb.h"
#import "OWSIdentityManager.h"
#import "SignalAccount.h"
#import "TSAttachment.h"
#import "TSAttachmentStream.h"
@ -17,12 +18,14 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSSyncContactsMessage ()
@property (nonatomic, readonly) id<ContactsManagerProtocol> contactsManager;
@property (nonatomic, readonly) OWSIdentityManager *identityManager;
@end
@implementation OWSSyncContactsMessage
- (instancetype)initWithContactsManager:(id<ContactsManagerProtocol>)contactsManager
identityManager:(OWSIdentityManager *)identityManager
{
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp]];
if (!self) {
@ -30,11 +33,12 @@ NS_ASSUME_NONNULL_BEGIN
}
_contactsManager = contactsManager;
_identityManager = identityManager;
return self;
}
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder
{
if (self.attachmentIds.count != 1) {
DDLogError(@"expected sync contact message to have exactly one attachment, but found %lu",
@ -53,7 +57,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
[syncMessageBuilder setContactsBuilder:contactsBuilder];
return [syncMessageBuilder build];
return syncMessageBuilder;
}
- (NSData *)buildPlainTextAttachmentData
@ -66,7 +70,9 @@ NS_ASSUME_NONNULL_BEGIN
OWSContactsOutputStream *contactsOutputStream = [OWSContactsOutputStream streamWithOutputStream:dataOutputStream];
for (SignalAccount *signalAccount in self.contactsManager.signalAccounts) {
[contactsOutputStream writeSignalAccount:signalAccount];
OWSRecipientIdentity *recipientIdentity = [self.identityManager recipientIdentityForRecipientId:signalAccount.recipientId];
[contactsOutputStream writeSignalAccount:signalAccount recipientIdentity:recipientIdentity];
}
[contactsOutputStream flush];

@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
return [super initWithTimestamp:[NSDate ows_millisecondTimeStamp]];
}
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder
{
if (self.attachmentIds.count != 1) {
@ -37,7 +37,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
[syncMessageBuilder setGroupsBuilder:groupsBuilder];
return [syncMessageBuilder build];
return syncMessageBuilder;
}
- (NSData *)buildPlainTextAttachmentData

@ -455,8 +455,6 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
return [[self dataMessageBuilder] build];
}
// For legacy message this is a serialized DataMessage.
// For modern messages, e.g. Sync and Call messages, this is a serialized Contact
- (NSData *)buildPlainTextData
{
OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new];

@ -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 <IdentityKeyStore>
@ -46,10 +46,7 @@ extern const NSUInteger kIdentityKeyLength;
*/
- (nullable OWSRecipientIdentity *)untrustedIdentityForSendingToRecipientId:(NSString *)recipientId;
// Will try to send a sync message with all verification states.
- (void)syncAllVerificationStates;
- (void)processIncomingSyncMessage:(NSArray<OWSSignalServiceProtosSyncMessageVerified *> *)verifieds;
- (void)processIncomingSyncMessage:(OWSSignalServiceProtosVerified *)verified;
@end

@ -7,6 +7,7 @@
#import "NotificationsProtocol.h"
#import "OWSMessageSender.h"
#import "OWSRecipientIdentity.h"
#import "OWSOutgoingNullMessage.h"
#import "OWSVerificationStateChangeMessage.h"
#import "OWSVerificationStateSyncMessage.h"
#import "TSAccountManager.h"
@ -455,7 +456,7 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
}];
}];
OWSVerificationStateSyncMessage *message = [OWSVerificationStateSyncMessage new];
NSMutableArray<OWSVerificationStateSyncMessage *> *messages = [NSMutableArray new];
for (NSString *recipientId in recipientIds) {
OWSRecipientIdentity *recipientIdentity = [OWSRecipientIdentity fetchObjectWithUniqueID:recipientId];
if (!recipientIdentity) {
@ -483,53 +484,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];
});
}
}
});
}
- (void)syncAllVerificationStates
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self)
{
OWSVerificationStateSyncMessage *message =
[OWSVerificationStateSyncMessage new];
[OWSRecipientIdentity enumerateCollectionObjectsUsingBlock:^(OWSRecipientIdentity *recipientIdentity, BOOL *stop) {
OWSAssert(recipientIdentity);
OWSAssert(recipientIdentity.recipientId.length > 0);
OWSAssert(recipientIdentity.identityKey.length == kStoredIdentityKeyLength);
if (recipientIdentity.recipientId.length < 1) {
OWSFail(@"Invalid recipient identity for recipientId: %@", recipientIdentity.recipientId);
return;
}
// Prepend key type for transit.
// TODO we should just be storing the key type so we don't have to juggle re-adding it.
NSData *identityKey = [recipientIdentity.identityKey prependKeyType];
if (identityKey.length != kIdentityKeyLength) {
OWSFail(@"Invalid recipient identitykey for recipientId: %@ key: %@",
recipientIdentity.recipientId,
identityKey);
return;
}
[message addVerificationState:recipientIdentity.verificationState
identityKey:identityKey
recipientId:recipientIdentity.recipientId];
}];
if (message.recipientIds.count > 0) {
dispatch_async(dispatch_get_main_queue(), ^{
[self sendSyncVerificationStateMessage:message];
for (OWSVerificationStateSyncMessage *message in messages) {
[self sendSyncVerificationStateMessage:message];
}
});
}
}
@ -539,18 +504,34 @@ 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
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:message.verificationForRecipientId];
// Send null message to appear as though we're sending a normal message to cover the sync messsage sent
// subsequently
OWSOutgoingNullMessage *nullMessage = [[OWSOutgoingNullMessage alloc] initWithContactThread:contactThread
verificationStateSyncMessage:message];
[self.messageSender sendMessage:nullMessage
success:^{
DDLogInfo(@"%@ Successfully sent verification state sync message", self.tag);
// Record that this verification state was successfully synced.
[self clearSyncMessageForRecipientIds:message.recipientIds];
dispatch_async(dispatch_get_main_queue(), ^{
DDLogInfo(@"%@ Successfully sent verification state NullMessage", self.tag);
[self.messageSender sendMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent verification state sync message", self.tag);
// Record that this verification state was successfully synced.
[self clearSyncMessageForRecipientId:message.verificationForRecipientId];
}
failure:^(NSError *error) {
DDLogError(
@"%@ Failed to send verification state sync message with error: %@", self.tag, error);
}];
});
}
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send verification state sync message with error: %@", self.tag, error);
failure:^(NSError *_Nonnull error) {
DDLogError(@"%@ Failed to send verification state NullMessage with error: %@", self.tag, error);
}];
}
@ -558,65 +539,52 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
{
OWSAssert(recipientId.length > 0);
[self clearSyncMessageForRecipientIds:@[recipientId]];
}
- (void)clearSyncMessageForRecipientIds:(NSArray<NSString *> *)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];
}
[self.storageManager removeObjectForKey:recipientId
inCollection:OWSIdentityManager_QueuedVerificationStateSyncMessages];
}
});
}
- (void)processIncomingSyncMessage:(NSArray<OWSSignalServiceProtosSyncMessageVerified *> *)verifieds
- (void)processIncomingSyncMessage:(OWSSignalServiceProtosVerified *)verified
{
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

@ -1167,7 +1167,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
inThread:(TSThread *)thread
{
NSMutableArray *messagesArray = [NSMutableArray arrayWithCapacity:recipient.devices.count];
NSData *plainText = [message buildPlainTextData];
DDLogDebug(@"%@ message: %@ plainTextData.length: %lu", self.tag, [message class], plainText.length);
for (NSNumber *deviceNumber in recipient.devices) {
@try {

@ -0,0 +1,19 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "TSOutgoingMessage.h"
NS_ASSUME_NONNULL_BEGIN
@class OWSVerificationStateSyncMessage;
@class TSContactThread;
@interface OWSOutgoingNullMessage : TSOutgoingMessage
- (instancetype)initWithContactThread:(TSContactThread *)contactThread
verificationStateSyncMessage:(OWSVerificationStateSyncMessage *)verificationStateSyncMessage;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,76 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSOutgoingNullMessage.h"
#import "OWSSignalServiceProtos.pb.h"
#import "Cryptography.h"
#import "OWSVerificationStateSyncMessage.h"
#import "NSDate+millisecondTimeStamp.h"
#import "TSContactThread.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWSOutgoingNullMessage ()
@property (nonatomic, readonly) OWSVerificationStateSyncMessage *verificationStateSyncMessage;
@end
@implementation OWSOutgoingNullMessage
- (instancetype)initWithContactThread:(TSContactThread *)contactThread
verificationStateSyncMessage:(OWSVerificationStateSyncMessage *)verificationStateSyncMessage
{
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:contactThread];
if (!self) {
return self;
}
_verificationStateSyncMessage = verificationStateSyncMessage;
return self;
}
#pragma mark - override TSOutgoingMessage
- (NSData *)buildPlainTextData
{
OWSSignalServiceProtosContentBuilder *contentBuilder = [OWSSignalServiceProtosContentBuilder new];
OWSSignalServiceProtosNullMessageBuilder *nullMessageBuilder = [OWSSignalServiceProtosNullMessageBuilder new];
NSUInteger contentLength = self.verificationStateSyncMessage.unpaddedVerifiedLength;
OWSAssert(self.verificationStateSyncMessage.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.
contentLength += self.verificationStateSyncMessage.paddingBytesLength;
OWSAssert(contentLength > 0)
nullMessageBuilder.padding = [Cryptography generateRandomBytes:contentLength];
contentBuilder.nullMessage = [nullMessageBuilder build];
return [contentBuilder build].data;
}
- (BOOL)shouldSyncTranscript
{
return NO;
}
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// No-op as we don't want to actually display this as an outgoing message in our thread.
return;
}
@end
NS_ASSUME_NONNULL_END

@ -36,6 +36,8 @@
@class OWSSignalServiceProtosGroupDetailsAvatar;
@class OWSSignalServiceProtosGroupDetailsAvatarBuilder;
@class OWSSignalServiceProtosGroupDetailsBuilder;
@class OWSSignalServiceProtosNullMessage;
@class OWSSignalServiceProtosNullMessageBuilder;
@class OWSSignalServiceProtosSyncMessage;
@class OWSSignalServiceProtosSyncMessageBlocked;
@class OWSSignalServiceProtosSyncMessageBlockedBuilder;
@ -50,8 +52,8 @@
@class OWSSignalServiceProtosSyncMessageRequestBuilder;
@class OWSSignalServiceProtosSyncMessageSent;
@class OWSSignalServiceProtosSyncMessageSentBuilder;
@class OWSSignalServiceProtosSyncMessageVerified;
@class OWSSignalServiceProtosSyncMessageVerifiedBuilder;
@class OWSSignalServiceProtosVerified;
@class OWSSignalServiceProtosVerifiedBuilder;
@class ObjectiveCFileOptions;
@class ObjectiveCFileOptionsBuilder;
@class PBDescriptorProto;
@ -109,6 +111,15 @@ typedef NS_ENUM(SInt32, OWSSignalServiceProtosEnvelopeType) {
BOOL OWSSignalServiceProtosEnvelopeTypeIsValidValue(OWSSignalServiceProtosEnvelopeType value);
NSString *NSStringFromOWSSignalServiceProtosEnvelopeType(OWSSignalServiceProtosEnvelopeType value);
typedef NS_ENUM(SInt32, OWSSignalServiceProtosVerifiedState) {
OWSSignalServiceProtosVerifiedStateDefault = 0,
OWSSignalServiceProtosVerifiedStateVerified = 1,
OWSSignalServiceProtosVerifiedStateUnverified = 2,
};
BOOL OWSSignalServiceProtosVerifiedStateIsValidValue(OWSSignalServiceProtosVerifiedState value);
NSString *NSStringFromOWSSignalServiceProtosVerifiedState(OWSSignalServiceProtosVerifiedState value);
typedef NS_ENUM(SInt32, OWSSignalServiceProtosDataMessageFlags) {
OWSSignalServiceProtosDataMessageFlagsEndSession = 1,
OWSSignalServiceProtosDataMessageFlagsExpirationTimerUpdate = 2,
@ -127,15 +138,6 @@ typedef NS_ENUM(SInt32, OWSSignalServiceProtosSyncMessageRequestType) {
BOOL OWSSignalServiceProtosSyncMessageRequestTypeIsValidValue(OWSSignalServiceProtosSyncMessageRequestType value);
NSString *NSStringFromOWSSignalServiceProtosSyncMessageRequestType(OWSSignalServiceProtosSyncMessageRequestType value);
typedef NS_ENUM(SInt32, OWSSignalServiceProtosSyncMessageVerifiedState) {
OWSSignalServiceProtosSyncMessageVerifiedStateDefault = 0,
OWSSignalServiceProtosSyncMessageVerifiedStateVerified = 1,
OWSSignalServiceProtosSyncMessageVerifiedStateUnverified = 2,
};
BOOL OWSSignalServiceProtosSyncMessageVerifiedStateIsValidValue(OWSSignalServiceProtosSyncMessageVerifiedState value);
NSString *NSStringFromOWSSignalServiceProtosSyncMessageVerifiedState(OWSSignalServiceProtosSyncMessageVerifiedState value);
typedef NS_ENUM(SInt32, OWSSignalServiceProtosAttachmentPointerFlags) {
OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage = 1,
};
@ -274,21 +276,26 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
#define Content_dataMessage @"dataMessage"
#define Content_syncMessage @"syncMessage"
#define Content_callMessage @"callMessage"
#define Content_nullMessage @"nullMessage"
@interface OWSSignalServiceProtosContent : PBGeneratedMessage<GeneratedMessageProtocol> {
@private
BOOL hasDataMessage_:1;
BOOL hasSyncMessage_:1;
BOOL hasCallMessage_:1;
BOOL hasNullMessage_:1;
OWSSignalServiceProtosDataMessage* dataMessage;
OWSSignalServiceProtosSyncMessage* syncMessage;
OWSSignalServiceProtosCallMessage* callMessage;
OWSSignalServiceProtosNullMessage* nullMessage;
}
- (BOOL) hasDataMessage;
- (BOOL) hasSyncMessage;
- (BOOL) hasCallMessage;
- (BOOL) hasNullMessage;
@property (readonly, strong) OWSSignalServiceProtosDataMessage* dataMessage;
@property (readonly, strong) OWSSignalServiceProtosSyncMessage* syncMessage;
@property (readonly, strong) OWSSignalServiceProtosCallMessage* callMessage;
@property (readonly, strong) OWSSignalServiceProtosNullMessage* nullMessage;
+ (instancetype) defaultInstance;
- (instancetype) defaultInstance;
@ -345,6 +352,143 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (OWSSignalServiceProtosContentBuilder*) setCallMessageBuilder:(OWSSignalServiceProtosCallMessageBuilder*) builderForValue;
- (OWSSignalServiceProtosContentBuilder*) mergeCallMessage:(OWSSignalServiceProtosCallMessage*) value;
- (OWSSignalServiceProtosContentBuilder*) clearCallMessage;
- (BOOL) hasNullMessage;
- (OWSSignalServiceProtosNullMessage*) nullMessage;
- (OWSSignalServiceProtosContentBuilder*) setNullMessage:(OWSSignalServiceProtosNullMessage*) value;
- (OWSSignalServiceProtosContentBuilder*) setNullMessageBuilder:(OWSSignalServiceProtosNullMessageBuilder*) builderForValue;
- (OWSSignalServiceProtosContentBuilder*) mergeNullMessage:(OWSSignalServiceProtosNullMessage*) value;
- (OWSSignalServiceProtosContentBuilder*) clearNullMessage;
@end
#define NullMessage_padding @"padding"
@interface OWSSignalServiceProtosNullMessage : PBGeneratedMessage<GeneratedMessageProtocol> {
@private
BOOL hasPadding_:1;
NSData* padding;
}
- (BOOL) hasPadding;
@property (readonly, strong) NSData* padding;
+ (instancetype) defaultInstance;
- (instancetype) defaultInstance;
- (BOOL) isInitialized;
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
- (OWSSignalServiceProtosNullMessageBuilder*) builder;
+ (OWSSignalServiceProtosNullMessageBuilder*) builder;
+ (OWSSignalServiceProtosNullMessageBuilder*) builderWithPrototype:(OWSSignalServiceProtosNullMessage*) prototype;
- (OWSSignalServiceProtosNullMessageBuilder*) toBuilder;
+ (OWSSignalServiceProtosNullMessage*) parseFromData:(NSData*) data;
+ (OWSSignalServiceProtosNullMessage*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+ (OWSSignalServiceProtosNullMessage*) parseFromInputStream:(NSInputStream*) input;
+ (OWSSignalServiceProtosNullMessage*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+ (OWSSignalServiceProtosNullMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input;
+ (OWSSignalServiceProtosNullMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
@end
@interface OWSSignalServiceProtosNullMessageBuilder : PBGeneratedMessageBuilder {
@private
OWSSignalServiceProtosNullMessage* resultNullMessage;
}
- (OWSSignalServiceProtosNullMessage*) defaultInstance;
- (OWSSignalServiceProtosNullMessageBuilder*) clear;
- (OWSSignalServiceProtosNullMessageBuilder*) clone;
- (OWSSignalServiceProtosNullMessage*) build;
- (OWSSignalServiceProtosNullMessage*) buildPartial;
- (OWSSignalServiceProtosNullMessageBuilder*) mergeFrom:(OWSSignalServiceProtosNullMessage*) other;
- (OWSSignalServiceProtosNullMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
- (OWSSignalServiceProtosNullMessageBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
- (BOOL) hasPadding;
- (NSData*) padding;
- (OWSSignalServiceProtosNullMessageBuilder*) setPadding:(NSData*) value;
- (OWSSignalServiceProtosNullMessageBuilder*) clearPadding;
@end
#define Verified_destination @"destination"
#define Verified_identityKey @"identityKey"
#define Verified_state @"state"
#define Verified_nullMessage @"nullMessage"
@interface OWSSignalServiceProtosVerified : PBGeneratedMessage<GeneratedMessageProtocol> {
@private
BOOL hasDestination_:1;
BOOL hasIdentityKey_:1;
BOOL hasNullMessage_:1;
BOOL hasState_:1;
NSString* destination;
NSData* identityKey;
NSData* nullMessage;
OWSSignalServiceProtosVerifiedState state;
}
- (BOOL) hasDestination;
- (BOOL) hasIdentityKey;
- (BOOL) hasState;
- (BOOL) hasNullMessage;
@property (readonly, strong) NSString* destination;
@property (readonly, strong) NSData* identityKey;
@property (readonly) OWSSignalServiceProtosVerifiedState state;
@property (readonly, strong) NSData* nullMessage;
+ (instancetype) defaultInstance;
- (instancetype) defaultInstance;
- (BOOL) isInitialized;
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
- (OWSSignalServiceProtosVerifiedBuilder*) builder;
+ (OWSSignalServiceProtosVerifiedBuilder*) builder;
+ (OWSSignalServiceProtosVerifiedBuilder*) builderWithPrototype:(OWSSignalServiceProtosVerified*) prototype;
- (OWSSignalServiceProtosVerifiedBuilder*) toBuilder;
+ (OWSSignalServiceProtosVerified*) parseFromData:(NSData*) data;
+ (OWSSignalServiceProtosVerified*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+ (OWSSignalServiceProtosVerified*) parseFromInputStream:(NSInputStream*) input;
+ (OWSSignalServiceProtosVerified*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+ (OWSSignalServiceProtosVerified*) parseFromCodedInputStream:(PBCodedInputStream*) input;
+ (OWSSignalServiceProtosVerified*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
@end
@interface OWSSignalServiceProtosVerifiedBuilder : PBGeneratedMessageBuilder {
@private
OWSSignalServiceProtosVerified* resultVerified;
}
- (OWSSignalServiceProtosVerified*) defaultInstance;
- (OWSSignalServiceProtosVerifiedBuilder*) clear;
- (OWSSignalServiceProtosVerifiedBuilder*) clone;
- (OWSSignalServiceProtosVerified*) build;
- (OWSSignalServiceProtosVerified*) buildPartial;
- (OWSSignalServiceProtosVerifiedBuilder*) mergeFrom:(OWSSignalServiceProtosVerified*) other;
- (OWSSignalServiceProtosVerifiedBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
- (OWSSignalServiceProtosVerifiedBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
- (BOOL) hasDestination;
- (NSString*) destination;
- (OWSSignalServiceProtosVerifiedBuilder*) setDestination:(NSString*) value;
- (OWSSignalServiceProtosVerifiedBuilder*) clearDestination;
- (BOOL) hasIdentityKey;
- (NSData*) identityKey;
- (OWSSignalServiceProtosVerifiedBuilder*) setIdentityKey:(NSData*) value;
- (OWSSignalServiceProtosVerifiedBuilder*) clearIdentityKey;
- (BOOL) hasState;
- (OWSSignalServiceProtosVerifiedState) state;
- (OWSSignalServiceProtosVerifiedBuilder*) setState:(OWSSignalServiceProtosVerifiedState) value;
- (OWSSignalServiceProtosVerifiedBuilder*) clearState;
- (BOOL) hasNullMessage;
- (NSData*) nullMessage;
- (OWSSignalServiceProtosVerifiedBuilder*) setNullMessage:(NSData*) value;
- (OWSSignalServiceProtosVerifiedBuilder*) clearNullMessage;
@end
#define CallMessage_offer @"offer"
@ -852,21 +996,23 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
BOOL hasGroups_:1;
BOOL hasRequest_:1;
BOOL hasBlocked_:1;
BOOL hasVerified_:1;
BOOL hasPadding_:1;
OWSSignalServiceProtosSyncMessageSent* sent;
OWSSignalServiceProtosSyncMessageContacts* contacts;
OWSSignalServiceProtosSyncMessageGroups* groups;
OWSSignalServiceProtosSyncMessageRequest* request;
OWSSignalServiceProtosSyncMessageBlocked* blocked;
OWSSignalServiceProtosVerified* verified;
NSData* padding;
NSMutableArray * readArray;
NSMutableArray * verifiedArray;
}
- (BOOL) hasSent;
- (BOOL) hasContacts;
- (BOOL) hasGroups;
- (BOOL) hasRequest;
- (BOOL) hasBlocked;
- (BOOL) hasVerified;
- (BOOL) hasPadding;
@property (readonly, strong) OWSSignalServiceProtosSyncMessageSent* sent;
@property (readonly, strong) OWSSignalServiceProtosSyncMessageContacts* contacts;
@ -874,10 +1020,9 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
@property (readonly, strong) OWSSignalServiceProtosSyncMessageRequest* request;
@property (readonly, strong) NSArray<OWSSignalServiceProtosSyncMessageRead*> * read;
@property (readonly, strong) OWSSignalServiceProtosSyncMessageBlocked* blocked;
@property (readonly, strong) NSArray<OWSSignalServiceProtosSyncMessageVerified*> * verified;
@property (readonly, strong) OWSSignalServiceProtosVerified* verified;
@property (readonly, strong) NSData* padding;
- (OWSSignalServiceProtosSyncMessageRead*)readAtIndex:(NSUInteger)index;
- (OWSSignalServiceProtosSyncMessageVerified*)verifiedAtIndex:(NSUInteger)index;
+ (instancetype) defaultInstance;
- (instancetype) defaultInstance;
@ -1253,76 +1398,6 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (OWSSignalServiceProtosSyncMessageReadBuilder*) clearTimestamp;
@end
#define Verified_destination @"destination"
#define Verified_identityKey @"identityKey"
#define Verified_state @"state"
@interface OWSSignalServiceProtosSyncMessageVerified : PBGeneratedMessage<GeneratedMessageProtocol> {
@private
BOOL hasDestination_:1;
BOOL hasIdentityKey_:1;
BOOL hasState_:1;
NSString* destination;
NSData* identityKey;
OWSSignalServiceProtosSyncMessageVerifiedState state;
}
- (BOOL) hasDestination;
- (BOOL) hasIdentityKey;
- (BOOL) hasState;
@property (readonly, strong) NSString* destination;
@property (readonly, strong) NSData* identityKey;
@property (readonly) OWSSignalServiceProtosSyncMessageVerifiedState state;
+ (instancetype) defaultInstance;
- (instancetype) defaultInstance;
- (BOOL) isInitialized;
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) builder;
+ (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) builder;
+ (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) builderWithPrototype:(OWSSignalServiceProtosSyncMessageVerified*) prototype;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) toBuilder;
+ (OWSSignalServiceProtosSyncMessageVerified*) parseFromData:(NSData*) data;
+ (OWSSignalServiceProtosSyncMessageVerified*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+ (OWSSignalServiceProtosSyncMessageVerified*) parseFromInputStream:(NSInputStream*) input;
+ (OWSSignalServiceProtosSyncMessageVerified*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+ (OWSSignalServiceProtosSyncMessageVerified*) parseFromCodedInputStream:(PBCodedInputStream*) input;
+ (OWSSignalServiceProtosSyncMessageVerified*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
@end
@interface OWSSignalServiceProtosSyncMessageVerifiedBuilder : PBGeneratedMessageBuilder {
@private
OWSSignalServiceProtosSyncMessageVerified* resultVerified;
}
- (OWSSignalServiceProtosSyncMessageVerified*) defaultInstance;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) clear;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) clone;
- (OWSSignalServiceProtosSyncMessageVerified*) build;
- (OWSSignalServiceProtosSyncMessageVerified*) buildPartial;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) mergeFrom:(OWSSignalServiceProtosSyncMessageVerified*) other;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
- (BOOL) hasDestination;
- (NSString*) destination;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) setDestination:(NSString*) value;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) clearDestination;
- (BOOL) hasIdentityKey;
- (NSData*) identityKey;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) setIdentityKey:(NSData*) value;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) clearIdentityKey;
- (BOOL) hasState;
- (OWSSignalServiceProtosSyncMessageVerifiedState) state;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) setState:(OWSSignalServiceProtosSyncMessageVerifiedState) value;
- (OWSSignalServiceProtosSyncMessageVerifiedBuilder*) clearState;
@end
@interface OWSSignalServiceProtosSyncMessageBuilder : PBGeneratedMessageBuilder {
@private
OWSSignalServiceProtosSyncMessage* resultSyncMessage;
@ -1381,11 +1456,12 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (OWSSignalServiceProtosSyncMessageBuilder*) mergeBlocked:(OWSSignalServiceProtosSyncMessageBlocked*) value;
- (OWSSignalServiceProtosSyncMessageBuilder*) clearBlocked;
- (NSMutableArray<OWSSignalServiceProtosSyncMessageVerified*> *)verified;
- (OWSSignalServiceProtosSyncMessageVerified*)verifiedAtIndex:(NSUInteger)index;
- (OWSSignalServiceProtosSyncMessageBuilder *)addVerified:(OWSSignalServiceProtosSyncMessageVerified*)value;
- (OWSSignalServiceProtosSyncMessageBuilder *)setVerifiedArray:(NSArray<OWSSignalServiceProtosSyncMessageVerified*> *)array;
- (OWSSignalServiceProtosSyncMessageBuilder *)clearVerified;
- (BOOL) hasVerified;
- (OWSSignalServiceProtosVerified*) verified;
- (OWSSignalServiceProtosSyncMessageBuilder*) setVerified:(OWSSignalServiceProtosVerified*) value;
- (OWSSignalServiceProtosSyncMessageBuilder*) setVerifiedBuilder:(OWSSignalServiceProtosVerifiedBuilder*) builderForValue;
- (OWSSignalServiceProtosSyncMessageBuilder*) mergeVerified:(OWSSignalServiceProtosVerified*) value;
- (OWSSignalServiceProtosSyncMessageBuilder*) clearVerified;
- (BOOL) hasPadding;
- (NSData*) padding;
@ -1609,25 +1685,30 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
#define ContactDetails_name @"name"
#define ContactDetails_avatar @"avatar"
#define ContactDetails_color @"color"
#define ContactDetails_verified @"verified"
@interface OWSSignalServiceProtosContactDetails : PBGeneratedMessage<GeneratedMessageProtocol> {
@private
BOOL hasNumber_:1;
BOOL hasName_:1;
BOOL hasColor_:1;
BOOL hasAvatar_:1;
BOOL hasVerified_:1;
NSString* number;
NSString* name;
NSString* color;
OWSSignalServiceProtosContactDetailsAvatar* avatar;
OWSSignalServiceProtosVerified* verified;
}
- (BOOL) hasNumber;
- (BOOL) hasName;
- (BOOL) hasAvatar;
- (BOOL) hasColor;
- (BOOL) hasVerified;
@property (readonly, strong) NSString* number;
@property (readonly, strong) NSString* name;
@property (readonly, strong) OWSSignalServiceProtosContactDetailsAvatar* avatar;
@property (readonly, strong) NSString* color;
@property (readonly, strong) OWSSignalServiceProtosVerified* verified;
+ (instancetype) defaultInstance;
- (instancetype) defaultInstance;
@ -1745,6 +1826,13 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (NSString*) color;
- (OWSSignalServiceProtosContactDetailsBuilder*) setColor:(NSString*) value;
- (OWSSignalServiceProtosContactDetailsBuilder*) clearColor;
- (BOOL) hasVerified;
- (OWSSignalServiceProtosVerified*) verified;
- (OWSSignalServiceProtosContactDetailsBuilder*) setVerified:(OWSSignalServiceProtosVerified*) value;
- (OWSSignalServiceProtosContactDetailsBuilder*) setVerifiedBuilder:(OWSSignalServiceProtosVerifiedBuilder*) builderForValue;
- (OWSSignalServiceProtosContactDetailsBuilder*) mergeVerified:(OWSSignalServiceProtosVerified*) value;
- (OWSSignalServiceProtosContactDetailsBuilder*) clearVerified;
@end
#define GroupDetails_id @"id"

File diff suppressed because it is too large Load Diff

@ -50,6 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) OWSMessageSender *messageSender;
@property (nonatomic, readonly) OWSIncomingMessageFinder *incomingMessageFinder;
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@property (nonatomic, readonly) OWSIdentityManager *identityManager;
@end
@ -73,13 +74,16 @@ NS_ASSUME_NONNULL_BEGIN
id<ContactsManagerProtocol> contactsManager = [TextSecureKitEnv sharedEnv].contactsManager;
id<OWSCallMessageHandler> callMessageHandler = [TextSecureKitEnv sharedEnv].callMessageHandler;
ContactsUpdater *contactsUpdater = [ContactsUpdater sharedUpdater];
OWSIdentityManager *identityManager = [OWSIdentityManager sharedManager];
OWSMessageSender *messageSender = [TextSecureKitEnv sharedEnv].messageSender;
return [self initWithNetworkManager:networkManager
storageManager:storageManager
callMessageHandler:callMessageHandler
contactsManager:contactsManager
contactsUpdater:contactsUpdater
identityManager:identityManager
messageSender:messageSender];
}
@ -88,6 +92,7 @@ NS_ASSUME_NONNULL_BEGIN
callMessageHandler:(id<OWSCallMessageHandler>)callMessageHandler
contactsManager:(id<ContactsManagerProtocol>)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater
identityManager:(OWSIdentityManager *)identityManager
messageSender:(OWSMessageSender *)messageSender
{
self = [super init];
@ -101,6 +106,7 @@ NS_ASSUME_NONNULL_BEGIN
_callMessageHandler = callMessageHandler;
_contactsManager = contactsManager;
_contactsUpdater = contactsUpdater;
_identityManager = identityManager;
_messageSender = messageSender;
_dbConnection = storageManager.newDatabaseConnection;
@ -165,6 +171,8 @@ NS_ASSUME_NONNULL_BEGIN
return [NSString stringWithFormat:@"<DataMessage: %@ />", [self descriptionForDataMessage:content.dataMessage]];
} else if (content.hasCallMessage) {
return [NSString stringWithFormat:@"<CallMessage: %@ />", content.callMessage];
} else if (content.hasNullMessage) {
return [NSString stringWithFormat:@"<NullMessage: %@ />", content.nullMessage];
} else {
OWSAssert(NO);
return @"UnknownContent";
@ -219,8 +227,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
@ -363,7 +372,7 @@ NS_ASSUME_NONNULL_BEGIN
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:[OWSIdentityManager sharedManager]
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
@ -415,7 +424,7 @@ NS_ASSUME_NONNULL_BEGIN
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:[OWSIdentityManager sharedManager]
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
@ -449,7 +458,7 @@ NS_ASSUME_NONNULL_BEGIN
sourceId:envelope.source
sourceDeviceId:envelope.sourceDevice];
if (duplicateEnvelope) {
DDLogInfo(@"%@ Ignoring previously received envelope with timestamp: %llu", self.tag, envelope.timestamp);
DDLogInfo(@"%@ Ignoring previously received envelope from %@.%d with timestamp: %llu", self.tag, envelope.source, (unsigned int)envelope.sourceDevice, envelope.timestamp);
return;
}
@ -462,6 +471,8 @@ NS_ASSUME_NONNULL_BEGIN
[self handleIncomingEnvelope:envelope withDataMessage:content.dataMessage];
} else if (content.hasCallMessage) {
[self handleIncomingEnvelope:envelope withCallMessage:content.callMessage];
} else if (content.hasNullMessage) {
DDLogInfo(@"%@ Received null message.", self.tag);
} else {
DDLogWarn(@"%@ Ignoring envelope. Content with no known payload", self.tag);
}
@ -648,7 +659,8 @@ NS_ASSUME_NONNULL_BEGIN
} else if (syncMessage.hasRequest) {
if (syncMessage.request.type == OWSSignalServiceProtosSyncMessageRequestTypeContacts) {
OWSSyncContactsMessage *syncContactsMessage =
[[OWSSyncContactsMessage alloc] initWithContactsManager:self.contactsManager];
[[OWSSyncContactsMessage alloc] initWithContactsManager:self.contactsManager
identityManager:self.identityManager];
[self.messageSender sendTemporaryAttachmentData:[syncContactsMessage buildPlainTextAttachmentData]
contentType:OWSMimeTypeApplicationOctetStream
@ -659,9 +671,6 @@ NS_ASSUME_NONNULL_BEGIN
failure:^(NSError *error) {
DDLogError(@"%@ Failed to send Contacts response syncMessage with error: %@", self.tag, error);
}];
// Also sync all verification state after syncing contacts.
[[OWSIdentityManager sharedManager] syncAllVerificationStates];
} else if (syncMessage.request.type == OWSSignalServiceProtosSyncMessageRequestTypeGroups) {
OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init];
@ -687,10 +696,9 @@ 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);
[[OWSIdentityManager sharedManager] processIncomingSyncMessage:syncMessage.verified];
} else if (syncMessage.hasVerified) {
DDLogInfo(@"%@ Received verification state for %@", self.tag, syncMessage.verified.destination);
[self.identityManager processIncomingSyncMessage:syncMessage.verified];
} else {
DDLogWarn(@"%@ Ignoring unsupported sync message.", self.tag);
}

@ -2,7 +2,8 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <SignalServiceKit/TSYapDatabaseObject.h>
#import "OWSSignalServiceProtos.pb.h"
#import "TSYapDatabaseObject.h"
NS_ASSUME_NONNULL_BEGIN
@ -13,6 +14,7 @@ typedef NS_ENUM(NSUInteger, OWSVerificationState) {
};
NSString *OWSVerificationStateToString(OWSVerificationState verificationState);
OWSSignalServiceProtosVerifiedState OWSVerificationStateToProtoState(OWSVerificationState verificationState);
@interface OWSRecipientIdentity : TSYapDatabaseObject

@ -20,6 +20,18 @@ NSString *OWSVerificationStateToString(OWSVerificationState verificationState)
}
}
OWSSignalServiceProtosVerifiedState OWSVerificationStateToProtoState(OWSVerificationState verificationState)
{
switch (verificationState) {
case OWSVerificationStateDefault:
return OWSSignalServiceProtosVerifiedStateDefault;
case OWSVerificationStateVerified:
return OWSSignalServiceProtosVerifiedStateVerified;
case OWSVerificationStateNoLongerVerified:
return OWSSignalServiceProtosVerifiedStateUnverified;
}
}
@interface OWSRecipientIdentity ()
@property (atomic) OWSVerificationState verificationState;

Loading…
Cancel
Save