- Sublassing errors in case of expected behaviour
- When receiving a new message that was using a previously unknown
identity key, we search for any other messages that are encrypted with
the new accepted key and decrypt those too.
- Addressing some of the warnings we had before.
This commit is contained in:
Frederic Jacobs 2014-12-31 21:30:20 +01:00
parent 4cb3231bb1
commit eff589af93
16 changed files with 189 additions and 107 deletions

View file

@ -4,10 +4,10 @@ inhibit_all_warnings!
link_with ["Signal", "SignalTests"]
pod 'SocketRocket', :git => 'https://github.com/square/SocketRocket.git', :commit => 'd0585af165'
pod 'SocketRocket', :git => 'https://github.com/square/SocketRocket.git', :commit => '954750c018'
pod 'OpenSSL', '~> 1.0.110'
pod 'libPhoneNumber-iOS', '~> 0.7'
pod 'AxolotlKit', '~> 0.3'
pod 'AxolotlKit', '~> 0.5'
pod 'PastelogKit', '~> 1.2'
pod 'TwistedOakCollapsingFutures','~> 1.0'
pod 'YapDatabase/SQLCipher'

View file

@ -21,7 +21,7 @@ PODS:
- AFNetworking/UIKit (2.5.0):
- AFNetworking/NSURLConnection
- AFNetworking/NSURLSession
- AxolotlKit (0.3):
- AxolotlKit (0.5):
- 25519 (~> 1.8)
- HKDFKit (~> 0.0.3)
- ProtocolBuffers (~> 1.9.2)
@ -59,14 +59,14 @@ PODS:
DEPENDENCIES:
- AFNetworking (~> 2.5)
- AxolotlKit (~> 0.3)
- AxolotlKit (~> 0.5)
- DJWActionSheet
- JSQMessagesViewController (from `https://github.com/dtsbourg/JSQMessagesViewController`, branch `JSignalQ`)
- libPhoneNumber-iOS (~> 0.7)
- Mantle (~> 1.5)
- OpenSSL (~> 1.0.110)
- PastelogKit (~> 1.2)
- SocketRocket (from `https://github.com/square/SocketRocket.git`, commit `d0585af165`)
- SocketRocket (from `https://github.com/square/SocketRocket.git`, commit `954750c018`)
- SSKeychain
- TwistedOakCollapsingFutures (~> 1.0)
- YapDatabase/SQLCipher
@ -76,7 +76,7 @@ EXTERNAL SOURCES:
:branch: JSignalQ
:git: https://github.com/dtsbourg/JSQMessagesViewController
SocketRocket:
:commit: d0585af165
:commit: 954750c018
:git: https://github.com/square/SocketRocket.git
CHECKOUT OPTIONS:
@ -84,13 +84,13 @@ CHECKOUT OPTIONS:
:commit: ed9858bd6df609bba83b21a029701cbf13682981
:git: https://github.com/dtsbourg/JSQMessagesViewController
SocketRocket:
:commit: d0585af165
:commit: 954750c018
:git: https://github.com/square/SocketRocket.git
SPEC CHECKSUMS:
25519: 601ffb5d258aa33d642062d6fa4096db210e02e7
AFNetworking: 0f54cb5d16ce38c1b76948faffb8d5fb705021c7
AxolotlKit: 19a7a6482e3deb6621e0f81a1733f60301802d40
AxolotlKit: eec4d036d5b021258dc8b6b0212f3c04edeaf15b
CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817
DJWActionSheet: d88b302d7c29523e1e9fb9b62cfac46f59bb90d9
HKDFKit: 5998cf1bbb611e7ecc6bd3eaaef8c7a7da7be949

2
Pods

@ -1 +1 @@
Subproject commit 94599a4564daeec5315e99bfae427f798925b0b2
Subproject commit 53c2e1ee892acb702b48f16ec8e63a0ea4d0fff4

View file

@ -353,6 +353,7 @@
B68112ED1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m in Sources */ = {isa = PBXBuildFile; fileRef = B68112EC1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m */; };
B684A46D19C3446200B11029 /* PushManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B684A46C19C3446200B11029 /* PushManagerTest.m */; };
B6850E5A1995A4710068E715 /* whisperFake.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6850E591995A4710068E715 /* whisperFake.cer */; };
B68B0E8A1A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = B68B0E891A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m */; };
B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; };
B6A3EB4B1A423B3800B2236B /* TSAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A3EB4A1A423B3800B2236B /* TSAttachmentAdapter.m */; };
B6AE33BD1A1EB121003DF39D /* GroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B6AE33BC1A1EB121003DF39D /* GroupModel.m */; };
@ -519,7 +520,7 @@
FCAC963C19FEF9280046DFC5 /* SignalsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC963B19FEF9280046DFC5 /* SignalsViewController.m */; };
FCAC964019FEF99A0046DFC5 /* InboxTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC963E19FEF99A0046DFC5 /* InboxTableViewCell.m */; };
FCAC964119FEF99A0046DFC5 /* InboxTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FCAC963F19FEF99A0046DFC5 /* InboxTableViewCell.xib */; };
FCAC965119FF0A6E0046DFC5 /* MessagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC965019FF0A6E0046DFC5 /* MessagesViewController.m */; };
FCAC965119FF0A6E0046DFC5 /* MessagesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAC965019FF0A6E0046DFC5 /* MessagesViewController.m */; settings = {COMPILER_FLAGS = "-Wno-receiver-is-weak"; }; };
FCAFC33F1A0F948F00AE5136 /* ActionContactDetailCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FCAFC33E1A0F948F00AE5136 /* ActionContactDetailCell.m */; };
FCB11D8A1A1284BB002F93FB /* SettingsTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FCB11D891A1284BB002F93FB /* SettingsTableViewCell.m */; };
FCB11D8C1A129A76002F93FB /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCB11D8B1A129A76002F93FB /* CoreMedia.framework */; };
@ -986,6 +987,9 @@
B68112EC1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "JSQMessagesCollectionViewCell+menuBarItems.m"; path = "views/JSQMessagesCollectionViewCell+menuBarItems.m"; sourceTree = "<group>"; };
B684A46C19C3446200B11029 /* PushManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PushManagerTest.m; path = Signal/test/push/PushManagerTest.m; sourceTree = SOURCE_ROOT; };
B6850E591995A4710068E715 /* whisperFake.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperFake.cer; sourceTree = "<group>"; };
B68B0E881A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInvalidIdentityKeyErrorMessage.h; sourceTree = "<group>"; };
B68B0E891A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSInvalidIdentityKeyErrorMessage.m; sourceTree = "<group>"; };
B68B0E8D1A542AD700DE8A02 /* TSErrorMessage_privateConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSErrorMessage_privateConstructor.h; sourceTree = "<group>"; };
B69CD25019773E79005CE69A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
B6A3EB491A423B3800B2236B /* TSAttachmentAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAttachmentAdapter.h; sourceTree = "<group>"; };
B6A3EB4A1A423B3800B2236B /* TSAttachmentAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachmentAdapter.m; sourceTree = "<group>"; };
@ -2375,7 +2379,10 @@
B6B096051A1D25ED008BFAA6 /* TSCall.h */,
B6B096061A1D25ED008BFAA6 /* TSCall.m */,
B6B096071A1D25ED008BFAA6 /* TSErrorMessage.h */,
B68B0E8D1A542AD700DE8A02 /* TSErrorMessage_privateConstructor.h */,
B6B096081A1D25ED008BFAA6 /* TSErrorMessage.m */,
B68B0E881A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.h */,
B68B0E891A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m */,
B6B0960B1A1D25ED008BFAA6 /* TSIncomingMessage.h */,
B6B0960C1A1D25ED008BFAA6 /* TSIncomingMessage.m */,
B6B0960D1A1D25ED008BFAA6 /* TSInfoMessage.h */,
@ -3144,6 +3151,7 @@
76EB05EC18170B33006006FC /* CallState.m in Sources */,
76EB05D218170B33006006FC /* ZrtpInitiator.m in Sources */,
76EB05E018170B33006006FC /* NetworkStream.m in Sources */,
B68B0E8A1A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m in Sources */,
B6B0968A1A1D25ED008BFAA6 /* TSStorageManager+SessionStore.m in Sources */,
FCFA64B71A24F6730007FB87 /* UIFont+OWS.m in Sources */,
B6B096891A1D25ED008BFAA6 /* TSStorageManager+PreKeyStore.m in Sources */,

