]> git.saurik.com Git - apple/security.git/blob - keychain/ot/tests/OTBottledPeerTLK.m
Security-59306.11.20.tar.gz
[apple/security.git] / keychain / ot / tests / OTBottledPeerTLK.m
1 /*
2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
3 *
4 * @APPLEself.LICENSEself.HEADERself.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 * @APPLEself.LICENSEself.HEADERself.END@
22 */
23
24 #if OCTAGON
25
26 #import "OTTestsBase.h"
27
28 @interface BottledPeerRestoreTLKTests : OTTestsBase
29 @property CKKSSOSSelfPeer* remotePeer1;
30 @property CKKSSOSPeer* remotePeer2;
31 @property CKKSSOSSelfPeer* untrustedPeer;
32
33 @end
34
35 @implementation BottledPeerRestoreTLKTests
36
37 - (void)setUp
38 {
39 [super setUp];
40
41 //set up a bottled peer and stick it in localStore
42 NSError* error = nil;
43
44 self.remotePeer1 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:self.sosPeerID
45 encryptionKey:self.peerEncryptionKey
46 signingKey:self.peerSigningKey];
47
48 [self.currentPeers addObject:self.remotePeer1];
49
50 OTBottledPeer *bp = [[OTBottledPeer alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionKey:self.peerEncryptionKey escrowKeys:self.escrowKeys error:&error];
51
52 XCTAssertNotNil(bp, @"plaintext should not be nil");
53 XCTAssertNil(error, @"error should be nil");
54 XCTAssertNotNil(self.escrowKeys.signingKey, @"signing public key should not be nil");
55 XCTAssertNotNil(self.escrowKeys.encryptionKey, @"encryption public key should not be nil");
56
57 OTBottledPeerSigned *bpSigned = [[OTBottledPeerSigned alloc]initWithBottledPeer:bp escrowedSigningKey:self.escrowKeys.signingKey peerSigningKey:self.peerSigningKey error:&error];
58
59 OTBottledPeerRecord* record = [bpSigned asRecord:[self currentIdentity:&error].spID];
60 self.recordName = record.recordName;
61
62 OTIdentity* identity = [self currentIdentity:&error];
63 [self.localStore insertBottledPeerRecord:record escrowRecordID:identity.spID error:&error];
64
65 self.remotePeer1 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"remote-peer1"
66 encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]
67 signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]];
68
69 self.remotePeer2 = [[CKKSSOSPeer alloc] initWithSOSPeerID:@"remote-peer2"
70 encryptionPublicKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]].publicKey
71 signingPublicKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]].publicKey];
72
73 // Local SOS trusts these peers
74 [self.currentPeers addObject:self.remotePeer1];
75 [self.currentPeers addObject:self.remotePeer2];
76
77 self.untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer"
78 encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]
79 signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]];
80 }
81
82 - (void)tearDown
83 {
84 _remotePeer1 = nil;
85 _remotePeer2 = nil;
86 _untrustedPeer = nil;
87 [super tearDown];
88 }
89
90 -(void) testTLKSharingWithRestoredBottledPeer
91 {
92 NSError* error = nil;
93
94 OTBottledPeerRecord *rec = [self.localStore readLocalBottledPeerRecordWithRecordID:self.recordName error:&error];
95 XCTAssertNotNil(rec, @"rec should not be nil: %@", error);
96 XCTAssertNil(error, @"error should be nil: %@", error);
97
98 OTBottledPeerSigned *bps = [[OTBottledPeerSigned alloc] initWithBottledPeerRecord:rec
99 escrowKeys:self.escrowKeys
100 error:&error];
101 XCTAssertNil(error, @"error should be nil: %@", error);
102 XCTAssertNotNil(bps, @"signed bottled peer should not be nil: %@", error);
103 XCTAssertTrue([bps.bp.peerEncryptionKey isEqual:self.peerEncryptionKey], @"enrolled and restored peer encryption keys should match");
104 XCTAssertTrue([bps.bp.peerSigningKey isEqual:self.peerSigningKey], @"enrolled and restored peer signing keys should match");
105
106
107 CKKSSelves* selves = [[CKKSViewManager manager] fetchSelfPeers:&error];
108 XCTAssertNotNil(selves, @"selves should not be nil: %@", error);
109
110 XCTAssertTrue([selves.allSelves count] == 2, @"should have 2 selves");
111 NSArray *arrayOfSelves = [selves.allSelves allObjects];
112 XCTAssertNotNil(arrayOfSelves, @"arrayOfSelves should not be nil: %@", error);
113
114 CKKSSOSSelfPeer *ourRestoredPeer = [arrayOfSelves objectAtIndex:0];
115 if([ourRestoredPeer.peerID isEqualToString:@"spid-local-peer"]){
116 ourRestoredPeer = [arrayOfSelves objectAtIndex:1];
117 }
118
119 XCTAssertTrue([ourRestoredPeer.peerID containsString:self.sosPeerID], @"peer ids should match!");
120 XCTAssertTrue([ourRestoredPeer.signingKey isEqual:self.peerSigningKey], @"signing keys should match");
121 XCTAssertTrue([ourRestoredPeer.encryptionKey isEqual:self.peerEncryptionKey], @"encryption keys should match");
122
123 [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID];
124 [self putFakeDeviceStatusInCloudKit:self.keychainZoneID];
125 [self startCKKSSubsystem];
126
127 // The CKKS subsystem should not try to write anything to the CloudKit database, but it should enter waitfortlk
128 XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk");
129
130 // peer1 arrives to save the day
131 // The CKKS subsystem should accept the keys, and share the TLK back to itself
132 [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID];
133
134 [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:ourRestoredPeer zoneID:self.keychainZoneID];
135 [self.keychainView notifyZoneChange:nil];
136 [self.keychainView waitForFetchAndIncomingQueueProcessing];
137
138 XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready");
139
140 // We expect a single record to be uploaded for each key class
141 [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
142 checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]];
143 [self addGenericPassword: @"data" account: @"account-delete-me"];
144 OCMVerifyAllWithDelay(self.mockDatabase, 8);
145
146 [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID
147 checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]];
148 [self addGenericPassword:@"asdf"
149 account:@"account-class-A"
150 viewHint:nil
151 access:(id)kSecAttrAccessibleWhenUnlocked
152 expecting:errSecSuccess
153 message:@"Adding class A item"];
154 OCMVerifyAllWithDelay(self.mockDatabase, 8);
155 }
156
157 - (nullable OTIdentity *)currentIdentity:(NSError * _Nullable __autoreleasing * _Nullable)error {
158 return [[OTIdentity alloc]initWithPeerID:@"ego peer id" spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionkey:self.peerEncryptionKey error:error];
159 }
160
161 @end
162 #endif