Compare commits

..

No commits in common. "master" and "mkirk/fixup-tests" have entirely different histories.

28 changed files with 194 additions and 290 deletions

View File

@ -11,7 +11,7 @@ Pod::Spec.new do |s|
s.source_files = "AxolotlKit/Classes/**/*.{h,m,swift}", "AxolotlKit/Private/*.{h,m,swift}"
s.public_header_files = "AxolotlKit/Classes/**/*.{h}"
s.prefix_header_file = "AxolotlKit/SPKPrefix.h"
s.ios.deployment_target = "10.0"
s.ios.deployment_target = "9.0"
s.osx.deployment_target = "10.8"
s.requires_arc = true

View File

@ -310,7 +310,6 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = B6B98F6F197D838A00B16B5E;
@ -527,7 +526,7 @@
"$(inherited)",
);
INFOPLIST_FILE = "AxolotlKit/AxolotlKit-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
PRODUCT_BUNDLE_IDENTIFIER = org.whispersystems.SignalProtocolKitTestApp;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
@ -544,7 +543,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "";
INFOPLIST_FILE = "AxolotlKit/AxolotlKit-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
PRODUCT_BUNDLE_IDENTIFIER = org.whispersystems.SignalProtocolKitTestApp;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
@ -640,7 +639,7 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
);
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -686,7 +685,7 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
);
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";

View File

@ -1,11 +1,13 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// AxolotlKeyFetch.h
// AxolotlKit
//
// Created by Frederic Jacobs on 21/07/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface PreKeyBundle : NSObject <NSSecureCoding>
@property (nonatomic, readonly) NSData *identityKey;
@ -27,5 +29,3 @@ NS_ASSUME_NONNULL_BEGIN
identityKey:(NSData *)identityKey;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,10 +1,13 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// AxolotlKeyFetch.m
// AxolotlKit
//
// Created by Frederic Jacobs on 21/07/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import "PreKeyBundle.h"
NS_ASSUME_NONNULL_BEGIN
static NSString* const kCoderPKBIdentityKey = @"kCoderPKBIdentityKey";
static NSString* const kCoderPKBregistrationId = @"kCoderPKBregistrationId";
@ -59,8 +62,7 @@ static NSString* const kCoderPKBsignedPreKeySignature = @"kCoderPKBsignedPreKeyS
return self;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
- (id)initWithCoder:(NSCoder *)aDecoder{
int registrationId = [aDecoder decodeIntForKey:kCoderPKBregistrationId];
int deviceId = [aDecoder decodeIntForKey:kCoderPKBdeviceId];
int preKeyId = [aDecoder decodeIntForKey:kCoderPKBpreKeyId];
@ -101,5 +103,3 @@ static NSString* const kCoderPKBsignedPreKeySignature = @"kCoderPKBsignedPreKeyS
}
@end
NS_ASSUME_NONNULL_END

View File

@ -5,20 +5,12 @@
#import <Curve25519Kit/Curve25519.h>
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface PreKeyRecord : NSObject <NSSecureCoding>
@property (nonatomic, readonly) int Id;
@property (nonatomic, readonly) ECKeyPair *keyPair;
@property (nonatomic, readonly, nullable) NSDate *createdAt;
- (instancetype)initWithId:(int)identifier
keyPair:(ECKeyPair *)keyPair
createdAt:(NSDate *)createdAt;
- (void)setCreatedAtToNow;
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair*)keyPair;
@end
NS_ASSUME_NONNULL_END

View File

