Handle known sender
This commit is contained in:
parent
6c2dbbc7c3
commit
f52a58e31e
1
Podfile
1
Podfile
|
@ -18,7 +18,6 @@ def shared_pods
|
|||
# pod 'HKDFKit', path: '../HKDFKit', testspecs: ["Tests"]
|
||||
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit', testspecs: ["Tests"]
|
||||
# pod 'Curve25519Kit', path: '../Curve25519Kit', testspecs: ["Tests"]
|
||||
# TODO: Use public repo.
|
||||
pod 'SignalMetadataKit', git: 'https://github.com/signalapp/SignalMetadataKit', testspecs: ["Tests"]
|
||||
# pod 'SignalMetadataKit', path: '../SignalMetadataKit', testspecs: ["Tests"]
|
||||
pod 'SignalServiceKit', path: '.', testspecs: ["Tests"]
|
||||
|
|
|
@ -261,7 +261,7 @@ CHECKOUT OPTIONS:
|
|||
:commit: b60dc7d58dfc93ca6eafbb3ea5300c6d67ebc69a
|
||||
:git: https://github.com/signalapp/SignalCoreKit.git
|
||||
SignalMetadataKit:
|
||||
:commit: d6b0186cc5b15019e85c375bce3bf78e7a7fc162
|
||||
:commit: a5473c8d33602775e00253afce78eef01a69260e
|
||||
:git: https://github.com/signalapp/SignalMetadataKit
|
||||
SocketRocket:
|
||||
:commit: 9f9563a83cd8960503074aa8de72206f83fb7a69
|
||||
|
@ -296,6 +296,6 @@ SPEC CHECKSUMS:
|
|||
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
|
||||
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
|
||||
|
||||
PODFILE CHECKSUM: 820287bc7925d7c20e02a02923976c60b1f5386b
|
||||
PODFILE CHECKSUM: 55c6b62a23df23853a2af68917716a56a813c3f0
|
||||
|
||||
COCOAPODS: 1.5.3
|
||||
|
|
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 5821eb8e9fd9f76fbdbedd3402892c185e65c48e
|
||||
Subproject commit 37cee04eebbe0ecbf61bd415383be9b1773dccef
|
|
@ -37,6 +37,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|||
if (error) {
|
||||
return error;
|
||||
}
|
||||
OWSCFailDebug(@"Caller should provide specific error");
|
||||
return OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, fallbackErrorDescription);
|
||||
}
|
||||
|
||||
|
@ -434,89 +435,140 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
|
|||
uint32_t localDeviceId = OWSDevicePrimaryDeviceId;
|
||||
|
||||
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
@try {
|
||||
NSError *error;
|
||||
SMKSecretSessionCipher *_Nullable cipher =
|
||||
[[SMKSecretSessionCipher alloc] initWithSessionStore:self.primaryStorage
|
||||
preKeyStore:self.primaryStorage
|
||||
signedPreKeyStore:self.primaryStorage
|
||||
identityStore:self.identityManager
|
||||
error:&error];
|
||||
if (error || !cipher) {
|
||||
OWSFailDebug(@"Could not create secret session cipher: %@", error);
|
||||
error = EnsureDecryptError(error, @"Could not create secret session cipher");
|
||||
return failureBlock(error);
|
||||
}
|
||||
|
||||
SMKDecryptResult *_Nullable decryptResult =
|
||||
[cipher throwswrapped_decryptMessageWithCertificateValidator:certificateValidator
|
||||
cipherTextData:encryptedData
|
||||
timestamp:serverTimestamp
|
||||
localRecipientId:localRecipientId
|
||||
localDeviceId:localDeviceId
|
||||
protocolContext:transaction
|
||||
error:&error];
|
||||
SCKRaiseIfExceptionWrapperError(error);
|
||||
|
||||
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);
|
||||
error = EnsureDecryptError(error, @"Could not decrypt UD message");
|
||||
return failureBlock(error);
|
||||
}
|
||||
|
||||
if (decryptResult.messageType == SMKMessageTypePrekey) {
|
||||
[TSPreKeyManager checkPreKeys];
|
||||
}
|
||||
|
||||
NSString *source = decryptResult.senderRecipientId;
|
||||
if (source.length < 1 || !source.isValidE164) {
|
||||
NSString *errorDescription = @"Invalid UD sender.";
|
||||
OWSFailDebug(@"%@", errorDescription);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
||||
return failureBlock(error);
|
||||
}
|
||||
|
||||
long sourceDeviceId = decryptResult.senderDeviceId;
|
||||
if (sourceDeviceId < 1 || sourceDeviceId > UINT32_MAX) {
|
||||
NSString *errorDescription = @"Invalid UD sender device id.";
|
||||
OWSFailDebug(@"%@", errorDescription);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
||||
return failureBlock(error);
|
||||
}
|
||||
NSData *plaintextData = [decryptResult.paddedPayload removePadding];
|
||||
|
||||
SSKProtoEnvelopeBuilder *envelopeBuilder = [envelope asBuilder];
|
||||
[envelopeBuilder setSource:source];
|
||||
[envelopeBuilder setSourceDevice:(uint32_t)sourceDeviceId];
|
||||
NSData *_Nullable newEnvelopeData = [envelopeBuilder buildSerializedDataAndReturnError:&error];
|
||||
if (error || !newEnvelopeData) {
|
||||
OWSFailDebug(@"Could not update UD envelope data: %@", error);
|
||||
error = EnsureDecryptError(error, @"Could not update UD envelope data");
|
||||
return failureBlock(error);
|
||||
}
|
||||
|
||||
OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:newEnvelopeData
|
||||
plaintextData:plaintextData
|
||||
source:source
|
||||
sourceDevice:(uint32_t)sourceDeviceId
|
||||
isUDMessage:YES];
|
||||
successBlock(result, 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 ud message: %@", exception.description];
|
||||
OWSLogError(@"%@", errorDescription);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
|
||||
failureBlock(error);
|
||||
});
|
||||
NSError *cipherError;
|
||||
SMKSecretSessionCipher *_Nullable cipher =
|
||||
[[SMKSecretSessionCipher alloc] initWithSessionStore:self.primaryStorage
|
||||
preKeyStore:self.primaryStorage
|
||||
signedPreKeyStore:self.primaryStorage
|
||||
identityStore:self.identityManager
|
||||
error:&cipherError];
|
||||
if (cipherError || !cipher) {
|
||||
OWSFailDebug(@"Could not create secret session cipher: %@", cipherError);
|
||||
cipherError = EnsureDecryptError(cipherError, @"Could not create secret session cipher");
|
||||
return failureBlock(cipherError);
|
||||
}
|
||||
|
||||
NSError *decryptError;
|
||||
SMKDecryptResult *_Nullable decryptResult =
|
||||
[cipher throwswrapped_decryptMessageWithCertificateValidator:certificateValidator
|
||||
cipherTextData:encryptedData
|
||||
timestamp:serverTimestamp
|
||||
localRecipientId:localRecipientId
|
||||
localDeviceId:localDeviceId
|
||||
protocolContext:transaction
|
||||
error:&decryptError];
|
||||
|
||||
if (!decryptResult) {
|
||||
if (!decryptError) {
|
||||
OWSFailDebug(@"Caller should provide specific error");
|
||||
NSError *error = OWSErrorWithCodeDescription(
|
||||
OWSErrorCodeFailedToDecryptUDMessage, @"Could not decrypt UD message");
|
||||
return failureBlock(error);
|
||||
}
|
||||
|
||||
// Decrypt Failure Part 1: Unwrap failure details
|
||||
|
||||
NSError *_Nullable underlyingError;
|
||||
SSKProtoEnvelope *_Nullable identifiedEnvelope;
|
||||
|
||||
if (![decryptError.domain isEqualToString:@"SignalMetadataKit.SecretSessionKnownSenderError"]) {
|
||||
underlyingError = decryptError;
|
||||
identifiedEnvelope = envelope;
|
||||
} else {
|
||||
underlyingError = decryptError.userInfo[NSUnderlyingErrorKey];
|
||||
|
||||
NSString *senderRecipientId
|
||||
= decryptError.userInfo[SecretSessionKnownSenderError.kSenderRecipientIdKey];
|
||||
OWSAssert(senderRecipientId);
|
||||
|
||||
NSNumber *senderDeviceId = decryptError.userInfo[SecretSessionKnownSenderError.kSenderDeviceIdKey];
|
||||
OWSAssert(senderDeviceId);
|
||||
|
||||
SSKProtoEnvelopeBuilder *identifiedEnvelopeBuilder = envelope.asBuilder;
|
||||
identifiedEnvelopeBuilder.source = senderRecipientId;
|
||||
identifiedEnvelopeBuilder.sourceDevice = senderDeviceId.unsignedIntValue;
|
||||
NSError *identifiedEnvelopeBuilderError;
|
||||
|
||||
identifiedEnvelope = [identifiedEnvelopeBuilder buildAndReturnError:&identifiedEnvelopeBuilderError];
|
||||
if (identifiedEnvelopeBuilderError) {
|
||||
OWSFailDebug(@"failure identifiedEnvelopeBuilderError: %@", identifiedEnvelopeBuilderError);
|
||||
}
|
||||
}
|
||||
OWSAssert(underlyingError);
|
||||
OWSAssert(identifiedEnvelope);
|
||||
|
||||
NSException *_Nullable underlyingException;
|
||||
if ([underlyingError.domain isEqualToString:SCKExceptionWrapperErrorDomain]
|
||||
&& underlyingError.code == SCKExceptionWrapperErrorThrown) {
|
||||
|
||||
underlyingException = underlyingError.userInfo[SCKExceptionWrapperUnderlyingExceptionKey];
|
||||
OWSAssert(underlyingException);
|
||||
}
|
||||
|
||||
// Decrypt Failure Part 2: Handle unwrapped failure details
|
||||
|
||||
if (underlyingException) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
[self processException:underlyingException envelope:identifiedEnvelope];
|
||||
NSString *errorDescription = [NSString
|
||||
stringWithFormat:@"Exception while decrypting ud message: %@", underlyingException.description];
|
||||
OWSLogError(@"%@", errorDescription);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
|
||||
failureBlock(error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if ([underlyingError.domain isEqualToString:@"SignalMetadataKit.SMKSecretSessionCipherError"]
|
||||
&& underlyingError.code == SMKSecretSessionCipherErrorSelfSentMessage) {
|
||||
// Self-sent messages can be safely discarded.
|
||||
failureBlock(underlyingError);
|
||||
return;
|
||||
}
|
||||
|
||||
OWSFailDebug(@"Could not decrypt UD message: %@", underlyingError);
|
||||
failureBlock(underlyingError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (decryptResult.messageType == SMKMessageTypePrekey) {
|
||||
[TSPreKeyManager checkPreKeys];
|
||||
}
|
||||
|
||||
NSString *source = decryptResult.senderRecipientId;
|
||||
if (source.length < 1 || !source.isValidE164) {
|
||||
NSString *errorDescription = @"Invalid UD sender.";
|
||||
OWSFailDebug(@"%@", errorDescription);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
||||
return failureBlock(error);
|
||||
}
|
||||
|
||||
long sourceDeviceId = decryptResult.senderDeviceId;
|
||||
if (sourceDeviceId < 1 || sourceDeviceId > UINT32_MAX) {
|
||||
NSString *errorDescription = @"Invalid UD sender device id.";
|
||||
OWSFailDebug(@"%@", errorDescription);
|
||||
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
||||
return failureBlock(error);
|
||||
}
|
||||
NSData *plaintextData = [decryptResult.paddedPayload removePadding];
|
||||
|
||||
SSKProtoEnvelopeBuilder *envelopeBuilder = [envelope asBuilder];
|
||||
[envelopeBuilder setSource:source];
|
||||
[envelopeBuilder setSourceDevice:(uint32_t)sourceDeviceId];
|
||||
NSError *envelopeBuilderError;
|
||||
NSData *_Nullable newEnvelopeData = [envelopeBuilder buildSerializedDataAndReturnError:&envelopeBuilderError];
|
||||
if (envelopeBuilderError || !newEnvelopeData) {
|
||||
OWSFailDebug(@"Could not update UD envelope data: %@", envelopeBuilderError);
|
||||
NSError *error = EnsureDecryptError(envelopeBuilderError, @"Could not update UD envelope data");
|
||||
return failureBlock(error);
|
||||
}
|
||||
|
||||
OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:newEnvelopeData
|
||||
plaintextData:plaintextData
|
||||
source:source
|
||||
sourceDevice:(uint32_t)sourceDeviceId
|
||||
isUDMessage:YES];
|
||||
successBlock(result, transaction);
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue