|
|
@ -8,6 +8,7 @@
|
|
|
|
#import "NotificationsProtocol.h"
|
|
|
|
#import "NotificationsProtocol.h"
|
|
|
|
#import "OWSAnalytics.h"
|
|
|
|
#import "OWSAnalytics.h"
|
|
|
|
#import "OWSBlockingManager.h"
|
|
|
|
#import "OWSBlockingManager.h"
|
|
|
|
|
|
|
|
#import "OWSDevice.h"
|
|
|
|
#import "OWSError.h"
|
|
|
|
#import "OWSError.h"
|
|
|
|
#import "OWSIdentityManager.h"
|
|
|
|
#import "OWSIdentityManager.h"
|
|
|
|
#import "OWSPrimaryStorage+PreKeyStore.h"
|
|
|
|
#import "OWSPrimaryStorage+PreKeyStore.h"
|
|
|
@ -46,6 +47,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
@property (nonatomic, nullable) NSData *plaintextData;
|
|
|
|
@property (nonatomic, nullable) NSData *plaintextData;
|
|
|
|
@property (nonatomic) NSString *source;
|
|
|
|
@property (nonatomic) NSString *source;
|
|
|
|
@property (nonatomic) UInt32 sourceDevice;
|
|
|
|
@property (nonatomic) UInt32 sourceDevice;
|
|
|
|
|
|
|
|
@property (nonatomic) BOOL isUDMessage;
|
|
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
@ -57,6 +59,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
plaintextData:(nullable NSData *)plaintextData
|
|
|
|
plaintextData:(nullable NSData *)plaintextData
|
|
|
|
source:(NSString *)source
|
|
|
|
source:(NSString *)source
|
|
|
|
sourceDevice:(UInt32)sourceDevice
|
|
|
|
sourceDevice:(UInt32)sourceDevice
|
|
|
|
|
|
|
|
isUDMessage:(BOOL)isUDMessage
|
|
|
|
{
|
|
|
|
{
|
|
|
|
OWSAssertDebug(envelopeData);
|
|
|
|
OWSAssertDebug(envelopeData);
|
|
|
|
OWSAssertDebug(source.length > 0);
|
|
|
|
OWSAssertDebug(source.length > 0);
|
|
|
@ -67,6 +70,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
result.plaintextData = plaintextData;
|
|
|
|
result.plaintextData = plaintextData;
|
|
|
|
result.source = source;
|
|
|
|
result.source = source;
|
|
|
|
result.sourceDevice = sourceDevice;
|
|
|
|
result.sourceDevice = sourceDevice;
|
|
|
|
|
|
|
|
result.isUDMessage = isUDMessage;
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -134,6 +138,11 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
return [self.blockingManager.blockedPhoneNumbers containsObject:envelope.source];
|
|
|
|
return [self.blockingManager.blockedPhoneNumbers containsObject:envelope.source];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (TSAccountManager *)tsAccountManager
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return TSAccountManager.sharedInstance;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark - Decryption
|
|
|
|
#pragma mark - Decryption
|
|
|
|
|
|
|
|
|
|
|
|
- (void)decryptEnvelope:(SSKProtoEnvelope *)envelope
|
|
|
|
- (void)decryptEnvelope:(SSKProtoEnvelope *)envelope
|
|
|
@ -157,11 +166,19 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSString *localRecipientId = self.tsAccountManager.localNumber;
|
|
|
|
|
|
|
|
uint32_t localDeviceId = OWSDevicePrimaryDeviceId;
|
|
|
|
DecryptSuccessBlock successBlock = ^(
|
|
|
|
DecryptSuccessBlock successBlock = ^(
|
|
|
|
OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
// Ensure all blocked messages are discarded.
|
|
|
|
// Ensure all blocked messages are discarded.
|
|
|
|
if ([self isEnvelopeSenderBlocked:envelope]) {
|
|
|
|
if ([self isEnvelopeSenderBlocked:envelope]) {
|
|
|
|
OWSLogInfo(@"ignoring blocked envelope: %@", envelope.source);
|
|
|
|
OWSLogInfo(@"Ignoring blocked envelope: %@", envelope.source);
|
|
|
|
|
|
|
|
return failureBlock();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ([result.source isEqualToString:localRecipientId] && result.sourceDevice == localDeviceId) {
|
|
|
|
|
|
|
|
// Self-sent messages should be discarded during the decryption process.
|
|
|
|
|
|
|
|
OWSFailDebug(@"Unexpected self-sent sync message.");
|
|
|
|
return failureBlock();
|
|
|
|
return failureBlock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -237,7 +254,8 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
[OWSMessageDecryptResult resultWithEnvelopeData:envelopeData
|
|
|
|
[OWSMessageDecryptResult resultWithEnvelopeData:envelopeData
|
|
|
|
plaintextData:nil
|
|
|
|
plaintextData:nil
|
|
|
|
source:envelope.source
|
|
|
|
source:envelope.source
|
|
|
|
sourceDevice:envelope.sourceDevice];
|
|
|
|
sourceDevice:envelope.sourceDevice
|
|
|
|
|
|
|
|
isUDMessage:NO];
|
|
|
|
successBlock(result, transaction);
|
|
|
|
successBlock(result, transaction);
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
// Return to avoid double-acknowledging.
|
|
|
|
// Return to avoid double-acknowledging.
|
|
|
@ -361,11 +379,11 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
// plaintextData may be nil for some envelope types.
|
|
|
|
// plaintextData may be nil for some envelope types.
|
|
|
|
NSData *_Nullable plaintextData =
|
|
|
|
NSData *_Nullable plaintextData =
|
|
|
|
[[cipher decrypt:cipherMessage protocolContext:transaction] removePadding];
|
|
|
|
[[cipher decrypt:cipherMessage protocolContext:transaction] removePadding];
|
|
|
|
OWSMessageDecryptResult *result =
|
|
|
|
OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData
|
|
|
|
[OWSMessageDecryptResult resultWithEnvelopeData:envelopeData
|
|
|
|
plaintextData:plaintextData
|
|
|
|
plaintextData:plaintextData
|
|
|
|
source:envelope.source
|
|
|
|
source:envelope.source
|
|
|
|
sourceDevice:envelope.sourceDevice
|
|
|
|
sourceDevice:envelope.sourceDevice];
|
|
|
|
isUDMessage:NO];
|
|
|
|
successBlock(result, transaction);
|
|
|
|
successBlock(result, transaction);
|
|
|
|
} @catch (NSException *exception) {
|
|
|
|
} @catch (NSException *exception) {
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
@ -414,6 +432,9 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
id<SMKCertificateValidator> certificateValidator =
|
|
|
|
id<SMKCertificateValidator> certificateValidator =
|
|
|
|
[[SMKCertificateDefaultValidator alloc] initWithTrustRoot:self.udManager.trustRoot];
|
|
|
|
[[SMKCertificateDefaultValidator alloc] initWithTrustRoot:self.udManager.trustRoot];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSString *localRecipientId = self.tsAccountManager.localNumber;
|
|
|
|
|
|
|
|
uint32_t localDeviceId = OWSDevicePrimaryDeviceId;
|
|
|
|
|
|
|
|
|
|
|
|
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
@try {
|
|
|
|
@try {
|
|
|
|
NSError *error;
|
|
|
|
NSError *error;
|
|
|
@ -433,9 +454,17 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
[cipher decryptMessageWithCertificateValidator:certificateValidator
|
|
|
|
[cipher decryptMessageWithCertificateValidator:certificateValidator
|
|
|
|
cipherTextData:encryptedData
|
|
|
|
cipherTextData:encryptedData
|
|
|
|
timestamp:serverTimestamp
|
|
|
|
timestamp:serverTimestamp
|
|
|
|
|
|
|
|
localRecipientId:localRecipientId
|
|
|
|
|
|
|
|
localDeviceId:localDeviceId
|
|
|
|
protocolContext:transaction
|
|
|
|
protocolContext:transaction
|
|
|
|
error:&error];
|
|
|
|
error:&error];
|
|
|
|
if (error || !decryptResult) {
|
|
|
|
if (error || !decryptResult) {
|
|
|
|
|
|
|
|
if ([error.domain isEqualToString:@"SignalMetadataKit.SMKSecretSessionCipherError"]
|
|
|
|
|
|
|
|
&& error.code == SMKSecretSessionCipherErrorSelfSentMessage) {
|
|
|
|
|
|
|
|
// Self-sent messages can be safely discarded.
|
|
|
|
|
|
|
|
return failureBlock(error);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OWSFailDebug(@"Could not decrypt UD message: %@", error);
|
|
|
|
OWSFailDebug(@"Could not decrypt UD message: %@", error);
|
|
|
|
error = EnsureDecryptError(error, @"Could not decrypt UD message");
|
|
|
|
error = EnsureDecryptError(error, @"Could not decrypt UD message");
|
|
|
|
return failureBlock(error);
|
|
|
|
return failureBlock(error);
|
|
|
@ -471,7 +500,8 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:newEnvelopeData
|
|
|
|
OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:newEnvelopeData
|
|
|
|
plaintextData:plaintextData
|
|
|
|
plaintextData:plaintextData
|
|
|
|
source:source
|
|
|
|
source:source
|
|
|
|
sourceDevice:(uint32_t)sourceDeviceId];
|
|
|
|
sourceDevice:(uint32_t)sourceDeviceId
|
|
|
|
|
|
|
|
isUDMessage:YES];
|
|
|
|
successBlock(result, transaction);
|
|
|
|
successBlock(result, transaction);
|
|
|
|
} @catch (NSException *exception) {
|
|
|
|
} @catch (NSException *exception) {
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
@ -517,7 +547,12 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorCorruptMessage], envelope);
|
|
|
|
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorCorruptMessage], envelope);
|
|
|
|
errorMessage = [TSErrorMessage corruptedMessageWithEnvelope:envelope withTransaction:transaction];
|
|
|
|
if (envelope.source.length > 0) {
|
|
|
|
|
|
|
|
errorMessage = [TSErrorMessage corruptedMessageWithEnvelope:envelope withTransaction:transaction];
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// TODO: Find another way to surface undecryptable UD messages to the user.
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OWSAssertDebug(errorMessage);
|
|
|
|
OWSAssertDebug(errorMessage);
|
|
|
|