|
|
@ -84,12 +84,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
#pragma mark - Decryption
|
|
|
|
#pragma mark - Decryption
|
|
|
|
|
|
|
|
|
|
|
|
- (void)decryptEnvelope:(SSKProtoEnvelope *)envelope
|
|
|
|
- (void)decryptEnvelope:(SSKProtoEnvelope *)envelope
|
|
|
|
envelopeData:(NSData *)envelopeData
|
|
|
|
envelopeData:(NSData *)envelopeDataOriginal
|
|
|
|
successBlock:(DecryptSuccessBlock)successBlockParameter
|
|
|
|
successBlock:(DecryptSuccessBlock)successBlockParameter
|
|
|
|
failureBlock:(DecryptFailureBlock)failureBlockParameter
|
|
|
|
failureBlock:(DecryptFailureBlock)failureBlockParameter
|
|
|
|
{
|
|
|
|
{
|
|
|
|
OWSAssertDebug(envelope);
|
|
|
|
OWSAssertDebug(envelope);
|
|
|
|
OWSAssertDebug(envelopeData);
|
|
|
|
OWSAssertDebug(envelopeDataOriginal);
|
|
|
|
OWSAssertDebug(successBlockParameter);
|
|
|
|
OWSAssertDebug(successBlockParameter);
|
|
|
|
OWSAssertDebug(failureBlockParameter);
|
|
|
|
OWSAssertDebug(failureBlockParameter);
|
|
|
|
OWSAssertDebug([TSAccountManager isRegistered]);
|
|
|
|
OWSAssertDebug([TSAccountManager isRegistered]);
|
|
|
@ -105,14 +105,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
DecryptSuccessBlock successBlock
|
|
|
|
DecryptSuccessBlock successBlock
|
|
|
|
= ^(NSData *envelopeData, NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
= ^(NSData *envelopeDataFinal, NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
// Having received a valid (decryptable) message from this user,
|
|
|
|
// Having received a valid (decryptable) message from this user,
|
|
|
|
// make note of the fact that they have a valid Signal account.
|
|
|
|
// make note of the fact that they have a valid Signal account.
|
|
|
|
[SignalRecipient markRecipientAsRegistered:envelope.source
|
|
|
|
[SignalRecipient markRecipientAsRegistered:envelope.source
|
|
|
|
deviceId:envelope.sourceDevice
|
|
|
|
deviceId:envelope.sourceDevice
|
|
|
|
transaction:transaction];
|
|
|
|
transaction:transaction];
|
|
|
|
|
|
|
|
|
|
|
|
successBlockParameter(envelopeData, plaintextData, transaction);
|
|
|
|
successBlockParameter(envelopeDataFinal, plaintextData, transaction);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
@try {
|
|
|
|
@try {
|
|
|
@ -128,12 +128,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
switch (envelope.type) {
|
|
|
|
switch (envelope.type) {
|
|
|
|
case SSKProtoEnvelopeTypeCiphertext: {
|
|
|
|
case SSKProtoEnvelopeTypeCiphertext: {
|
|
|
|
[self decryptSecureMessage:envelope
|
|
|
|
[self decryptSecureMessage:envelope
|
|
|
|
envelopeData:envelopeData
|
|
|
|
envelopeData:envelopeDataOriginal
|
|
|
|
successBlock:^(NSData *envelopeData,
|
|
|
|
successBlock:^(NSData *envelopeDataFinal,
|
|
|
|
NSData *_Nullable plaintextData,
|
|
|
|
NSData *_Nullable plaintextData,
|
|
|
|
YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
OWSLogDebug(@"decrypted secure message.");
|
|
|
|
OWSLogDebug(@"decrypted secure message.");
|
|
|
|
successBlock(envelopeData, plaintextData, transaction);
|
|
|
|
successBlock(envelopeDataFinal, plaintextData, transaction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
failureBlock:^(NSError *_Nullable error) {
|
|
|
|
failureBlock:^(NSError *_Nullable error) {
|
|
|
|
OWSLogError(@"decrypting secure message from address: %@ failed with error: %@",
|
|
|
|
OWSLogError(@"decrypting secure message from address: %@ failed with error: %@",
|
|
|
@ -147,12 +147,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case SSKProtoEnvelopeTypePrekeyBundle: {
|
|
|
|
case SSKProtoEnvelopeTypePrekeyBundle: {
|
|
|
|
[self decryptPreKeyBundle:envelope
|
|
|
|
[self decryptPreKeyBundle:envelope
|
|
|
|
envelopeData:envelopeData
|
|
|
|
envelopeData:envelopeDataOriginal
|
|
|
|
successBlock:^(NSData *envelopeData,
|
|
|
|
successBlock:^(NSData *envelopeDataFinal,
|
|
|
|
NSData *_Nullable plaintextData,
|
|
|
|
NSData *_Nullable plaintextData,
|
|
|
|
YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
OWSLogDebug(@"decrypted pre-key whisper message");
|
|
|
|
OWSLogDebug(@"decrypted pre-key whisper message");
|
|
|
|
successBlock(envelopeData, plaintextData, transaction);
|
|
|
|
successBlock(envelopeDataFinal, plaintextData, transaction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
failureBlock:^(NSError *_Nullable error) {
|
|
|
|
failureBlock:^(NSError *_Nullable error) {
|
|
|
|
OWSLogError(@"decrypting pre-key whisper message from address: %@ failed "
|
|
|
|
OWSLogError(@"decrypting pre-key whisper message from address: %@ failed "
|
|
|
@ -170,18 +170,18 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
case SSKProtoEnvelopeTypeKeyExchange:
|
|
|
|
case SSKProtoEnvelopeTypeKeyExchange:
|
|
|
|
case SSKProtoEnvelopeTypeUnknown: {
|
|
|
|
case SSKProtoEnvelopeTypeUnknown: {
|
|
|
|
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
successBlock(envelopeData, nil, transaction);
|
|
|
|
successBlock(envelopeDataOriginal, nil, transaction);
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
// Return to avoid double-acknowledging.
|
|
|
|
// Return to avoid double-acknowledging.
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case SSKProtoEnvelopeTypeUnidentifiedSender: {
|
|
|
|
case SSKProtoEnvelopeTypeUnidentifiedSender: {
|
|
|
|
[self decryptUnidentifiedSender:envelope
|
|
|
|
[self decryptUnidentifiedSender:envelope
|
|
|
|
successBlock:^(NSData *envelopeData,
|
|
|
|
successBlock:^(NSData *envelopeDataFinal,
|
|
|
|
NSData *_Nullable plaintextData,
|
|
|
|
NSData *_Nullable plaintextData,
|
|
|
|
YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
OWSLogDebug(@"decrypted unidentified sender message");
|
|
|
|
OWSLogDebug(@"decrypted unidentified sender message");
|
|
|
|
successBlock(envelopeData, plaintextData, transaction);
|
|
|
|
successBlock(envelopeDataFinal, plaintextData, transaction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
failureBlock:^(NSError *_Nullable error) {
|
|
|
|
failureBlock:^(NSError *_Nullable error) {
|
|
|
|
OWSLogError(@"decrypting unidentified sender message from address: %@ failed "
|
|
|
|
OWSLogError(@"decrypting unidentified sender message from address: %@ failed "
|
|
|
@ -277,8 +277,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
NSData *encryptedData = envelope.content ?: envelope.legacyMessage;
|
|
|
|
NSData *encryptedData = envelope.content ?: envelope.legacyMessage;
|
|
|
|
if (!encryptedData) {
|
|
|
|
if (!encryptedData) {
|
|
|
|
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
|
|
|
|
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
|
|
|
|
failureBlock(nil);
|
|
|
|
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, @"Envelope has no content");
|
|
|
|
return;
|
|
|
|
return failureBlock(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[self.dbConnection
|
|
|
|
[self.dbConnection
|
|
|
@ -323,29 +323,22 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
// NOTE: We don't need to bother with `legacyMessage` for UD messages.
|
|
|
|
// NOTE: We don't need to bother with `legacyMessage` for UD messages.
|
|
|
|
NSData *encryptedData = envelope.content;
|
|
|
|
NSData *encryptedData = envelope.content;
|
|
|
|
if (!encryptedData) {
|
|
|
|
if (!encryptedData) {
|
|
|
|
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
|
|
|
|
NSString *errorDescription = @"UD Envelope is missing content.";
|
|
|
|
failureBlock(nil);
|
|
|
|
OWSFailDebug(@"%@", errorDescription);
|
|
|
|
return;
|
|
|
|
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
|
|
|
|
|
|
|
return failureBlock(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!envelope.hasServerTimestamp) {
|
|
|
|
if (!envelope.hasServerTimestamp) {
|
|
|
|
OWSProdFail(@"UD Envelope is missing server timestamp.");
|
|
|
|
NSString *errorDescription = @"UD Envelope is missing server timestamp.";
|
|
|
|
failureBlock(nil);
|
|
|
|
OWSFailDebug(@"%@", errorDescription);
|
|
|
|
return;
|
|
|
|
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
|
|
|
|
|
|
|
return failureBlock(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UInt64 serverTimestamp = envelope.serverTimestamp;
|
|
|
|
UInt64 serverTimestamp = envelope.serverTimestamp;
|
|
|
|
|
|
|
|
|
|
|
|
NSData *_Nullable trustRootData = [NSData dataFromBase64String:kUDTrustRoot];
|
|
|
|
|
|
|
|
OWSAssert(trustRootData);
|
|
|
|
|
|
|
|
NSError *error;
|
|
|
|
|
|
|
|
ECPublicKey *_Nullable trustRoot = [[ECPublicKey alloc] initWithKeyData:trustRootData error:&error];
|
|
|
|
|
|
|
|
if (error || !trustRoot) {
|
|
|
|
|
|
|
|
OWSProdFail(@"Invalid UD trust root.");
|
|
|
|
|
|
|
|
failureBlock(nil);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
id<SMKCertificateValidator> certificateValidator =
|
|
|
|
id<SMKCertificateValidator> certificateValidator =
|
|
|
|
[[SMKCertificateDefaultValidator alloc] initWithTrustRoot:trustRoot];
|
|
|
|
[[SMKCertificateDefaultValidator alloc] initWithTrustRoot:self.trustRoot];
|
|
|
|
|
|
|
|
|
|
|
|
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
@try {
|
|
|
|
@try {
|
|
|
@ -357,10 +350,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
identityStore:self.identityManager
|
|
|
|
identityStore:self.identityManager
|
|
|
|
error:&error];
|
|
|
|
error:&error];
|
|
|
|
if (error || !cipher) {
|
|
|
|
if (error || !cipher) {
|
|
|
|
NSString *errorDescription =
|
|
|
|
OWSFailDebug(@"%@", @"Could not create secret session cipher: %@", error);
|
|
|
|
[NSString stringWithFormat:@"Could not create secret session cipher: %@", error];
|
|
|
|
|
|
|
|
OWSFailDebug(@"%@", errorDescription);
|
|
|
|
|
|
|
|
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
|
|
|
|
|
|
|
|
return failureBlock(error);
|
|
|
|
return failureBlock(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -370,16 +360,24 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
timestamp:serverTimestamp
|
|
|
|
timestamp:serverTimestamp
|
|
|
|
protocolContext:transaction
|
|
|
|
protocolContext:transaction
|
|
|
|
error:&error];
|
|
|
|
error:&error];
|
|
|
|
|
|
|
|
if (error || !decryptResult) {
|
|
|
|
|
|
|
|
OWSFailDebug(@"%@", @"Could not decrypt UD message: %@", error);
|
|
|
|
|
|
|
|
return failureBlock(error);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NSString *source = decryptResult.senderRecipientId;
|
|
|
|
NSString *source = decryptResult.senderRecipientId;
|
|
|
|
if (source.length < 1) {
|
|
|
|
if (source.length < 1) {
|
|
|
|
OWSProdFail(@"Invalid UD source.");
|
|
|
|
NSString *errorDescription = @"Invalid UD sender.";
|
|
|
|
return failureBlock(nil);
|
|
|
|
OWSFailDebug(@"%@", errorDescription);
|
|
|
|
|
|
|
|
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
|
|
|
|
|
|
|
return failureBlock(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
long sourceDeviceId = decryptResult.senderDeviceId;
|
|
|
|
long sourceDeviceId = decryptResult.senderDeviceId;
|
|
|
|
if (sourceDeviceId < 1 || sourceDeviceId > UINT32_MAX) {
|
|
|
|
if (sourceDeviceId < 1 || sourceDeviceId > UINT32_MAX) {
|
|
|
|
OWSProdFail(@"Invalid UD sender device id.");
|
|
|
|
NSString *errorDescription = @"Invalid UD sender device id.";
|
|
|
|
return failureBlock(nil);
|
|
|
|
OWSFailDebug(@"%@", errorDescription);
|
|
|
|
|
|
|
|
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptUDMessage, errorDescription);
|
|
|
|
|
|
|
|
return failureBlock(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NSData *plaintextData = [decryptResult.paddedPayload removePadding];
|
|
|
|
NSData *plaintextData = [decryptResult.paddedPayload removePadding];
|
|
|
|
|
|
|
|
|
|
|
@ -409,6 +407,19 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (ECPublicKey *)trustRoot
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
NSData *_Nullable trustRootData = [NSData dataFromBase64String:kUDTrustRoot];
|
|
|
|
|
|
|
|
OWSAssert(trustRootData);
|
|
|
|
|
|
|
|
NSError *error;
|
|
|
|
|
|
|
|
ECPublicKey *_Nullable trustRoot = [[ECPublicKey alloc] initWithKeyData:trustRootData error:&error];
|
|
|
|
|
|
|
|
if (error || !trustRoot) {
|
|
|
|
|
|
|
|
// This exits.
|
|
|
|
|
|
|
|
OWSFail(@"Invalid UD trust root.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return trustRoot;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)processException:(NSException *)exception envelope:(SSKProtoEnvelope *)envelope
|
|
|
|
- (void)processException:(NSException *)exception envelope:(SSKProtoEnvelope *)envelope
|
|
|
|
{
|
|
|
|
{
|
|
|
|
OWSLogError(
|
|
|
|
OWSLogError(
|
|
|
|