Add protocol context to protocol kit.

pull/1/head
Matthew Chen 7 years ago
parent 7358f3053f
commit 074046b98e

@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSIdentityManager *identityManager = [OWSIdentityManager sharedManager];
NSString *recipientId = [thread contactIdentifier];
NSData *currentKey = [identityManager identityKeyForRecipientId:recipientId];
NSData *currentKey = [identityManager identityKeyForRecipientIdWOT:recipientId];
NSMutableData *flippedKey = [NSMutableData new];
const char *currentKeyBytes = currentKey.bytes;
for (NSUInteger i = 0; i < currentKey.length; i++) {

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "ShowGroupMembersViewController.h"
@ -246,7 +246,7 @@ NS_ASSUME_NONNULL_BEGIN
for (NSString *recipientId in recipientIds) {
OWSVerificationState verificationState = [identityManger verificationStateForRecipientId:recipientId];
if (verificationState == OWSVerificationStateNoLongerVerified) {
NSData *identityKey = [identityManger identityKeyForRecipientId:recipientId];
NSData *identityKey = [identityManger identityKeyForRecipientIdWOT:recipientId];
if (identityKey.length < 1) {
OWSFail(@"Missing identity key for: %@", recipientId);
continue;

@ -404,7 +404,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
}
case OWSVerificationStateNoLongerVerified: {
DDLogInfo(@"%@ marked recipient: %@ as default verification status.", self.logTag, recipientId);
NSData *identityKey = [[OWSIdentityManager sharedManager] identityKeyForRecipientId:recipientId];
NSData *identityKey = [[OWSIdentityManager sharedManager] identityKeyForRecipientIdWOT:recipientId];
OWSAssert(identityKey);
[[OWSIdentityManager sharedManager] setVerificationState:OWSVerificationStateDefault
identityKey:identityKey

@ -106,9 +106,7 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
[transaction removeAllObjectsInCollection:TSAccountManager_UserAccountCollection];
}];
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[[TSStorageManager sharedManager] resetSessionStore];
});
[[TSStorageManager sharedManager] resetSessionStore];
}
+ (BOOL)isRegistered
@ -201,9 +199,11 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
- (uint32_t)getOrGenerateRegistrationId
{
__block uint32_t result;
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[self getOrGenerateRegistrationId:transaction];
result = [self getOrGenerateRegistrationId:transaction];
}];
return result;
}
- (uint32_t)getOrGenerateRegistrationId:(YapDatabaseReadWriteTransaction *)transaction

@ -134,11 +134,11 @@ static const NSTimeInterval kSignedPreKeyUpdateFailureMaxFailureDuration = 10 *
RefreshPreKeysMode modeCopy = mode;
TSStorageManager *storageManager = [TSStorageManager sharedManager];
ECKeyPair *identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair];
ECKeyPair *identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPairWithoutProtocolContext];
if (!identityKeyPair) {
[[OWSIdentityManager sharedManager] generateNewIdentityKey];
identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair];
identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPairWithoutProtocolContext];
// Switch modes if necessary.
modeCopy = RefreshPreKeysMode_SignedAndOneTime;

@ -111,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)hasSafetyNumbers
{
return !![[OWSIdentityManager sharedManager] identityKeyForRecipientId:self.contactIdentifier];
return !![[OWSIdentityManager sharedManager] identityKeyForRecipientIdWOT:self.contactIdentifier];
}
- (NSString *)name

@ -68,9 +68,7 @@ NS_ASSUME_NONNULL_BEGIN
TSThread *thread = [transcript threadWithTransaction:transaction];
if (transcript.isEndSessionMessage) {
DDLogInfo(@"%@ EndSession was sent to recipient: %@.", self.logTag, transcript.recipientId);
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[self.storageManager deleteAllSessionsForContact:transcript.recipientId protocolContext:protocolContext];
});
[self.storageManager deleteAllSessionsForContact:transcript.recipientId protocolContext:transaction];
[[[TSInfoMessage alloc] initWithTimestamp:transcript.timestamp
inThread:thread
messageType:TSInfoMessageTypeSessionDidEnd] saveWithTransaction:transaction];

@ -10,6 +10,7 @@
#import "TSContactThread.h"
#import "TSDatabaseView.h"
#import "TSErrorMessage_privateConstructor.h"
#import "TSStorageManager+SessionStore.h"
#import "TSStorageManager.h"
#import <AxolotlKit/NSData+keyVersionByte.h>
#import <AxolotlKit/PreKeyWhisperMessage.h>
@ -80,10 +81,11 @@ NS_ASSUME_NONNULL_BEGIN
}
// Saving a new identity mutates the session store so it must happen on the sessionStoreQueue
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[TSStorageManager.protocolStoreDBConnection asyncReadWriteWithBlock:^(
YapDatabaseReadWriteTransaction *transaction) {
[[OWSIdentityManager sharedManager] saveRemoteIdentity:newKey
recipientId:self.envelope.source
protocolContext:protocolContext];
protocolContext:transaction];
dispatch_async(dispatch_get_main_queue(), ^{
// Decrypt this and any old messages for the newly accepted key
@ -99,7 +101,7 @@ NS_ASSUME_NONNULL_BEGIN
[errorMessage remove];
}
});
});
}];
}
- (nullable NSData *)newIdentityKey

@ -10,6 +10,7 @@
#import "TSContactThread.h"
#import "TSErrorMessage_privateConstructor.h"
#import "TSOutgoingMessage.h"
#import "TSStorageManager+SessionStore.h"
#import <AxolotlKit/NSData+keyVersionByte.h>
NS_ASSUME_NONNULL_BEGIN
@ -57,11 +58,12 @@ NSString *TSInvalidRecipientKey = @"TSInvalidRecipientKey";
return;
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[[OWSIdentityManager sharedManager] saveRemoteIdentity:newIdentityKey
recipientId:self.recipientId
protocolContext:protocolContext];
});
[TSStorageManager.protocolStoreDBConnection
asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[[OWSIdentityManager sharedManager] saveRemoteIdentity:newIdentityKey
recipientId:self.recipientId
protocolContext:transaction];
}];
}
- (nullable NSData *)newIdentityKey

@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class OWSStorage;
@class YapDatabaseReadWriteTransaction;
// This class is used to write incoming (decrypted, unprocessed)
// messages to a durable queue and then process them in batches,
@ -15,7 +16,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)sharedInstance;
+ (void)asyncRegisterDatabaseExtension:(OWSStorage *)storage;
- (void)enqueueEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData;
- (void)enqueueEnvelopeData:(NSData *)envelopeData
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)handleAnyUnprocessedEnvelopesAsync;
@end

@ -136,14 +136,16 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
return [jobs copy];
}
- (void)addJobWithEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData
- (void)addJobWithEnvelopeData:(NSData *)envelopeData
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
// We need to persist the decrypted envelope data ASAP to prevent data loss.
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
OWSMessageContentJob *job =
[[OWSMessageContentJob alloc] initWithEnvelopeData:envelopeData plaintextData:plaintextData];
[job saveWithTransaction:transaction];
}];
OWSAssert(envelopeData);
OWSAssert(transaction);
OWSMessageContentJob *job =
[[OWSMessageContentJob alloc] initWithEnvelopeData:envelopeData plaintextData:plaintextData];
[job saveWithTransaction:transaction];
}
- (void)removeJobsWithIds:(NSArray<NSString *> *)uniqueIds
@ -293,12 +295,15 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
return queue;
}
- (void)enqueueEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData
- (void)enqueueEnvelopeData:(NSData *)envelopeData
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(envelopeData);
OWSAssert(transaction);
// We need to persist the decrypted envelope data ASAP to prevent data loss.
[self.finder addJobWithEnvelopeData:envelopeData plaintextData:plaintextData];
[self.finder addJobWithEnvelopeData:envelopeData plaintextData:plaintextData transaction:transaction];
}
- (void)drainQueue
@ -459,12 +464,15 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
[self.processingQueue drainQueue];
}
- (void)enqueueEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData
- (void)enqueueEnvelopeData:(NSData *)envelopeData
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(envelopeData);
OWSAssert(transaction);
// We need to persist the decrypted envelope data ASAP to prevent data loss.
[self.processingQueue enqueueEnvelopeData:envelopeData plaintextData:plaintextData];
[self.processingQueue enqueueEnvelopeData:envelopeData plaintextData:plaintextData transaction:transaction];
[self.processingQueue drainQueue];
}

