mirror of https://github.com/oxen-io/session-ios
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.
125 lines
5.3 KiB
Objective-C
125 lines
5.3 KiB
Objective-C
//
|
|
// TSErrorMessage.m
|
|
// TextSecureKit
|
|
//
|
|
// Created by Frederic Jacobs on 12/11/14.
|
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
#import "TSErrorMessage.h"
|
|
#import "NSDate+millisecondTimeStamp.h"
|
|
#import "TSStorageManager+IdentityKeyStore.h"
|
|
#import <AxolotlKit/PreKeyWhisperMessage.h>
|
|
#import <AxolotlKit/NSData+keyVersionByte.h>
|
|
#import "TSMessagesManager.h"
|
|
#import "TSFingerprintGenerator.h"
|
|
|
|
@interface TSErrorMessage()
|
|
@property NSData *pushSignal;
|
|
@end
|
|
|
|
@implementation TSErrorMessage
|
|
|
|
- (instancetype)initForUnknownIdentityKeyWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread incomingPushSignal:(NSData*)signal{
|
|
self = [self initWithTimestamp:timestamp inThread:thread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
|
|
|
|
if (self) {
|
|
_pushSignal = signal;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType{
|
|
self = [super initWithTimestamp:timestamp inThread:thread messageBody:nil attachements:nil];
|
|
|
|
if (self) {
|
|
_errorType = errorMessageType;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (instancetype)initWithSignal:(IncomingPushMessageSignal*)signal transaction:(YapDatabaseReadWriteTransaction*)transaction failedMessageType:(TSErrorMessageType)errorMessageType{
|
|
TSContactThread *contactThread = [TSContactThread threadWithContactId:signal.source transaction:transaction];
|
|
return [self initWithTimestamp:signal.timestamp inThread:contactThread failedMessageType:errorMessageType];
|
|
}
|
|
|
|
- (NSString*)description{
|
|
switch (_errorType) {
|
|
case TSErrorMessageNoSession:
|
|
return @"No available session for contact";
|
|
case TSErrorMessageMissingKeyId:
|
|
return @"Received a message with unknown PreKey";
|
|
case TSErrorMessageInvalidMessage:
|
|
return @"Received a corrupted message";
|
|
case TSErrorMessageInvalidVersion:
|
|
return @"Received a message not compatible with this version";
|
|
case TSErrorMessageDuplicateMessage:
|
|
return @"Received a duplicated message";
|
|
case TSErrorMessageInvalidKeyException:
|
|
return @"The recipient's key is not valid.";
|
|
case TSErrorMessageWrongTrustedIdentityKey:
|
|
return @"Identity key changed. Tap to verify new key.";
|
|
default:
|
|
return @"An unknown error occured";
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ (instancetype)corruptedMessageWithSignal:(IncomingPushMessageSignal *)signal withTransaction:(YapDatabaseReadWriteTransaction *)transaction{
|
|
return [[self alloc] initWithSignal:signal transaction:transaction failedMessageType:TSErrorMessageInvalidMessage];
|
|
}
|
|
|
|
+ (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)signal withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
|
return [[self alloc] initWithSignal:signal transaction:transaction failedMessageType:TSErrorMessageInvalidVersion];
|
|
}
|
|
|
|
+ (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)signal withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
|
return [[self alloc] initWithSignal:signal transaction:transaction failedMessageType:TSErrorMessageMissingKeyId];
|
|
}
|
|
|
|
+ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)signal withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
|
return [[self alloc] initWithSignal:signal transaction:transaction failedMessageType:TSErrorMessageInvalidKeyException];
|
|
}
|
|
|
|
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
|
TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction];
|
|
TSErrorMessage *errorMessage = [[self alloc] initForUnknownIdentityKeyWithTimestamp:preKeyMessage.timestamp inThread:contactThread incomingPushSignal:preKeyMessage.data];
|
|
return errorMessage;
|
|
}
|
|
|
|
+ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)signal withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
|
return [[self alloc] initWithSignal:signal transaction:transaction failedMessageType:TSErrorMessageNoSession];
|
|
}
|
|
|
|
- (void)acceptNewIdentityKey{
|
|
if (_errorType != TSErrorMessageWrongTrustedIdentityKey || !_pushSignal) {
|
|
return;
|
|
}
|
|
|
|
TSStorageManager *storage = [TSStorageManager sharedManager];
|
|
IncomingPushMessageSignal *signal = [IncomingPushMessageSignal parseFromData:_pushSignal];
|
|
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:signal.message];
|
|
NSData *newKey = [message.identityKey removeKeyType];
|
|
|
|
[storage saveRemoteIdentity:newKey recipientId:signal.source];
|
|
|
|
[[TSMessagesManager sharedManager] handleMessageSignal:signal];
|
|
//TODO: Decrypt any other messages encrypted with that new identity key automatically.
|
|
}
|
|
|
|
- (NSString *)newIdentityKey{
|
|
if (_errorType != TSErrorMessageWrongTrustedIdentityKey || !_pushSignal) {
|
|
return @"";
|
|
}
|
|
|
|
IncomingPushMessageSignal *signal = [IncomingPushMessageSignal parseFromData:_pushSignal];
|
|
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:signal.message];
|
|
NSData *identityKey = [message.identityKey removeKeyType];
|
|
|
|
return [TSFingerprintGenerator getFingerprintForDisplay:identityKey];
|
|
}
|
|
|
|
@end
|