View file

@ -156,15 +156,20 @@
-(BOOL) application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation {
if ([url.scheme isEqualToString:@"sgnl"]) {
if ([url.host hasPrefix:@"verify"] && ![TSAccountManager isRegistered]) {
UIViewController *controller = [[Environment getCurrent].signUpFlowNavigationController.childViewControllers lastObject];
if ([controller isKindOfClass:[CodeVerificationViewController class]]) {
CodeVerificationViewController *cvvc = (CodeVerificationViewController*)controller;
NSString *verificationCode = [url.path substringFromIndex:1];
id signupController = [Environment getCurrent].signUpFlowNavigationController;
if ([signupController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navController = (UINavigationController*)signupController;
UIViewController *controller = [navController.childViewControllers lastObject];
if ([controller isKindOfClass:[CodeVerificationViewController class]]) {
CodeVerificationViewController *cvvc = (CodeVerificationViewController*)controller;
NSString *verificationCode = [url.path substringFromIndex:1];
cvvc.challengeTextField.text = verificationCode;
[cvvc verifyChallengeAction:nil];
} else{
DDLogWarn(@"Not the verification view controller we expected. Got %@ instead", NSStringFromClass(controller.class));
}
cvvc.challengeTextField.text = verificationCode;
[cvvc verifyChallengeAction:nil];
} else{
DDLogWarn(@"Not the verification view controller we expected. Got %@ instead", NSStringFromClass(controller.class));
}
} else{
DDLogWarn(@"Application opened with an unknown URL action: %@", url.host);
@ -200,7 +205,7 @@
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if ([self isRedPhonePush:userInfo]) {
[self application:application didReceiveRemoteNotification:userInfo];
} else {

View file

@ -11,13 +11,13 @@
*/
@interface ResponderSessionDescriptor : NSObject
@property (nonatomic,readonly) int32_t interopVersion;
@property (nonatomic,readonly) NSUInteger interopVersion;
@property (nonatomic,readonly) in_port_t relayUdpPort;
@property (nonatomic,readonly) int64_t sessionId;
@property (nonatomic,readonly) NSString* relayServerName;
@property (nonatomic,readonly) PhoneNumber* initiatorNumber;
+(ResponderSessionDescriptor*)responderSessionDescriptorWithInteropVersion:(int32_t)interopVersion
+(ResponderSessionDescriptor*)responderSessionDescriptorWithInteropVersion:(NSUInteger)interopVersion
andRelayUdpPort:(in_port_t)relayUdpPort
andSessionId:(int64_t)sessionId
andRelayServerName:(NSString*)relayServerName

View file

@ -28,7 +28,7 @@
@synthesize initiatorNumber;
@synthesize interopVersion;
+(ResponderSessionDescriptor*)responderSessionDescriptorWithInteropVersion:(int32_t)interopVersion
+(ResponderSessionDescriptor*)responderSessionDescriptorWithInteropVersion:(NSUInteger)interopVersion
andRelayUdpPort:(in_port_t)relayUdpPort
andSessionId:(int64_t)sessionId
andRelayServerName:(NSString*)relayServerName
@ -72,8 +72,8 @@
checkOperation(parsedPayload.initiator != nil);
checkOperation(parsedPayload.serverName != nil);
unsigned int interopVersion = parsedPayload.version;
unsigned long long sessionId = parsedPayload.sessionId;
NSUInteger interopVersion = parsedPayload.version;
int64_t sessionId = (int64_t)parsedPayload.sessionId;
in_port_t relayUdpPort = (in_port_t)parsedPayload.port;
NSString* relayServerName = parsedPayload.serverName;
PhoneNumber* phoneNumber = [PhoneNumber phoneNumberFromE164:parsedPayload.initiator];
@ -106,11 +106,11 @@
}
-(NSString*) description {
return [NSString stringWithFormat:@"relay name: %@, relay port: %d, session id: %llud, interop version: %d",
return [NSString stringWithFormat:@"relay name: %@, relay port: %d, session id: %llud, interop version: %lu",
relayServerName,
relayUdpPort,
sessionId,
interopVersion];
(unsigned long)interopVersion];
}
@end

View file

@ -7,7 +7,6 @@
//
#import "TSMessage.h"
#import "IncomingPushMessageSignal.pb.h"
@interface TSErrorMessage : TSMessage
@ -28,15 +27,6 @@ typedef NS_ENUM(int32_t, TSErrorMessageType){
+ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
+ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
/**
* Methods on TSErrorMessageWrongTrustedIdentityKey error types
*/
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
- (void)acceptNewIdentityKey;
- (NSString*)newIdentityKey;
@property (nonatomic, readonly) TSErrorMessageType errorType;
@end

View file

@ -8,29 +8,12 @@
#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
#import "TSErrorMessage_privateConstructor.h"
@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{
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType {
self = [super initWithTimestamp:timestamp inThread:thread messageBody:nil attachments:nil];
if (self) {
@ -83,42 +66,8 @@
return [[self alloc] initWithSignal:signal transaction:transaction failedMessageType:TSErrorMessageInvalidKeyException];
}
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId: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

View file

@ -0,0 +1,17 @@
//
// TSErrorMessage_privateConstructor.h
// Signal
//
// Created by Frederic Jacobs on 31/12/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "TSErrorMessage.h"
@interface TSErrorMessage ()
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType NS_DESIGNATED_INITIALIZER;
@property NSData *pushSignal;
@end

View file

@ -0,0 +1,18 @@
//
// TSInvalidIdentityKeyErrorMessage.h
// Signal
//
// Created by Frederic Jacobs on 31/12/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "TSErrorMessage.h"
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
- (void)acceptNewIdentityKey;
- (NSString*)newIdentityKey;
@end

View file

@ -0,0 +1,92 @@
//
// TSInvalidIdentityKeyErrorMessage.m
// Signal
//
// Created by Frederic Jacobs on 31/12/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import <YapDatabase/YapDatabaseTransaction.h>
#import <YapDatabase/YapDatabaseView.h>
#import "TSInvalidIdentityKeyErrorMessage.h"
#import "TSErrorMessage_privateConstructor.h"
#import "TSDatabaseView.h"
#import "TSStorageManager.h"
#import "TSStorageManager+IdentityKeyStore.h"
#import <AxolotlKit/PreKeyWhisperMessage.h>
#import <AxolotlKit/NSData+keyVersionByte.h>
#import "TSMessagesManager.h"
#import "TSFingerprintGenerator.h"
@implementation TSInvalidIdentityKeyErrorMessage
- (instancetype)initForUnknownIdentityKeyWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread incomingPushSignal:(NSData*)signal{
self = [self initWithTimestamp:timestamp inThread:thread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
if (self) {
self.pushSignal = signal;
}
return self;
}
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:preKeyMessage.source transaction:transaction];
TSInvalidIdentityKeyErrorMessage *errorMessage = [[self alloc] initForUnknownIdentityKeyWithTimestamp:preKeyMessage.timestamp inThread:contactThread incomingPushSignal:preKeyMessage.data];
return errorMessage;
}
- (void)acceptNewIdentityKey{
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey || !self.pushSignal) {
return;
}
TSStorageManager *storage = [TSStorageManager sharedManager];
IncomingPushMessageSignal *signal = [IncomingPushMessageSignal parseFromData:self.pushSignal];
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:signal.message];
NSData *newKey = [message.identityKey removeKeyType];
[storage saveRemoteIdentity:newKey recipientId:signal.source];
[[TSMessagesManager sharedManager] handleMessageSignal:signal];
__block NSMutableSet *messagesToDecrypt = [NSMutableSet set];
[[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[[transaction ext:TSMessageDatabaseViewExtensionName]enumerateKeysAndObjectsInGroup:self.uniqueThreadId withOptions:NSEnumerationReverse usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
TSInteraction *interaction = (TSInteraction*)object;
DDLogVerbose(@"Interaction type: %@", interaction.description);
if ([interaction isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
TSInvalidIdentityKeyErrorMessage *invalidKeyMessage = (TSInvalidIdentityKeyErrorMessage*)interaction;
IncomingPushMessageSignal *invalidMessageSignal = [IncomingPushMessageSignal parseFromData:invalidKeyMessage.pushSignal];
PreKeyWhisperMessage *pkwm = [[PreKeyWhisperMessage alloc] initWithData:invalidMessageSignal.message];
NSData *newKeyCandidate = [pkwm.identityKey removeKeyType];
if ([newKeyCandidate isEqualToData:newKey]) {
[messagesToDecrypt addObject:invalidMessageSignal];
}
}
}];
}];
for (IncomingPushMessageSignal *aSignal in messagesToDecrypt) {
[[TSMessagesManager sharedManager] handleMessageSignal:aSignal];
}
}
- (NSString *)newIdentityKey{
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey || !self.pushSignal) {
return @"";
}
IncomingPushMessageSignal *signal = [IncomingPushMessageSignal parseFromData:self.pushSignal];
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:signal.message];
NSData *identityKey = [message.identityKey removeKeyType];
return [TSFingerprintGenerator getFingerprintForDisplay:identityKey];
}
@end

View file

@ -19,6 +19,7 @@
#import "TSIncomingMessage.h"
#import "TSErrorMessage.h"
#import "TSInvalidIdentityKeyErrorMessage.h"
#import "TSInfoMessage.h"
#import "TSStorageManager+keyingMaterial.h"
@ -305,7 +306,7 @@
} else if ([exception.name isEqualToString:InvalidVersionException]){
errorMessage = [TSErrorMessage invalidVersionWithSignal:signal withTransaction:transaction];
} else if ([exception.name isEqualToString:UntrustedIdentityKeyException]){
errorMessage = [TSErrorMessage untrustedKeyWithSignal:signal withTransaction:transaction];
errorMessage = [TSInvalidIdentityKeyErrorMessage untrustedKeyWithSignal:signal withTransaction:transaction];
} else {
errorMessage = [TSErrorMessage corruptedMessageWithSignal:signal withTransaction:transaction];
}

View file

@ -17,17 +17,17 @@ typedef NS_ENUM(NSInteger, TSMACType) {
TSHMACSHA256AttachementType = 3
};
+(NSMutableData*) generateRandomBytes:(int)numberBytes;
+(NSMutableData*) generateRandomBytes:(NSUInteger)numberBytes;
#pragma mark SHA and HMAC methods
+(NSData*) computeSHA256:(NSData *)data truncatedToBytes:(int)truncatedBytes;
+(NSData*) computeSHA256:(NSData *)data truncatedToBytes:(NSUInteger)truncatedBytes;
+(NSString*)truncatedSHA1Base64EncodedWithoutPadding:(NSString*)string;
+(NSString*)computeSHA1DigestForString:(NSString*)input;
+(NSData*) computeSHA256HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey;
+(NSData*) computeSHA1HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey;
+(NSData*) truncatedSHA1HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey truncation:(int)bytes;
+(NSData*) truncatedSHA1HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey truncation:(NSUInteger)bytes;
+(NSData*) decryptAppleMessagePayload:(NSData*)payload withSignalingKey:(NSString*)signalingKeyString;

View file

@ -25,7 +25,7 @@
#pragma mark random bytes methods
+(NSMutableData*) generateRandomBytes:(int)numberBytes {
+(NSMutableData*) generateRandomBytes:(NSUInteger)numberBytes {
/* used to generate db master key, and to generate signaling key, both at install */
NSMutableData* randomBytes = [NSMutableData dataWithLength:numberBytes];
int err = 0;
@ -72,7 +72,7 @@
}
#pragma mark SHA256
+(NSData*) computeSHA256:(NSData *)data truncatedToBytes:(int)truncatedBytes {
+(NSData*) computeSHA256:(NSData *)data truncatedToBytes:(NSUInteger)truncatedBytes {
uint8_t digest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, (unsigned int)data.length, digest);
return [[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH] subdataWithRange:NSMakeRange(0, truncatedBytes)];
@ -103,11 +103,11 @@
}
+(NSData*) truncatedSHA1HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey truncation:(int)bytes{
+(NSData*) truncatedSHA1HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey truncation:(NSUInteger)bytes{
return [[Cryptography computeSHA1HMAC:dataToHMAC withHMACKey:HMACKey] subdataWithRange:NSMakeRange(0, bytes)];
}
+(NSData*) truncatedSHA256HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey truncation:(int)bytes{
+(NSData*) truncatedSHA256HMAC:(NSData*)dataToHMAC withHMACKey:(NSData*)HMACKey truncation:(NSUInteger)bytes{
return [[Cryptography computeSHA256HMAC:dataToHMAC withHMACKey:HMACKey] subdataWithRange:NSMakeRange(0, bytes)];
}

View file

@ -39,6 +39,7 @@
#import "TSMessageAdapter.h"
#import "TSErrorMessage.h"
#import "TSInvalidIdentityKeyErrorMessage.h"
#import "TSIncomingMessage.h"
#import "TSInteraction.h"
#import "TSAttachmentAdapter.h"
@ -543,14 +544,15 @@ typedef enum : NSUInteger {
DDLogWarn(@"Currently unsupported");
}
}
break;}
}
break;
case TSErrorMessageAdapter:
[self handleErrorMessageTap:(TSErrorMessage*)interaction];
break;
case TSInfoMessageAdapter:
break;
case TSCallAdapter:
break;
default:
break;
}
@ -581,8 +583,9 @@ typedef enum : NSUInteger {
}
- (void)handleErrorMessageTap:(TSErrorMessage*)message{
if (message.errorType == TSErrorMessageWrongTrustedIdentityKey) {
NSString *newKeyFingerprint = [message newIdentityKey];
if ([message isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
TSInvalidIdentityKeyErrorMessage *errorMessage = (TSInvalidIdentityKeyErrorMessage*)message;
NSString *newKeyFingerprint = [errorMessage newIdentityKey];
NSString *messageString = [NSString stringWithFormat:@"Do you want to accept %@'s new identity key: %@", _thread.name, newKeyFingerprint];
NSArray *actions = @[@"Accept new identity key", @"Copy new identity key to pasteboard"];
@ -598,9 +601,8 @@ typedef enum : NSUInteger {
} else {
switch (tappedButtonIndex) {
case 0:
[message acceptNewIdentityKey];
[errorMessage acceptNewIdentityKey];
break;
case 1:
[[UIPasteboard generalPasteboard] setString:newKeyFingerprint];
break;
@ -862,7 +864,7 @@ typedef enum : NSUInteger {
#pragma mark - UICollectionView DataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
NSInteger numberOfMessages = [self.messageMappings numberOfItemsInSection:section];
NSInteger numberOfMessages = (NSInteger)[self.messageMappings numberOfItemsInSection:(NSUInteger)section];
return numberOfMessages;
}
@ -873,8 +875,8 @@ typedef enum : NSUInteger {
NSParameterAssert(viewTransaction != nil);
NSParameterAssert(self.messageMappings != nil);
NSParameterAssert(indexPath != nil);
NSUInteger row = indexPath.row;
NSUInteger section = indexPath.section;
NSUInteger row = (NSUInteger)indexPath.row;
NSUInteger section = (NSUInteger)indexPath.section;
NSUInteger numberOfItemsInSection = [self.messageMappings numberOfItemsInSection:section];
NSAssert(row < numberOfItemsInSection, @"Cannot fetch message because row %d is >= numberOfItemsInSection %d", (int)row, (int)numberOfItemsInSection);