@ -30,6 +30,9 @@ extern const NSUInteger kIdentityKeyLength;
- (void)generateNewIdentityKey;
// TODO: Rename to identityKeyForRecipientId.
- (nullable NSData *)identityKeyForRecipientIdWOT:(NSString *)recipientId;
- (nullable NSData *)identityKeyForRecipientId:(NSString *)recipientId protocolContext:(nullable id)protocolContext;
- (void)setVerificationState:(OWSVerificationState)verificationState
@ -55,6 +58,7 @@ extern const NSUInteger kIdentityKeyLength;
#pragma mark - Debug
// TODO:
- (nullable ECKeyPair *)identityKeyPairWithoutProtocolContext;
#if DEBUG

@ -132,6 +132,15 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
inCollection:TSStorageManagerIdentityKeyStoreCollection];
}
- (nullable NSData *)identityKeyForRecipientIdWOT:(NSString *)recipientId
{
__block NSData *_Nullable result = nil;
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
result = [self identityKeyForRecipientId:recipientId protocolContext:transaction];
}];
return result;
}
- (nullable NSData *)identityKeyForRecipientId:(NSString *)recipientId protocolContext:(nullable id)protocolContext
{
OWSAssert(recipientId.length > 0);

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSMessageHandler.h"
@ -7,8 +7,9 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class YapDatabaseReadWriteTransaction;
typedef void (^DecryptSuccessBlock)(NSData *_Nullable plaintextData);
typedef void (^DecryptSuccessBlock)(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction);
typedef void (^DecryptFailureBlock)(void);
@interface OWSMessageDecrypter : OWSMessageHandler

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSMessageDecrypter.h"
@ -89,20 +89,18 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Decryption
- (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
successBlock:(DecryptSuccessBlock)successBlockParameter
successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(DecryptFailureBlock)failureBlockParameter
{
OWSAssert(envelope);
OWSAssert(successBlockParameter);
OWSAssert(successBlock);
OWSAssert(failureBlockParameter);
OWSAssert([TSAccountManager isRegistered]);
// Ensure that successBlock and failureBlock are called on a worker queue.
DecryptSuccessBlock successBlock = ^(NSData *_Nullable plaintextData) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
successBlockParameter(plaintextData);
});
};
// successBlock is called synchronously so that we can avail ourselves of
// the transaction.
//
// Ensure that failureBlock is called on a worker queue.
DecryptFailureBlock failureBlock = ^() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
failureBlockParameter();
@ -121,9 +119,9 @@ NS_ASSUME_NONNULL_BEGIN
switch (envelope.type) {
case OWSSignalServiceProtosEnvelopeTypeCiphertext: {
[self decryptSecureMessage:envelope
successBlock:^(NSData *_Nullable plaintextData) {
successBlock:^(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
DDLogDebug(@"%@ decrypted secure message.", self.logTag);
successBlock(plaintextData);
successBlock(plaintextData, transaction);
}
failureBlock:^(NSError *_Nullable error) {
DDLogError(@"%@ decrypting secure message from address: %@ failed with error: %@",
@ -138,9 +136,9 @@ NS_ASSUME_NONNULL_BEGIN
}
case OWSSignalServiceProtosEnvelopeTypePrekeyBundle: {
[self decryptPreKeyBundle:envelope
successBlock:^(NSData *_Nullable plaintextData) {
successBlock:^(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
DDLogDebug(@"%@ decrypted pre-key whisper message", self.logTag);
successBlock(plaintextData);
successBlock(plaintextData, transaction);
}
failureBlock:^(NSError *_Nullable error) {
DDLogError(@"%@ decrypting pre-key whisper message from address: %@ failed "
@ -157,10 +155,14 @@ NS_ASSUME_NONNULL_BEGIN
// These message types don't have a payload to decrypt.
case OWSSignalServiceProtosEnvelopeTypeReceipt:
case OWSSignalServiceProtosEnvelopeTypeKeyExchange:
case OWSSignalServiceProtosEnvelopeTypeUnknown:
successBlock(nil);
case OWSSignalServiceProtosEnvelopeTypeUnknown: {
[TSStorageManager.protocolStoreDBConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
successBlock(nil, transaction);
}];
// Return to avoid double-acknowledging.
return;
}
default:
DDLogWarn(@"Received unhandled envelope type: %d", (int)envelope.type);
break;
@ -234,27 +236,30 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{
@try {
id<CipherMessage> cipherMessage = cipherMessageBlock(encryptedData);
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
NSData *plaintextData = [[cipher decrypt:cipherMessage] removePadding];
successBlock(plaintextData);
} @catch (NSException *exception) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self processException:exception envelope:envelope];
NSString *errorDescription = [NSString
stringWithFormat:@"Exception while decrypting %@: %@", cipherTypeName, exception.description];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
failureBlock(error);
});
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[TSStorageManager.protocolStoreDBConnection readWriteWithBlock:^(
YapDatabaseReadWriteTransaction *_Nonnull transaction) {
@try {
id<CipherMessage> cipherMessage = cipherMessageBlock(encryptedData);
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
NSData *plaintextData = [[cipher decrypt:cipherMessage protocolContext:transaction] removePadding];
successBlock(plaintextData, transaction);
} @catch (NSException *exception) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self processException:exception envelope:envelope];
NSString *errorDescription = [NSString
stringWithFormat:@"Exception while decrypting %@: %@", cipherTypeName, exception.description];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
failureBlock(error);
});
}
}];
});
}

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSMessageHandler.h"
@ -20,10 +20,6 @@ NS_ASSUME_NONNULL_BEGIN
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (NSUInteger)unreadMessagesCount;
- (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread;
- (NSUInteger)unreadMessagesInThread:(TSThread *)thread;
@end
NS_ASSUME_NONNULL_END

@ -21,6 +21,7 @@
#import "OWSIncomingMessageFinder.h"
#import "OWSIncomingSentMessageTranscript.h"
#import "OWSMessageSender.h"
#import "OWSMessageUtils.h"
#import "OWSReadReceiptManager.h"
#import "OWSRecordTranscriptJob.h"
#import "OWSSyncConfigurationMessage.h"
@ -137,7 +138,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)yapDatabaseModified:(NSNotification *)notification
{
if (AppReadiness.isAppReady) {
[self updateApplicationBadgeCount];
[OWSMessageUtils.sharedManager updateApplicationBadgeCount];
}
}
@ -1118,47 +1119,6 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (NSUInteger)unreadMessagesCount
{
__block NSUInteger numberOfItems;
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
numberOfItems = [[transaction ext:TSUnreadDatabaseViewExtensionName] numberOfItemsInAllGroups];
}];
return numberOfItems;
}
- (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread
{
__block NSUInteger numberOfItems;
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
id databaseView = [transaction ext:TSUnreadDatabaseViewExtensionName];
OWSAssert(databaseView);
numberOfItems = ([databaseView numberOfItemsInAllGroups] - [databaseView numberOfItemsInGroup:thread.uniqueId]);
}];
return numberOfItems;
}
- (void)updateApplicationBadgeCount
{
if (!CurrentAppContext().isMainApp) {
return;
}
NSUInteger numberOfItems = [self unreadMessagesCount];
[CurrentAppContext() setMainAppBadgeNumber:numberOfItems];
}
- (NSUInteger)unreadMessagesInThread:(TSThread *)thread
{
__block NSUInteger numberOfItems;
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
numberOfItems = [[transaction ext:TSUnreadDatabaseViewExtensionName] numberOfItemsInGroup:thread.uniqueId];
}];
return numberOfItems;
}
@end
NS_ASSUME_NONNULL_END