@ -8,11 +8,8 @@
#import "PreKeyRecord.h"
NS_ASSUME_NONNULL_BEGIN
static NSString* const kCoderPreKeyId = @"kCoderPreKeyId";
static NSString* const kCoderPreKeyPair = @"kCoderPreKeyPair";
static NSString* const kCoderCreatedAt = @"kCoderCreatedAt";
@implementation PreKeyRecord
@ -20,10 +17,7 @@ static NSString* const kCoderCreatedAt = @"kCoderCreatedAt";
return YES;
}
- (instancetype)initWithId:(int)identifier
keyPair:(ECKeyPair*)keyPair
createdAt:(NSDate *)createdAt
{
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair*)keyPair{
OWSAssert(keyPair);
self = [super init];
@ -31,30 +25,20 @@ static NSString* const kCoderCreatedAt = @"kCoderCreatedAt";
if (self) {
_Id = identifier;
_keyPair = keyPair;
_createdAt = createdAt;
}
return self;
}
- (nullable id)initWithCoder:(NSCoder *)aDecoder {
return [self initWithId:[aDecoder decodeIntForKey:kCoderPreKeyId]
keyPair:[aDecoder decodeObjectOfClass:[ECKeyPair class] forKey:kCoderPreKeyPair]
createdAt:[aDecoder decodeObjectOfClass:[NSDate class] forKey:kCoderCreatedAt]];
- (id)initWithCoder:(NSCoder *)aDecoder{
return [self initWithId:[aDecoder decodeIntForKey:kCoderPreKeyId] keyPair:[aDecoder decodeObjectOfClass:[ECKeyPair class] forKey:kCoderPreKeyPair]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeInteger:_Id forKey:kCoderPreKeyId];
[aCoder encodeObject:_keyPair forKey:kCoderPreKeyPair];
if (_createdAt != nil) {
[aCoder encodeObject:_createdAt forKey:kCoderCreatedAt];
}
}
- (void)setCreatedAtToNow {
_createdAt = [NSDate date];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -6,8 +6,6 @@
#import "PreKeyRecord.h"
#import <Curve25519Kit/Curve25519.h>
NS_ASSUME_NONNULL_BEGIN
@interface SignedPreKeyRecord : PreKeyRecord <NSSecureCoding>
@property (nonatomic, readonly) NSData *signature;
@ -21,5 +19,3 @@ NS_ASSUME_NONNULL_BEGIN
- (void)markAsAcceptedByService;
@end
NS_ASSUME_NONNULL_END

View File

@ -4,8 +4,6 @@
#import "SignedPrekeyRecord.h"
NS_ASSUME_NONNULL_BEGIN
static NSString* const kCoderPreKeyId = @"kCoderPreKeyId";
static NSString* const kCoderPreKeyPair = @"kCoderPreKeyPair";
static NSString* const kCoderPreKeyDate = @"kCoderPreKeyDate";
@ -28,9 +26,7 @@ static NSString *const kCoderPreKeyWasAcceptedByService = @"kCoderPreKeyWasAccep
OWSAssert(signature);
OWSAssert(generatedAt);
self = [super initWithId:identifier
keyPair:keyPair
createdAt:generatedAt];
self = [super initWithId:identifier keyPair:keyPair];
if (self) {
_signature = signature;
@ -42,9 +38,7 @@ static NSString *const kCoderPreKeyWasAcceptedByService = @"kCoderPreKeyWasAccep
}
- (instancetype)initWithId:(int)identifier keyPair:(ECKeyPair *)keyPair signature:(NSData*)signature generatedAt:(NSDate *)generatedAt{
self = [super initWithId:identifier
keyPair:keyPair
createdAt:generatedAt];
self = [super initWithId:identifier keyPair:keyPair];
if (self) {
_signature = signature;
@ -54,7 +48,7 @@ static NSString *const kCoderPreKeyWasAcceptedByService = @"kCoderPreKeyWasAccep
return self;
}
- (nullable id)initWithCoder:(NSCoder *)aDecoder{
- (id)initWithCoder:(NSCoder *)aDecoder{
return [self initWithId:[aDecoder decodeIntForKey:kCoderPreKeyId]
keyPair:[aDecoder decodeObjectOfClass:[ECKeyPair class] forKey:kCoderPreKeyPair]
signature:[aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderPreKeySignature]
@ -81,5 +75,3 @@ static NSString *const kCoderPreKeyWasAcceptedByService = @"kCoderPreKeyWasAccep
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,12 +1,11 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "AxolotlStore.h"
#import "IdentityKeyStore.h"
#import "PreKeyStore.h"
#import "PreKeyWhisperMessage.h"
#import "SPKProtocolContext.h"
#import "SessionState.h"
#import "SessionStore.h"
#import "SignedPreKeyStore.h"
@ -25,22 +24,20 @@ NS_ASSUME_NONNULL_BEGIN
// identity and session store writes are coordinated and/or occur within a single
// transaction.
- (id<CipherMessage>)throws_encryptMessage:(NSData *)paddedMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
protocolContext:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (nullable id<CipherMessage>)encryptMessage:(NSData *)paddedMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
error:(NSError **)outError;
- (NSData *)throws_decrypt:(id<CipherMessage>)whisperMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
protocolContext:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (nullable NSData *)decrypt:(id<CipherMessage>)whisperMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
error:(NSError **)outError;
- (int)throws_remoteRegistrationId:(nullable id<SPKProtocolReadContext>)protocolContext
NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (int)throws_remoteRegistrationId:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (int)throws_sessionVersion:(nullable id<SPKProtocolReadContext>)protocolContext
NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (int)throws_sessionVersion:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
@end

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "SessionCipher.h"
@ -20,7 +20,6 @@
#import <Curve25519Kit/Ed25519.h>
#import <HKDFKit/HKDFKit.h>
#import <SignalCoreKit/SCKExceptionWrapper.h>
#import <SignalCoreKit/NSData+OWS.h>
NS_ASSUME_NONNULL_BEGIN
@ -70,7 +69,6 @@ NS_ASSUME_NONNULL_BEGIN
_deviceId = deviceId;
_sessionStore = sessionStore;
_identityKeyStore = identityKeyStore;
_prekeyStore = preKeyStore;
_sessionBuilder = [[SessionBuilder alloc] initWithSessionStore:sessionStore
preKeyStore:preKeyStore
signedPreKeyStore:signedPreKeyStore
@ -83,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (nullable id<CipherMessage>)encryptMessage:(NSData *)paddedMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
error:(NSError **)outError
{
__block id<CipherMessage> result;
@ -96,7 +94,7 @@ NS_ASSUME_NONNULL_BEGIN
return result;
}
- (id<CipherMessage>)throws_encryptMessage:(NSData *)paddedMessage protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (id<CipherMessage>)throws_encryptMessage:(NSData *)paddedMessage protocolContext:(nullable id)protocolContext
{
OWSAssert(paddedMessage);
@ -113,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
recipientId:self.recipientId
direction:TSMessageDirectionOutgoing
protocolContext:protocolContext]) {
OWSLogWarn(
DDLogWarn(
@"%@ Previously known identity key for while encrypting for recipient: %@", self.tag, self.recipientId);
@throw [NSException exceptionWithName:UntrustedIdentityKeyException
reason:@"There is a previously known identity key."
@ -141,8 +139,7 @@ NS_ASSUME_NONNULL_BEGIN
PendingPreKey *items = [sessionState unacknowledgedPreKeyMessageItems];
int localRegistrationId = [sessionState localRegistrationId];
OWSLogInfo(@"Building PreKeyWhisperMessage for: %@.%lu with preKeyId: %d",
self.recipientId, (unsigned long) self.deviceId, items.preKeyId);
DDLogInfo(@"Building PreKeyWhisperMessage for: %@ with preKeyId: %d", self.recipientId, items.preKeyId);
cipherMessage =
[[PreKeyWhisperMessage alloc] init_throws_withWhisperMessage:cipherMessage
@ -163,7 +160,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (nullable NSData *)decrypt:(id<CipherMessage>)whisperMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
error:(NSError **)outError
{
__block NSData *_Nullable result;
@ -176,7 +173,7 @@ NS_ASSUME_NONNULL_BEGIN
return result;
}
- (NSData *)throws_decrypt:(id<CipherMessage>)whisperMessage protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (NSData *)throws_decrypt:(id<CipherMessage>)whisperMessage protocolContext:(nullable id)protocolContext
{
OWSAssert(whisperMessage);
@ -201,7 +198,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (NSData *)throws_decryptPreKeyWhisperMessage:(PreKeyWhisperMessage *)preKeyWhisperMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
OWSAssert(preKeyWhisperMessage);
@ -221,14 +218,13 @@ NS_ASSUME_NONNULL_BEGIN
// If there was an unsigned PreKey
if (unsignedPreKeyId >= 0) {
[self.prekeyStore removePreKey:unsignedPreKeyId
protocolContext:protocolContext];
[self.prekeyStore removePreKey:unsignedPreKeyId];
}
return plaintext;
}
- (NSData *)throws_decryptWhisperMessage:(WhisperMessage *)whisperMessage protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (NSData *)throws_decryptWhisperMessage:(WhisperMessage *)whisperMessage protocolContext:(nullable id)protocolContext
{
OWSAssert(whisperMessage);
@ -238,27 +234,20 @@ NS_ASSUME_NONNULL_BEGIN
whisperMessage:whisperMessage
protocolContext:protocolContext];
// Our current session state may not have a remote identity key
// if we decrypted this message using an old session. It's safe
// to ignore this, as the identity key message was already surfaced
// when it originally changed.
if (sessionRecord.sessionState.remoteIdentityKey) {
if (![self.identityKeyStore isTrustedIdentityKey:sessionRecord.sessionState.remoteIdentityKey
recipientId:self.recipientId
direction:TSMessageDirectionIncoming
protocolContext:protocolContext]) {
OWSLogWarn(
@"%@ Previously known identity key for while decrypting from recipient: %@", self.tag, self.recipientId);
@throw [NSException exceptionWithName:UntrustedIdentityKeyException
reason:@"There is a previously known identity key."
userInfo:@{}];
}
[self.identityKeyStore saveRemoteIdentity:sessionRecord.sessionState.remoteIdentityKey
recipientId:self.recipientId
protocolContext:protocolContext];
if (![self.identityKeyStore isTrustedIdentityKey:sessionRecord.sessionState.remoteIdentityKey
recipientId:self.recipientId
direction:TSMessageDirectionIncoming
protocolContext:protocolContext]) {
DDLogWarn(
@"%@ Previously known identity key for while decrypting from recipient: %@", self.tag, self.recipientId);
@throw [NSException exceptionWithName:UntrustedIdentityKeyException
reason:@"There is a previously known identity key."
userInfo:@{}];
}
[self.identityKeyStore saveRemoteIdentity:sessionRecord.sessionState.remoteIdentityKey
recipientId:self.recipientId
protocolContext:protocolContext];
[self.sessionStore storeSession:self.recipientId
deviceId:self.deviceId
session:sessionRecord
@ -267,14 +256,9 @@ NS_ASSUME_NONNULL_BEGIN
return plaintext;
}
- (void)logDecryptionFailureForWhisperMessage:(WhisperMessage *)whisperMessage sessionState:(SessionState *)sessionState
{
OWSFailDebug(@"Failed to decrypt whisper message with ratchet key: %@ and counter: %d. Session loaded using recipientId: %@ and deviceId: %d. Local session has base key: %@ and counter: %d", whisperMessage.senderRatchetKey.hexadecimalString, whisperMessage.counter, self.recipientId, self.deviceId, sessionState.senderRatchetKey.hexadecimalString, sessionState.previousCounter);
}
- (NSData *)throws_decryptWithSessionRecord:(SessionRecord *)sessionRecord
whisperMessage:(WhisperMessage *)whisperMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
OWSAssert(sessionRecord);
OWSAssert(whisperMessage);
@ -286,49 +270,51 @@ NS_ASSUME_NONNULL_BEGIN
NSData *decryptedData = [self throws_decryptWithSessionState:sessionState
whisperMessage:whisperMessage
protocolContext:protocolContext];
OWSLogDebug(@"%@ successfully decrypted with current session state: %@", self.tag, sessionState);
DDLogDebug(@"%@ successfully decrypted with current session state: %@", self.tag, sessionState);
return decryptedData;
}
@catch (NSException *exception) {
if ([exception.name isEqualToString:InvalidMessageException]) {
[exceptions addObject:exception];
} else {
[self logDecryptionFailureForWhisperMessage:whisperMessage sessionState:sessionState];
@throw exception;
}
}
// If we can decrypt the message with an "old" session state, that means the sender is using an "old" session.
// We can continue to receive messages from this sender, but we will send to them using our current session.
__block NSData *_Nullable decryptedData;
// In which case, we promote that session to "active" so as to converge on a single session for sending/receiving.
__block NSUInteger stateToPromoteIdx;
__block NSData *decryptedData;
[[sessionRecord previousSessionStates]
enumerateObjectsUsingBlock:^(SessionState *_Nonnull previousState, NSUInteger idx, BOOL *_Nonnull stop) {
@try {
decryptedData = [self throws_decryptWithSessionState:previousState
whisperMessage:whisperMessage
protocolContext:protocolContext];
OWSLogInfo(@"%@ successfully decrypted with PREVIOUS session state: %@", self.tag, previousState);
DDLogInfo(@"%@ successfully decrypted with PREVIOUS session state: %@", self.tag, previousState);
OWSAssert(decryptedData != nil);
stateToPromoteIdx = idx;
*stop = YES;
} @catch (NSException *exception) {
if (![exception.name isEqualToString:InvalidMessageException]) {
[self logDecryptionFailureForWhisperMessage:whisperMessage sessionState:sessionState];
}
[exceptions addObject:exception];
}
}];
if (decryptedData) {
SessionState *sessionStateToPromote = [sessionRecord previousSessionStates][stateToPromoteIdx];
OWSAssert(sessionStateToPromote != nil);
DDLogInfo(@"%@ promoting session: %@", self.tag, sessionStateToPromote);
[[sessionRecord previousSessionStates] removeObjectAtIndex:stateToPromoteIdx];
[sessionRecord promoteState:sessionStateToPromote];
return decryptedData;
}
BOOL containsActiveSession =
[self.sessionStore containsSession:self.recipientId deviceId:self.deviceId protocolContext:protocolContext];
OWSLogError(@"%@ No valid session for recipient: %@.%lu containsActiveSession: %@, previousStates: %lu",
DDLogError(@"%@ No valid session for recipient: %@ containsActiveSession: %@, previousStates: %lu",
self.tag,
self.recipientId,
(unsigned long) self.deviceId,
(containsActiveSession ? @"YES" : @"NO"),
(unsigned long)sessionRecord.previousSessionStates.count);
@ -348,7 +334,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSData *)throws_decryptWithSessionState:(SessionState *)sessionState
whisperMessage:(WhisperMessage *)whisperMessage
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
OWSAssert(sessionState);
OWSAssert(whisperMessage);
@ -397,10 +383,10 @@ NS_ASSUME_NONNULL_BEGIN
@try {
if ([sessionState hasReceiverChain:theirEphemeral]) {
OWSLogInfo(@"%@ %@.%d has existing receiver chain.", self.tag, self.recipientId, self.deviceId);
DDLogInfo(@"%@ %@.%d has existing receiver chain.", self.tag, self.recipientId, self.deviceId);
return [sessionState receiverChainKey:theirEphemeral];
} else{
OWSLogInfo(@"%@ %@.%d creating new chains.", self.tag, self.recipientId, self.deviceId);
DDLogInfo(@"%@ %@.%d creating new chains.", self.tag, self.recipientId, self.deviceId);
RootKey *rootKey = [sessionState rootKey];
OWSAssert(rootKey.keyData.length == 32);
@ -456,7 +442,7 @@ NS_ASSUME_NONNULL_BEGIN
}
}
NSUInteger kCounterLimit = 25000;
NSUInteger kCounterLimit = 2000;
int counterOffset;
if (__builtin_sub_overflow(counter, chainKey.index, &counterOffset)) {
OWSFailDebug(@"Overflow while calculating counter offset");
@ -498,7 +484,7 @@ NS_ASSUME_NONNULL_BEGIN
return versionByte;
}
- (int)throws_remoteRegistrationId:(nullable id<SPKProtocolReadContext>)protocolContext
- (int)throws_remoteRegistrationId:(nullable id)protocolContext
{
SessionRecord *_Nullable record =
[self.sessionStore loadSession:self.recipientId deviceId:_deviceId protocolContext:protocolContext];
@ -510,7 +496,7 @@ NS_ASSUME_NONNULL_BEGIN
return record.sessionState.remoteRegistrationId;
}
- (int)throws_sessionVersion:(nullable id<SPKProtocolReadContext>)protocolContext
- (int)throws_sessionVersion:(nullable id)protocolContext
{
SessionRecord *_Nullable record =
[self.sessionStore loadSession:self.recipientId deviceId:_deviceId protocolContext:protocolContext];

View File

@ -1,12 +1,11 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "AxolotlStore.h"
#import "IdentityKeyStore.h"
#import "PreKeyBundle.h"
#import "PreKeyStore.h"
#import "SPKProtocolContext.h"
#import "SessionStore.h"
#import "SignedPreKeyStore.h"
#import <Foundation/Foundation.h>
@ -31,14 +30,14 @@ extern const int kPreKeyOfLastResortId;
deviceId:(int)deviceId;
- (void)throws_processPrekeyBundle:(PreKeyBundle *)preKeyBundle
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
protocolContext:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (BOOL)processPrekeyBundle:(PreKeyBundle *)preKeyBundle
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
error:(NSError **)outError;
- (int)throws_processPrekeyWhisperMessage:(PreKeyWhisperMessage *)message
withSession:(SessionRecord *)sessionRecord
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
protocolContext:(nullable id)protocolContext NS_SWIFT_UNAVAILABLE("throws objc exceptions");
@end

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "SessionBuilder.h"
@ -80,7 +80,7 @@ const int kPreKeyOfLastResortId = 0xFFFFFF;
}
- (BOOL)processPrekeyBundle:(PreKeyBundle *)preKeyBundle
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
error:(NSError **)outError
{
return [SCKExceptionWrapper
@ -90,7 +90,7 @@ const int kPreKeyOfLastResortId = 0xFFFFFF;
error:outError];
}
- (void)throws_processPrekeyBundle:(PreKeyBundle *)preKeyBundle protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (void)throws_processPrekeyBundle:(PreKeyBundle *)preKeyBundle protocolContext:(nullable id)protocolContext
{
OWSAssert(preKeyBundle);
@ -146,6 +146,12 @@ const int kPreKeyOfLastResortId = 0xFFFFFF;
BOOL previousIdentityExisted = [self.identityStore saveRemoteIdentity:theirIdentityKey
recipientId:self.recipientId
protocolContext:protocolContext];
if (previousIdentityExisted) {
DDLogInfo(@"%@ PKBundle removing previous session states for changed identity for recipient:%@",
self.tag,
self.recipientId);
[sessionRecord removePreviousSessionStates];
}
[self.sessionStore storeSession:self.recipientId
deviceId:self.deviceId
@ -155,7 +161,7 @@ const int kPreKeyOfLastResortId = 0xFFFFFF;
- (int)throws_processPrekeyWhisperMessage:(PreKeyWhisperMessage *)message
withSession:(SessionRecord *)sessionRecord
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
OWSAssert(message);
OWSAssert(sessionRecord);
@ -191,7 +197,7 @@ const int kPreKeyOfLastResortId = 0xFFFFFF;
- (int)throws_processPrekeyV3:(PreKeyWhisperMessage *)message
withSession:(SessionRecord *)sessionRecord
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
OWSAssert(message);
OWSAssert(sessionRecord);
@ -202,28 +208,11 @@ const int kPreKeyOfLastResortId = 0xFFFFFF;
return -1;
}
SignedPreKeyRecord *_Nullable signedPreKeyRecord = [self.signedPreKeyStore loadSignedPreKey:message.signedPrekeyId
protocolContext:protocolContext];
if (signedPreKeyRecord == nil) {
OWSLogWarn(@"Signed prekey id: %lu, prekey id: %lu.",
(unsigned long) message.signedPrekeyId,
(unsigned long) message.prekeyID);
OWSLogWarn(@"Available signed prekey ids: %@",
[self.signedPreKeyStore availableSignedPreKeyIdsWithProtocolContext:protocolContext]);
OWSRaiseException(InvalidKeyIdException, @"No signed prekey found matching key id");
}
ECKeyPair *ourSignedPrekey = signedPreKeyRecord.keyPair;
ECKeyPair *ourSignedPrekey = [self.signedPreKeyStore throws_loadSignedPrekey:message.signedPrekeyId].keyPair;
ECKeyPair *_Nullable ourOneTimePreKey;
if (message.prekeyID >= 0) {
PreKeyRecord *_Nullable preKey = [self.prekeyStore loadPreKey:message.prekeyID
protocolContext:protocolContext];
if (preKey == nil) {
OWSFailDebug(@"Missing prekeyID: %lu", (unsigned long) message.prekeyID);
OWSRaiseException(InvalidKeyIdException, @"No pre key found matching key id");
}
ourOneTimePreKey = preKey.keyPair;
ourOneTimePreKey = [self.prekeyStore throws_loadPreKey:message.prekeyID].keyPair;
} else {
DDLogWarn(@"%@ Processing PreKey message which had no one-time prekey.", self.tag);
}

View File

@ -11,11 +11,13 @@
- (BOOL)hasSessionState:(int)version baseKey:(NSData*)aliceBaseKey;
- (SessionState*)sessionState;
- (NSArray<SessionState *> *)previousSessionStates;
- (NSMutableArray<SessionState *> *)previousSessionStates;
- (void)removePreviousSessionStates;
- (BOOL)isFresh;
- (void)markAsUnFresh;
- (void)archiveCurrentState;
- (void)promoteState:(SessionState*)promotedState;
- (void)setState:(SessionState*)sessionState;
@end

View File

@ -71,11 +71,16 @@
return _sessionState;
}
- (NSArray<SessionState *> *)previousSessionStates
- (NSMutableArray<SessionState *> *)previousSessionStates
{
return _previousStates;
}
- (void)removePreviousSessionStates
{
[_previousStates removeAllObjects];
}
- (BOOL)isFresh{
return _fresh;
}
@ -86,10 +91,6 @@
}
- (void)archiveCurrentState{
if (self.sessionState.isFresh) {
OWSLogInfo(@"Skipping archive, current session state is fresh.");
return;
}
[self promoteState:[SessionState new]];
}
@ -102,7 +103,7 @@
ows_sub_overflow(self.previousStates.count, ARCHIVED_STATES_MAX_LENGTH, &deleteCount);
NSIndexSet *indexesToDelete =
[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ARCHIVED_STATES_MAX_LENGTH, deleteCount)];
[self.previousStates removeObjectsAtIndexes:indexesToDelete];
[self.previousSessionStates removeObjectsAtIndexes:indexesToDelete];
}
}

View File

@ -39,8 +39,6 @@
@property(nonatomic)int remoteRegistrationId;
@property(nonatomic)int localRegistrationId;
@property (nonatomic, readonly) BOOL isFresh;
- (NSData*)senderRatchetKey;
- (ECKeyPair*)senderRatchetKeyPair;

View File

@ -119,11 +119,6 @@ static NSString* const kCoderPendingPrekey = @"kCoderPendingPrekey";
[aCoder encodeObject:self.pendingPreKey forKey:kCoderPendingPrekey];
}
- (BOOL)isFresh
{
return self.remoteIdentityKey == nil && self.localIdentityKey == nil && self.sendingChain == nil && self.receivingChains.count == 0 && self.pendingPreKey == nil;
}
- (NSData*)senderRatchetKey{
return [[self senderRatchetKeyPair] publicKey];
}

View File

@ -1,8 +1,7 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "SPKProtocolContext.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@ -18,9 +17,9 @@ typedef NS_ENUM(NSInteger, TSMessageDirection) {
// See a discussion of the protocolContext in SessionCipher.h.
@protocol IdentityKeyStore <NSObject>
- (nullable ECKeyPair *)identityKeyPair:(nullable id<SPKProtocolWriteContext>)protocolContext;
- (nullable ECKeyPair *)identityKeyPair:(nullable id)protocolContext;
- (int)localRegistrationId:(nullable id<SPKProtocolWriteContext>)protocolContext;
- (int)localRegistrationId:(nullable id)protocolContext;
/**
* Record a recipients identity key
@ -33,7 +32,7 @@ typedef NS_ENUM(NSInteger, TSMessageDirection) {
*/
- (BOOL)saveRemoteIdentity:(NSData *)identityKey
recipientId:(NSString *)recipientId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
protocolContext:(nullable id)protocolContext;
/**
* @param identityKey key data used to identify the recipient
@ -47,12 +46,11 @@ typedef NS_ENUM(NSInteger, TSMessageDirection) {
- (BOOL)isTrustedIdentityKey:(NSData *)identityKey
recipientId:(NSString *)recipientId
direction:(TSMessageDirection)direction
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
protocolContext:(nullable id)protocolContext;
- (nullable NSData *)identityKeyForRecipientId:(NSString *)recipientId;
- (nullable NSData *)identityKeyForRecipientId:(NSString *)recipientId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
- (nullable NSData *)identityKeyForRecipientId:(NSString *)recipientId protocolContext:(nullable id)protocolContext;
@end

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "PreKeyRecord.h"
@ -9,14 +9,13 @@ NS_ASSUME_NONNULL_BEGIN
@protocol PreKeyStore <NSObject>
- (nullable PreKeyRecord *)loadPreKey:(int)preKeyId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
- (PreKeyRecord *)throws_loadPreKey:(int)preKeyId NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (void)storePreKey:(int)preKeyId preKeyRecord:(PreKeyRecord *)record
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
- (void)storePreKey:(int)preKeyId preKeyRecord:(PreKeyRecord *)record;
- (void)removePreKey:(int)preKeyId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
- (BOOL)containsPreKey:(int)preKeyId;
- (void)removePreKey:(int)preKeyId;
@end

View File

@ -1,8 +1,7 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "SPKProtocolContext.h"
#import "SessionRecord.h"
#import <Foundation/Foundation.h>
@ -21,24 +20,24 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (SessionRecord *)loadSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
protocolContext:(nullable id)protocolContext;
- (NSArray *)subDevicesSessions:(NSString *)contactIdentifier protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext __attribute__((deprecated));
- (NSArray *)subDevicesSessions:(NSString *)contactIdentifier protocolContext:(nullable id)protocolContext __attribute__((deprecated));
- (void)storeSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
session:(SessionRecord *)session
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
protocolContext:(nullable id)protocolContext;
- (BOOL)containsSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
protocolContext:(nullable id)protocolContext;
- (void)deleteSessionForContact:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
protocolContext:(nullable id)protocolContext;
- (void)deleteAllSessionsForContact:(NSString *)contactIdentifier protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
- (void)deleteAllSessionsForContact:(NSString *)contactIdentifier protocolContext:(nullable id)protocolContext;
@end

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "SignedPrekeyRecord.h"
@ -9,22 +9,17 @@ NS_ASSUME_NONNULL_BEGIN
@protocol SignedPreKeyStore <NSObject>
- (nullable SignedPreKeyRecord *)loadSignedPreKey:(int)signedPreKeyId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
- (SignedPreKeyRecord *)throws_loadSignedPrekey:(int)signedPreKeyId NS_SWIFT_UNAVAILABLE("throws objc exceptions");
- (NSArray<SignedPreKeyRecord *> *)loadSignedPreKeysWithProtocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
- (nullable SignedPreKeyRecord *)loadSignedPrekeyOrNil:(int)signedPreKeyId;
- (void)storeSignedPreKey:(int)signedPreKeyId
signedPreKeyRecord:(SignedPreKeyRecord *)signedPreKeyRecord
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
- (NSArray<SignedPreKeyRecord *> *)loadSignedPreKeys;
- (BOOL)containsSignedPreKey:(int)signedPreKeyId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
- (void)storeSignedPreKey:(int)signedPreKeyId signedPreKeyRecord:(SignedPreKeyRecord *)signedPreKeyRecord;
- (void)removeSignedPreKey:(int)signedPreKeyId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext;
- (BOOL)containsSignedPreKey:(int)signedPreKeyId;
- (NSArray<NSString *> *)availableSignedPreKeyIdsWithProtocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
- (void)removeSignedPreKey:(int)signedPrekeyId;
@end

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "SPKMockProtocolStore.h"
@ -52,13 +52,31 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Signed PreKey Store
- (nullable SignedPreKeyRecord *)loadSignedPreKey:(int)signedPreKeyId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext
- (SignedPreKeyRecord *)throws_loadSignedPrekey:(int)signedPreKeyId
{
if (![[self.signedPreKeyStore allKeys] containsObject:[NSNumber numberWithInt:signedPreKeyId]]) {
@throw [NSException exceptionWithName:InvalidKeyIdException reason:@"No such signedprekeyrecord" userInfo:nil];
}
return [self.signedPreKeyStore objectForKey:[NSNumber numberWithInt:signedPreKeyId]];
}
- (NSArray<SignedPreKeyRecord *> *)loadSignedPreKeysWithProtocolContext:(nullable id<SPKProtocolReadContext>)protocolContext
- (nullable SignedPreKeyRecord *)loadSignedPrekeyOrNil:(int)signedPreKeyId
{
if ([self containsSignedPreKey:signedPreKeyId]) {
@try {
// Given that we've checked for `contains` this really shouldn't fail.
return [self throws_loadSignedPrekey:signedPreKeyId];
} @catch (NSException *exception) {
OWSFailDebug(@"unexpected exception: %@", exception);
return nil;
}
} else {
return nil;
}
}
- (NSArray<SignedPreKeyRecord *> *)loadSignedPreKeys
{
NSMutableArray *results = [NSMutableArray array];
@ -69,20 +87,12 @@ NS_ASSUME_NONNULL_BEGIN
return results;
}
- (NSArray<NSString *> *)availableSignedPreKeyIdsWithProtocolContext:(nullable id<SPKProtocolReadContext>)protocolContext
{
return @[];
}
- (void)storeSignedPreKey:(int)signedPreKeyId
signedPreKeyRecord:(SignedPreKeyRecord *)signedPreKeyRecord
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (void)storeSignedPreKey:(int)signedPreKeyId signedPreKeyRecord:(SignedPreKeyRecord *)signedPreKeyRecord
{
[self.signedPreKeyStore setObject:signedPreKeyRecord forKey:[NSNumber numberWithInteger:signedPreKeyId]];
}
- (BOOL)containsSignedPreKey:(int)signedPreKeyId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext
{
if ([[self.signedPreKeyStore allKeys] containsObject:[NSNumber numberWithInteger:signedPreKeyId]]) {
return TRUE;
@ -91,17 +101,19 @@ NS_ASSUME_NONNULL_BEGIN
return FALSE;
}
- (void)removeSignedPreKey:(int)signedPreKeyId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (void)removeSignedPreKey:(int)signedPrekeyId
{
[self.signedPreKeyStore removeObjectForKey:[NSNumber numberWithInteger:signedPreKeyId]];
[self.signedPreKeyStore removeObjectForKey:[NSNumber numberWithInteger:signedPrekeyId]];
}
#pragma mark PreKey Store
- (nullable PreKeyRecord *)loadPreKey:(int)preKeyId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext;
- (PreKeyRecord *)throws_loadPreKey:(int)preKeyId
{
if (![[self.preKeyStore allKeys] containsObject:[NSNumber numberWithInt:preKeyId]]) {
@throw [NSException exceptionWithName:InvalidKeyIdException reason:@"No such signedprekeyrecord" userInfo:nil];
}
return [self.preKeyStore objectForKey:[NSNumber numberWithInt:preKeyId]];
}
@ -117,32 +129,39 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)storePreKey:(int)preKeyId preKeyRecord:(PreKeyRecord *)record
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
{
[self.preKeyStore setObject:record forKey:[NSNumber numberWithInt:preKeyId]];
}
- (BOOL)containsPreKey:(int)preKeyId
{
if ([[self.preKeyStore allKeys] containsObject:[NSNumber numberWithInteger:preKeyId]]) {
return TRUE;
}
return FALSE;
}
- (void)removePreKey:(int)preKeyId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
{
[self.preKeyStore removeObjectForKey:[NSNumber numberWithInt:preKeyId]];
}
#pragma mark IdentityKeyStore
- (nullable ECKeyPair *)identityKeyPair:(nullable id<SPKProtocolWriteContext>)protocolContext
- (nullable ECKeyPair *)identityKeyPair:(nullable id)protocolContext
{
return self.identityKeyPair;
}
- (int)localRegistrationId:(nullable id<SPKProtocolWriteContext>)protocolContext
- (int)localRegistrationId:(nullable id)protocolContext
{
return self.localRegistrationId;
}
- (BOOL)saveRemoteIdentity:(NSData *)identityKey
recipientId:(NSString *)recipientId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
NSData *existingKey = [self.trustedKeys objectForKey:recipientId];
@ -157,7 +176,7 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)isTrustedIdentityKey:(NSData *)identityKey
recipientId:(NSString *)recipientId
direction:(TSMessageDirection)direction
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
NSData *data = [self.trustedKeys objectForKey:recipientId];
if (!data) {
@ -183,8 +202,7 @@ NS_ASSUME_NONNULL_BEGIN
return [self identityKeyForRecipientId:recipientId protocolContext:nil];
}
- (nullable NSData *)identityKeyForRecipientId:(NSString *)recipientId
protocolContext:(nullable id<SPKProtocolReadContext>)protocolContext
- (nullable NSData *)identityKeyForRecipientId:(NSString *)recipientId protocolContext:(nullable id)protocolContext
{
NSData *_Nullable data = [self.trustedKeys objectForKey:recipientId];
return data;
@ -194,7 +212,7 @@ NS_ASSUME_NONNULL_BEGIN
- (SessionRecord *)loadSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
SessionRecord *sessionRecord = [[self deviceSessionRecordsForContactIdentifier:contactIdentifier]
objectForKey:[NSNumber numberWithInteger:deviceId]];
@ -206,13 +224,10 @@ NS_ASSUME_NONNULL_BEGIN
return sessionRecord;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (NSArray *)subDevicesSessions:(NSString *)contactIdentifier protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (NSArray *)subDevicesSessions:(NSString *)contactIdentifier protocolContext:(nullable id)protocolContext
{
return [[self deviceSessionRecordsForContactIdentifier:contactIdentifier] allKeys];
}
#pragma clang diagnostic pop
- (NSMutableDictionary *)deviceSessionRecordsForContactIdentifier:(NSString *)contactIdentifier
{
@ -222,7 +237,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)storeSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
session:(SessionRecord *)session
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
NSAssert(session, @"Session can't be nil");
NSMutableDictionary *deviceSessions = self.sessionRecords[contactIdentifier];
@ -236,7 +251,7 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)containsSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
if ([[self.sessionRecords objectForKey:contactIdentifier] objectForKey:[NSNumber numberWithInt:deviceId]]) {
@ -247,14 +262,14 @@ NS_ASSUME_NONNULL_BEGIN
- (void)deleteSessionForContact:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
protocolContext:(nullable id)protocolContext
{
NSMutableDictionary<NSNumber *, SessionRecord *> *sessions =
[self deviceSessionRecordsForContactIdentifier:contactIdentifier];
[sessions removeObjectForKey:@(deviceId)];
}
- (void)deleteAllSessionsForContact:(NSString *)contactIdentifier protocolContext:(nullable id<SPKProtocolWriteContext>)protocolContext
- (void)deleteAllSessionsForContact:(NSString *)contactIdentifier protocolContext:(nullable id)protocolContext
{
[self.sessionRecords removeObjectForKey:contactIdentifier];
}

View File

@ -1,11 +1,9 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSData (keyVersionByte)
- (instancetype)prependKeyType;
@ -14,5 +12,3 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable instancetype)removeKeyTypeAndReturnError:(NSError **)outError;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,13 +1,11 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "NSData+keyVersionByte.h"
#import "AxolotlExceptions.h"
#import <SignalCoreKit/SCKExceptionWrapper.h>
NS_ASSUME_NONNULL_BEGIN
@implementation NSData (keyVersionByte)
const Byte DJB_TYPE = 0x05;
@ -48,5 +46,3 @@ const Byte DJB_TYPE = 0x05;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,17 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol SPKProtocolReadContext <NSObject>
@end
@protocol SPKProtocolWriteContext <SPKProtocolReadContext>
@end
NS_ASSUME_NONNULL_END

View File

@ -80,16 +80,8 @@
XCTAssert([outgoingMessage isKindOfClass:[PreKeyWhisperMessage class]], @"Message should be PreKey type");
PreKeyWhisperMessage *incomingMessage = (PreKeyWhisperMessage*)outgoingMessage;
[bobStore storePreKey:31337 preKeyRecord:[[PreKeyRecord alloc] initWithId:bobPreKey.preKeyId
keyPair:bobPreKeyPair
createdAt:[NSDate date]]
protocolContext:nil];
[bobStore storeSignedPreKey:22
signedPreKeyRecord:[[SignedPreKeyRecord alloc] initWithId:22
keyPair:bobSignedPreKeyPair
signature:bobSignedPreKeySignature
generatedAt:[NSDate date]]
protocolContext:nil];
[bobStore storePreKey:31337 preKeyRecord:[[PreKeyRecord alloc] initWithId:bobPreKey.preKeyId keyPair:bobPreKeyPair]];
[bobStore storeSignedPreKey:22 signedPreKeyRecord:[[SignedPreKeyRecord alloc] initWithId:22 keyPair:bobSignedPreKeyPair signature:bobSignedPreKeySignature generatedAt:[NSDate date]]];
SessionCipher *bobSessionCipher = [[SessionCipher alloc] initWithAxolotlStore:bobStore recipientId:ALICE_RECIPIENT_ID deviceId:1];
[bobSessionCipher throws_decrypt:incomingMessage protocolContext:nil];
@ -97,7 +89,7 @@
XCTAssert([bobStore containsSession:ALICE_RECIPIENT_ID deviceId:1 protocolContext:nil]);
XCTAssert([bobStore loadSession:ALICE_RECIPIENT_ID deviceId:1 protocolContext:nil].sessionState.version == 3);
XCTAssert([bobStore loadSession:ALICE_RECIPIENT_ID deviceId:1 protocolContext:nil].sessionState.aliceBaseKey != nil);
}
}
/**
* Tests the case where an attacker would send a new PreKeyWhisperMessage with another IdentityKey

View File

@ -13,10 +13,6 @@
#import <Curve25519Kit/Curve25519.h>
#import <XCTest/XCTest.h>
@interface SessionRecord (Private)
- (void)promoteState:(SessionState *)promotedState;
@end
@interface SessionCipherTest : XCTestCase
@property (nonatomic, readonly) NSString *aliceIdentifier;
@ -81,11 +77,10 @@
XCTAssertNotEqualObjects(initialSessionState, activeSession.sessionState);
XCTAssertEqualObjects(newSessionState, activeSession.sessionState);
// 3.) Bob should decrypt with initial session after receiving a message from that old session,
// but importantly *not* promote it to be the active session.
// 3.) Bob should promote back the initial session after receiving a message from that old session.
[self runInteractionWithAliceRecord:aliceSessionRecord bobRecord:bobSessionRecord];
XCTAssertNotEqualObjects(initialSessionState, activeSession.sessionState);
XCTAssertEqualObjects(newSessionState, activeSession.sessionState);
XCTAssertNotEqualObjects(newSessionState, activeSession.sessionState);
XCTAssertEqualObjects(initialSessionState, activeSession.sessionState);
XCTAssertEqual(1, bobSessionRecord.previousSessionStates.count);
XCTAssertEqual(0, aliceSessionRecord.previousSessionStates.count);
}

View File

@ -7,6 +7,14 @@
NS_ASSUME_NONNULL_BEGIN
@interface ECKeyPair (ECKeyPairTestingPrivate)
- (nullable id)initWithPublicKey:(NSData *)publicKey privateKey:(NSData *)privateKey;
@end
#pragma mark -
@implementation ECKeyPair (testing)
+ (ECKeyPair *)throws_keyPairWithPrivateKey:(NSData *)privateKey publicKey:(NSData *)publicKey
@ -19,9 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Public or Private key is not required size" userInfo:@{@"PrivateKey":privateKey, @"Public Key":publicKey}];
}
NSError *error;
ECKeyPair *_Nullable keyPairCopy = [[ECKeyPair alloc] initWithPublicKeyData:[publicKey copy] privateKeyData:[privateKey copy] error:&error];
OWSAssertDebug(error == nil && keyPairCopy != nil);
ECKeyPair *keyPairCopy = [[ECKeyPair alloc] initWithPublicKey:[publicKey copy] privateKey:[privateKey copy]];
return keyPairCopy;
}

View File

@ -1,4 +1,4 @@
**Deprecation Warning**: It is recommended that the swift interface of [libsignal-client](https://github.com/signalapp/libsignal-client) be used for all new iOS applications. This library is no longer used by us or maintained.
**Deprecation Warning**: It is recommended that [libsignal-protocol-c](https://github.com/whispersystems/libsignal-protocol-c) be used for all new applications.
# SignalProtocolKit [![Build Status](https://travis-ci.org/WhisperSystems/AxolotlKit.svg?branch=master)](https://travis-ci.org/WhisperSystems/AxolotlKit)