]> git.saurik.com Git - apple/security.git/blob - keychain/ot/tests/OTContextTests.m
Security-59306.11.20.tar.gz
[apple/security.git] / keychain / ot / tests / OTContextTests.m
1 /*
2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #if OCTAGON
26
27 #import <Foundation/Foundation.h>
28 #import <XCTest/XCTest.h>
29 #import <OCMock/OCMock.h>
30
31 #import "OTTestsBase.h"
32
33 static NSString* const testContextID = @"Foo";
34 static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer";
35
36 @interface UnitTestOTContext : OTTestsBase
37 @property (nonatomic, strong) OTBottledPeerRecord* fakeBottledPeerRecord;
38 @end
39
40 @implementation UnitTestOTContext
41
42 - (void)setUp
43 {
44 [super setUp];
45 self.continueAfterFailure = NO;
46 }
47
48 - (void)tearDown
49 {
50 self.zones = nil;
51 self.operationQueue = nil;
52 [super tearDown];
53 }
54
55 -(void) testEnroll
56 {
57 NSError* error = nil;
58
59 NSString* escrowRecordID = [self currentIdentity:&error].spID;
60 XCTAssertNil(error, @"error should be nil: %@", error);
61 XCTAssertNotNil(escrowRecordID, @"escrowRecordID should not be nil: %@", error);
62
63 NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil];
64
65 [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES];
66 [self startCKKSSubsystem];
67
68 OTPreflightInfo* info = nil;
69 XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info:%@", error);
70 XCTAssertNil(error, @"error should be nil: %@", error);
71 XCTAssertNotNil(info, @"preflight info should not be nil: %@", error);
72 XCTAssertNotNil(info.bottleID, @"escrowRecordID should not be nil: %@", error);
73 XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error);
74
75 OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error];
76 XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error);
77
78 XCTAssertTrue([self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:escrowRecordID error:&error], @"launch should succeed");
79 XCTAssertNil(error, @"error should be nil: %@", error);
80 [self releaseCloudKitFetchHold];
81
82 [self expectCKFetch];
83 XCTAssertEqual( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count], (unsigned long)1, @"should have 1 record");
84 }
85
86 -(void) testEnrollAndRestore
87 {
88 NSError* error = nil;
89 [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID];
90
91 NSString* escrowRecordID = [self currentIdentity:&error].spID;
92 XCTAssertNil(error, @"error should be nil: %@", error);
93 XCTAssertNotNil(escrowRecordID, @"escrowRecordID should not be nil: %@", error);
94
95 NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil];
96
97 [self startCKKSSubsystem];
98
99 OTPreflightInfo* info = nil;
100 XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info");
101 XCTAssertNil(error, @"error should be nil: %@", error);
102 XCTAssertNotNil(info, @"preflight info should not be nil: %@", error);
103 XCTAssertNotNil(info.bottleID, @"escrowRecordID should not be nil: %@", error);
104 XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error);
105
106 OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error];
107 XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error);
108
109 [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO];
110 XCTAssertTrue([self.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:bprecord.escrowRecordID error:&error], @"should create bottled peer record");
111 XCTAssertNil(error, "error should be nil");
112 [self waitForCKModifications];
113
114 [self releaseCloudKitFetchHold];
115
116 OTBottledPeerSigned* bp = [self.context restoreFromEscrowRecordID:escrowRecordID secret:self.secret error:&error];
117 [self waitForCKModifications];
118
119 XCTAssertTrue( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count] == 1, @"should have 1 record");
120 [self waitForCKModifications];
121
122 XCTAssertNil(error, @"error should be nil: %@", error);
123 XCTAssertNotNil(bp, @"signed bottled peer should not be nil: %@", error);
124 XCTAssertTrue([bp.bp.peerEncryptionKey isEqual:self.peerEncryptionKey], @"enrolled and restored peer encryption keys should match");
125 XCTAssertTrue([bp.bp.peerSigningKey isEqual:self.peerSigningKey], @"enrolled and restored peer signing keys should match");
126 }
127
128 -(void)testEnrollAndRestoreFromCloudKit
129 {
130 NSError* error = nil;
131 [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID];
132
133 NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil];
134
135 [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES];
136 [self startCKKSSubsystem];
137
138 OTPreflightInfo* info = nil;
139 XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info");
140 XCTAssertNil(error, @"error should be nil: %@", error);
141 XCTAssertNotNil(info, @"preflight info should not be nil: %@", error);
142 XCTAssertNotNil(info.bottleID, @"bottleID should not be nil: %@", error);
143 XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error);
144
145 OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error];
146 XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error);
147
148 XCTAssertTrue([self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:info.bottleID error:&error], @"launch should succeed");
149 XCTAssertNil(error, @"error should be nil: %@", error);
150
151 [self waitForCKModifications];
152 OCMVerifyAllWithDelay(self.mockDatabase, 8);
153 [self releaseCloudKitFetchHold];
154
155 XCTAssertTrue([[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count] > 0, @"should have multiple records");
156 OTIdentity *identity = [self currentIdentity:&error];
157
158 XCTAssertNil(error, @"error should be nil: %@", error);
159 XCTAssertNotNil(self.escrowKeys, @"escrow keys should not be nil: %@", error);
160
161 NSString* recordName = [OTBottledPeerRecord constructRecordID:identity.spID escrowSigningSPKI:[self.escrowKeys.signingKey.publicKey encodeSubjectPublicKeyInfo]];
162
163 OTBottledPeerRecord *rec = [self.localStore readLocalBottledPeerRecordWithRecordID:recordName error:&error];
164
165 XCTAssertNotNil(rec.signatureUsingEscrowKey, @"signatureUsingEscrow should not be nil: %@", error);
166
167 XCTAssertNotNil(rec.signatureUsingPeerKey, @"signatureUsingPeerKey should not be nil: %@", error);
168
169 XCTAssertNotNil(rec.bottle, @"bottle should not be nil: %@", error);
170
171
172 OTBottledPeerSigned *bps = [[OTBottledPeerSigned alloc] initWithBottledPeerRecord:rec
173 escrowKeys:self.escrowKeys
174 error:&error];
175 XCTAssertNil(error, @"error should be nil: %@", error);
176 XCTAssertNotNil(bps, @"signed bottled peer should not be nil: %@", error);
177 XCTAssertTrue([bps.bp.peerEncryptionKey isEqual:self.peerEncryptionKey], @"enrolled and restored peer encryption keys should match");
178 XCTAssertTrue([bps.bp.peerSigningKey isEqual:self.peerSigningKey], @"enrolled and restored peer signing keys should match");
179 }
180
181 -(void) testScrubbing
182 {
183 NSError* error = nil;
184
185 NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil];
186
187 [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES];
188 [self startCKKSSubsystem];
189
190 OTPreflightInfo* info = nil;
191 XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info");
192 XCTAssertNil(error, @"error should be nil: %@", error);
193 XCTAssertNotNil(info, @"preflight info should not be nil: %@", error);
194 XCTAssertNotNil(info.bottleID, @"escrowRecordID should not be nil: %@", error);
195 XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error);
196
197 XCTAssertTrue([self.context scrubBottledPeer:testContextID bottleID:info.bottleID error:&error], @"scrubbing bottled peer should succeed");
198 XCTAssertNil(error, @"error should be nil: %@", error);
199 NSArray* list = [self.context.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error];
200 XCTAssertTrue([list count] == 0, @"there should be 0 records in localstore");
201 }
202
203 -(void) testGettingListOfRecordIDS
204 {
205 NSError* error = nil;
206
207 NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil];
208 [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES];
209 [self startCKKSSubsystem];
210
211 OTPreflightInfo* info = nil;
212 XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info");
213 XCTAssertNil(error, @"error should be nil: %@", error);
214 XCTAssertNotNil(info, @"preflight info should not be nil: %@", error);
215 XCTAssertNotNil(info.bottleID, @"bottleID should not be nil: %@", error);
216 XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error);
217
218 OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error];
219 XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error);
220
221 XCTAssertTrue([self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:info.bottleID error:&error], @"launch should succeed");
222 XCTAssertNil(error, @"error should be nil: %@", error);
223
224 [self waitForCKModifications];
225 OCMVerifyAllWithDelay(self.mockDatabase, 8);
226 [self releaseCloudKitFetchHold];
227
228 NSArray* list = [self.context.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error];
229 XCTAssertNotNil(list, @"list should not be nil");
230 XCTAssertTrue([list count] > 0, @"list of escrow record ids should not be empty");
231 }
232
233 - (nullable OTIdentity *)currentIdentity:(NSError**)error {
234
235 return [[OTIdentity alloc]initWithPeerID:@"ego peer id" spID:@"sos peer id" peerSigningKey:self.peerSigningKey peerEncryptionkey:self.peerEncryptionKey error:error];
236 }
237
238 @end
239 #endif
240