@ -331,11 +331,15 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
OWSSignalServiceProtosEnvelope *envelope = job.envelopeProto;
[self.messageDecrypter decryptEnvelope:envelope
successBlock:^(NSData *_Nullable plaintextData) {
// We can't decrypt the same message twice, so we need to persist
// the decrypted envelope data ASAP to prevent data loss.
[self.batchMessageProcessor enqueueEnvelopeData:job.envelopeData plaintextData:plaintextData];
successBlock:^(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
OWSAssert(transaction);
// We persist the decrypted envelope data in the same transaction within which
// it was decrypted to prevent data loss. If the new job isn't persisted,
// the session state side effects of its decryption are also rolled back.
[self.batchMessageProcessor enqueueEnvelopeData:job.envelopeData
plaintextData:plaintextData
transaction:transaction];
dispatch_async(self.serialQueue, ^{
completion(YES);

@ -904,9 +904,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
NSData *newIdentityKey = [newIdentityKeyWithVersion removeKeyType];
[[OWSIdentityManager sharedManager] saveRemoteIdentity:newIdentityKey
recipientId:recipient.recipientId
protocolContext:protocolContext];
[TSStorageManager.protocolStoreDBConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[[OWSIdentityManager sharedManager] saveRemoteIdentity:newIdentityKey
recipientId:recipient.recipientId
protocolContext:transaction];
}];
failureHandler(error);
return;
@ -1101,30 +1104,34 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
}
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{
if (extraDevices.count < 1 && missingDevices.count < 1) {
OWSProdFail([OWSAnalyticsEvents messageSenderErrorNoMissingOrExtraDevices]);
}
[TSStorageManager.protocolStoreDBConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
if (extraDevices.count < 1 && missingDevices.count < 1) {
OWSProdFail([OWSAnalyticsEvents messageSenderErrorNoMissingOrExtraDevices]);
}
if (extraDevices && extraDevices.count > 0) {
DDLogInfo(@"%@ removing extra devices: %@", self.logTag, extraDevices);
for (NSNumber *extraDeviceId in extraDevices) {
[self.storageManager deleteSessionForContact:recipient.uniqueId
deviceId:extraDeviceId.intValue
protocolContext:protocolContext];
if (extraDevices && extraDevices.count > 0) {
DDLogInfo(@"%@ removing extra devices: %@", self.logTag, extraDevices);
for (NSNumber *extraDeviceId in extraDevices) {
[self.storageManager deleteSessionForContact:recipient.uniqueId
deviceId:extraDeviceId.intValue
protocolContext:transaction];
}
[recipient removeDevices:[NSSet setWithArray:extraDevices]];
}
[recipient removeDevices:[NSSet setWithArray:extraDevices]];
}
if (missingDevices && missingDevices.count > 0) {
DDLogInfo(@"%@ Adding missing devices: %@", self.logTag, missingDevices);
[recipient addDevices:[NSSet setWithArray:missingDevices]];
}
if (missingDevices && missingDevices.count > 0) {
DDLogInfo(@"%@ Adding missing devices: %@", self.logTag, missingDevices);
[recipient addDevices:[NSSet setWithArray:missingDevices]];
}
[recipient saveWithTransaction:transaction];
[recipient save];
completionHandler();
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
completionHandler();
});
}];
}
- (void)handleMessageSentLocally:(TSOutgoingMessage *)message
@ -1249,19 +1256,19 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
@try {
__block NSDictionary *messageDict;
__block NSException *encryptionException;
// Mutating session state is not thread safe, so we operate on a serial queue, shared with decryption
// operations.
dispatch_sync([OWSDispatch sessionStoreQueue], ^{
@try {
messageDict = [self encryptedMessageWithPlaintext:plainText
toRecipient:recipient.uniqueId
deviceId:deviceNumber
keyingStorage:self.storageManager
isSilent:message.isSilent];
} @catch (NSException *exception) {
encryptionException = exception;
}
});
[TSStorageManager.protocolStoreDBConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
@try {
messageDict = [self encryptedMessageWithPlaintext:plainText
toRecipient:recipient.uniqueId
deviceId:deviceNumber
keyingStorage:self.storageManager
isSilent:message.isSilent
transaction:transaction];
} @catch (NSException *exception) {
encryptionException = exception;
}
}];
if (encryptionException) {
DDLogInfo(@"%@ Exception during encryption: %@", self.logTag, encryptionException);
@ -1290,13 +1297,15 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
deviceId:(NSNumber *)deviceNumber
keyingStorage:(TSStorageManager *)storage
isSilent:(BOOL)isSilent
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(plainText);
OWSAssert(identifier.length > 0);
OWSAssert(deviceNumber);
OWSAssert(storage);
OWSAssert(transaction);
if (![storage containsSession:identifier deviceId:[deviceNumber intValue] protocolContext:protocolContext]) {
if (![storage containsSession:identifier deviceId:[deviceNumber intValue] protocolContext:transaction]) {
__block dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block PreKeyBundle *_Nullable bundle;
__block NSException *_Nullable exception;
@ -1341,10 +1350,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
recipientId:identifier
deviceId:[deviceNumber intValue]];
@try {
// Mutating session state is not thread safe.
@synchronized(self) {
[builder processPrekeyBundle:bundle];
}
[builder processPrekeyBundle:bundle protocolContext:transaction];
} @catch (NSException *exception) {
if ([exception.name isEqualToString:UntrustedIdentityKeyException]) {
OWSRaiseExceptionWithUserInfo(UntrustedIdentityKeyException,
@ -1363,18 +1369,20 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
recipientId:identifier
deviceId:[deviceNumber intValue]];
id<CipherMessage> encryptedMessage = [cipher encryptMessage:[plainText paddedMessageBody]];
id<CipherMessage> encryptedMessage =
[cipher encryptMessage:[plainText paddedMessageBody] protocolContext:transaction];
NSData *serializedMessage = encryptedMessage.serialized;
TSWhisperMessageType messageType = [self messageTypeForCipherMessage:encryptedMessage];
OWSMessageServiceParams *messageParams = [[OWSMessageServiceParams alloc] initWithType:messageType
recipientId:identifier
device:[deviceNumber intValue]
content:serializedMessage
isSilent:isSilent
registrationId:cipher.remoteRegistrationId];
OWSMessageServiceParams *messageParams =
[[OWSMessageServiceParams alloc] initWithType:messageType
recipientId:identifier
device:[deviceNumber intValue]
content:serializedMessage
isSilent:isSilent
registrationId:[cipher remoteRegistrationId:transaction]];
NSError *error;
NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error];
@ -1428,15 +1436,15 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return;
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[TSStorageManager.protocolStoreDBConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (NSUInteger i = 0; i < [devices count]; i++) {
int deviceNumber = [devices[i] intValue];
[[TSStorageManager sharedManager] deleteSessionForContact:identifier
deviceId:deviceNumber
protocolContext:protocolContext];
protocolContext:transaction];
}
completionHandler();
});
}];
completionHandler();
});
}

