forked from signalapp/SignalProtocolKit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSessionCipherTest.m
133 lines (100 loc) · 6.07 KB
/
SessionCipherTest.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <AxolotlKit/AliceAxolotlParameters.h>
#import <AxolotlKit/BobAxolotlParameters.h>
#import <AxolotlKit/ChainKey.h>
#import <AxolotlKit/RatchetingSession.h>
#import <AxolotlKit/SPKMockProtocolStore.h>
#import <AxolotlKit/SessionBuilder.h>
#import <AxolotlKit/SessionCipher.h>
#import <AxolotlKit/SessionState.h>
#import <Curve25519Kit/Curve25519.h>
#import <XCTest/XCTest.h>
@interface SessionCipherTest : XCTestCase
@property (nonatomic, readonly) NSString *aliceIdentifier;
@property (nonatomic, readonly) NSString *bobIdentifier;
@property (nonatomic, readonly) SPKMockProtocolStore *aliceStore;
@property (nonatomic, readonly) SPKMockProtocolStore *bobStore;
@end
@implementation SessionCipherTest
- (NSString *)aliceIdentifier
{
return @"+3728378173821";
}
- (NSString *)bobIdentifier
{
return @"bob@gmail.com";
}
- (void)setUp {
[super setUp];
_aliceStore = [SPKMockProtocolStore new];
_bobStore = [SPKMockProtocolStore new];
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testBasicSession{
SessionRecord *aliceSessionRecord = [SessionRecord new];
SessionRecord *bobSessionRecord = [SessionRecord new];
[self throws_sessionInitializationWithAliceSessionRecord:aliceSessionRecord bobSessionRecord:bobSessionRecord];
[self runInteractionWithAliceRecord:aliceSessionRecord bobRecord:bobSessionRecord];
}
- (void)testPromotingOldSessionState
{
SessionRecord *aliceSessionRecord = [SessionRecord new];
SessionRecord *bobSessionRecord = [SessionRecord new];
// 1.) Given Alice and Bob have initialized some session together
SessionState *initialSessionState = bobSessionRecord.sessionState;
[self throws_sessionInitializationWithAliceSessionRecord:aliceSessionRecord bobSessionRecord:bobSessionRecord];
SessionRecord *activeSession = [self.bobStore loadSession:self.aliceIdentifier deviceId:1 protocolContext:nil];
XCTAssertNotNil(activeSession);
XCTAssertEqualObjects(initialSessionState, activeSession.sessionState);
// 2.) If for some reason, bob has promoted a different session...
SessionState *newSessionState = [SessionState new];
[bobSessionRecord promoteState:newSessionState];
XCTAssertEqual(1, bobSessionRecord.previousSessionStates.count);
[self.bobStore storeSession:self.aliceIdentifier deviceId:1 session:bobSessionRecord protocolContext:nil];
activeSession = [self.bobStore loadSession:self.aliceIdentifier deviceId:1 protocolContext:nil];
XCTAssertNotNil(activeSession);
XCTAssertNotEqualObjects(initialSessionState, activeSession.sessionState);
XCTAssertEqualObjects(newSessionState, activeSession.sessionState);
// 3.) Bob should promote back the initial session after receiving a message from that old session.
[self runInteractionWithAliceRecord:aliceSessionRecord bobRecord:bobSessionRecord];
XCTAssertNotEqualObjects(newSessionState, activeSession.sessionState);
XCTAssertEqualObjects(initialSessionState, activeSession.sessionState);
XCTAssertEqual(1, bobSessionRecord.previousSessionStates.count);
XCTAssertEqual(0, aliceSessionRecord.previousSessionStates.count);
}
- (void)throws_sessionInitializationWithAliceSessionRecord:(SessionRecord *)aliceSessionRecord
bobSessionRecord:(SessionRecord *)bobSessionRecord
{
SessionState *aliceSessionState = aliceSessionRecord.sessionState;
SessionState *bobSessionState = bobSessionRecord.sessionState;
ECKeyPair *aliceIdentityKeyPair = [Curve25519 generateKeyPair];
ECKeyPair *aliceBaseKey = [Curve25519 generateKeyPair];
ECKeyPair *bobIdentityKeyPair = [Curve25519 generateKeyPair];
ECKeyPair *bobBaseKey = [Curve25519 generateKeyPair];
ECKeyPair *bobOneTimePK = [Curve25519 generateKeyPair];
AliceAxolotlParameters *aliceParams = [[AliceAxolotlParameters alloc] initWithIdentityKey:aliceIdentityKeyPair theirIdentityKey:[bobIdentityKeyPair publicKey] ourBaseKey:aliceBaseKey theirSignedPreKey:[bobBaseKey publicKey] theirOneTimePreKey:[bobOneTimePK publicKey] theirRatchetKey:[bobBaseKey publicKey]];
BobAxolotlParameters *bobParams = [[BobAxolotlParameters alloc] initWithMyIdentityKeyPair:bobIdentityKeyPair theirIdentityKey:[aliceIdentityKeyPair publicKey] ourSignedPrekey:bobBaseKey ourRatchetKey:bobBaseKey ourOneTimePrekey:bobOneTimePK theirBaseKey:[aliceBaseKey publicKey]];
[RatchetingSession throws_initializeSession:bobSessionState sessionVersion:3 BobParameters:bobParams];
[RatchetingSession throws_initializeSession:aliceSessionState sessionVersion:3 AliceParameters:aliceParams];
[self.aliceStore saveRemoteIdentity:bobIdentityKeyPair.publicKey recipientId:self.bobIdentifier protocolContext:nil];
[self.aliceStore storeSession:self.bobIdentifier deviceId:1 session:aliceSessionRecord protocolContext:nil];
[self.bobStore saveRemoteIdentity:aliceIdentityKeyPair.publicKey recipientId:self.aliceIdentifier protocolContext:nil];
[self.bobStore storeSession:self.aliceIdentifier deviceId:1 session:bobSessionRecord protocolContext:nil];
XCTAssert([aliceSessionState.remoteIdentityKey isEqualToData:bobSessionState.localIdentityKey]);
}
- (void)runInteractionWithAliceRecord:(SessionRecord*)aliceSessionRecord bobRecord:(SessionRecord*)bobSessionRecord {
SessionCipher *aliceSessionCipher =
[[SessionCipher alloc] initWithAxolotlStore:self.aliceStore recipientId:self.bobIdentifier deviceId:1];
SessionCipher *bobSessionCipher =
[[SessionCipher alloc] initWithAxolotlStore:self.bobStore recipientId:self.aliceIdentifier deviceId:1];
NSData *alicePlainText = [@"This is a plaintext message!" dataUsingEncoding:NSUTF8StringEncoding];
WhisperMessage *cipherText = [aliceSessionCipher throws_encryptMessage:alicePlainText protocolContext:nil];
NSData *bobPlaintext = [bobSessionCipher throws_decrypt:cipherText protocolContext:nil];
XCTAssert([bobPlaintext isEqualToData:alicePlainText]);
}
@end