You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-ios/src/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivi...

139 lines
4.6 KiB
Matlab

//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
10 years ago
#import "TSInvalidIdentityKeyReceivingErrorMessage.h"
#import "OWSFingerprint.h"
#import "TSContactThread.h"
10 years ago
#import "TSDatabaseView.h"
#import "TSErrorMessage_privateConstructor.h"
#import "TSMessagesManager.h"
#import "TSStorageManager+IdentityKeyStore.h"
#import "TSStorageManager.h"
#import <AxolotlKit/NSData+keyVersionByte.h>
#import <AxolotlKit/PreKeyWhisperMessage.h>
#import <YapDatabase/YapDatabaseTransaction.h>
#import <YapDatabase/YapDatabaseView.h>
10 years ago
NS_ASSUME_NONNULL_BEGIN
@interface TSInvalidIdentityKeyReceivingErrorMessage ()
@property (nonatomic, readonly, copy) NSString *authorId;
@end
@implementation TSInvalidIdentityKeyReceivingErrorMessage {
// Not using a property declaration in order to exclude from DB serialization
OWSSignalServiceProtosEnvelope *_envelope;
10 years ago
}
@synthesize envelopeData = _envelopeData;
+ (instancetype)untrustedKeyWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
10 years ago
TSContactThread *contactThread =
[TSContactThread getOrCreateThreadWithContactId:envelope.source transaction:transaction];
10 years ago
TSInvalidIdentityKeyReceivingErrorMessage *errorMessage =
[[self alloc] initForUnknownIdentityKeyWithTimestamp:envelope.timestamp
10 years ago
inThread:contactThread
incomingEnvelope:envelope];
10 years ago
return errorMessage;
}
- (instancetype)initForUnknownIdentityKeyWithTimestamp:(uint64_t)timestamp
inThread:(TSThread *)thread
incomingEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
{
self = [self initWithTimestamp:timestamp inThread:thread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
if (!self) {
return self;
10 years ago
}
_envelopeData = envelope.data;
_authorId = envelope.source;
10 years ago
return self;
}
10 years ago
- (OWSSignalServiceProtosEnvelope *)envelope
{
if (!_envelope) {
_envelope = [OWSSignalServiceProtosEnvelope parseFromData:self.envelopeData];
}
return _envelope;
}
10 years ago
- (void)acceptNewIdentityKey
{
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey) {
DDLogError(@"Refusing to accept identity key for anything but a Key error.");
return;
}
10 years ago
NSData *newKey = [self newIdentityKey];
if (!newKey) {
DDLogError(@"Couldn't extract identity key to accept");
return;
}
10 years ago
// Saving a new identity mutates the session store so it must happen on the sessionStoreQueue
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[[TSStorageManager sharedManager] saveRemoteIdentity:newKey recipientId:self.envelope.source];
dispatch_async(dispatch_get_main_queue(), ^{
// Decrypt this and any old messages for the newly accepted key
NSArray<TSInvalidIdentityKeyReceivingErrorMessage *> *messagesToDecrypt =
[self.thread receivedMessagesForInvalidKey:newKey];
for (TSInvalidIdentityKeyReceivingErrorMessage *errorMessage in messagesToDecrypt) {
[[TSMessagesManager sharedManager] handleReceivedEnvelope:errorMessage.envelope];
// Here we remove the existing error message because handleReceivedEnvelope will either
// 1.) succeed and create a new successful message in the thread or...
// 2.) fail and create a new identical error message in the thread.
[errorMessage remove];
}
});
});
10 years ago
}
- (NSData *)newIdentityKey
{
if (!self.envelope) {
DDLogError(@"Error message had no envelope data to extract key from");
return nil;
}
if (self.envelope.type != OWSSignalServiceProtosEnvelopeTypePrekeyBundle) {
DDLogError(@"Refusing to attempt key extraction from an envelope which isn't a prekey bundle");
return nil;
10 years ago
}
// DEPRECATED - Remove after all clients have been upgraded.
NSData *pkwmData = self.envelope.hasContent ? self.envelope.content : self.envelope.legacyMessage;
if (!pkwmData) {
DDLogError(@"Ignoring acceptNewIdentityKey for empty message");
return nil;
}
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:pkwmData];
return [message.identityKey removeKeyType];
}
10 years ago
- (NSString *)theirSignalId
{
if (self.authorId) {
return self.authorId;
} else {
// for existing messages before we were storing author id.
return self.envelope.source;
}
10 years ago
}
@end
NS_ASSUME_NONNULL_END