@ -2,28 +2,21 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSMessageHandler.h"
NS_ASSUME_NONNULL_BEGIN
@class OWSSignalServiceProtosEnvelope;
@class TSThread;
@class YapDatabaseReadWriteTransaction;
@interface OWSMessageManager : OWSMessageHandler
@interface OWSMessageUtils : NSObject
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)sharedManager;
// processEnvelope: can be called from any thread.
- (void)processEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
plaintextData:(NSData *_Nullable)plaintextData
transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (NSUInteger)unreadMessagesCount;
- (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread;
- (NSUInteger)unreadMessagesInThread:(TSThread *)thread;
- (void)updateApplicationBadgeCount;
@end
NS_ASSUME_NONNULL_END

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSFingerprintBuilder.h"
@ -36,7 +36,8 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable OWSFingerprint *)fingerprintWithTheirSignalId:(NSString *)theirSignalId
{
NSData *_Nullable theirIdentityKey = [[OWSIdentityManager sharedManager] identityKeyForRecipientId:theirSignalId];
NSData *_Nullable theirIdentityKey =
[[OWSIdentityManager sharedManager] identityKeyForRecipientIdWOT:theirSignalId];
if (theirIdentityKey == nil) {
OWSFail(@"%@ Missing their identity key", self.logTag);
@ -51,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
NSString *theirName = [self.contactsManager displayNameForPhoneIdentifier:theirSignalId];
NSString *mySignalId = [self.accountManager localNumber];
NSData *myIdentityKey = [[OWSIdentityManager sharedManager] identityKeyPair].publicKey;
NSData *myIdentityKey = [[OWSIdentityManager sharedManager] identityKeyPairWithoutProtocolContext].publicKey;
return [OWSFingerprint fingerprintWithMyStableId:mySignalId
myIdentityKey:myIdentityKey

@ -43,7 +43,9 @@ NSString *const kSessionStoreDBConnectionKey = @"kSessionStoreDBConnectionKey";
#pragma mark - SessionStore
- (SessionRecord *)loadSession:(NSString *)contactIdentifier deviceId:(int)deviceId protocolContext:(id)protocolContext
- (SessionRecord *)loadSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id)protocolContext
{
OWSAssert(contactIdentifier.length > 0);
OWSAssert(deviceId >= 0);
@ -116,7 +118,9 @@ NSString *const kSessionStoreDBConnectionKey = @"kSessionStoreDBConnectionKey";
inCollection:TSStorageManagerSessionStoreCollection];
}
- (BOOL)containsSession:(NSString *)contactIdentifier deviceId:(int)deviceId protocolContext:(id)protocolContext
- (BOOL)containsSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id)protocolContext
{
OWSAssert(contactIdentifier.length > 0);
OWSAssert(deviceId >= 0);

@ -27,7 +27,7 @@ NSString *const TSStorageManagerKeyPrekeyCurrentSignedPrekeyId = @"currentSigned
// Signed prekey ids must be > 0.
int preKeyId = 1 + arc4random_uniform(INT32_MAX - 1);
ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair];
ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPairWithoutProtocolContext];
return [[SignedPreKeyRecord alloc]
initWithId:preKeyId
keyPair:keyPair

Loading…
Cancel
Save