2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 #import "CloudKitMockXCTest.h"
27 #import "keychain/ckks/CKKS.h"
28 #import "keychain/ckks/CKKSControl.h"
29 #import "keychain/ckks/CKKSCurrentKeyPointer.h"
30 #import "keychain/ckks/CKKSItem.h"
31 #import "keychain/ckks/tests/CKKSMockSOSPresentAdapter.h"
32 #import "keychain/ot/OTCuttlefishAccountStateHolder.h"
33 #include "OSX/sec/Security/SecItemShim.h"
35 NS_ASSUME_NONNULL_BEGIN
38 @
class CKKSCurrentKeyPointer
;
40 @interface ZoneKeys
: CKKSCurrentKeySet
41 @property CKKSKey
* rolledTLK
;
43 - (instancetype
)initLoadingRecordsFromZone
:(FakeCKZone
*)zone
;
47 * Builds on the CloudKit mock infrastructure and adds keychain helper methods.
50 @interface CloudKitKeychainSyncingMockXCTest
: CloudKitMockXCTest
52 @property CKKSControl
* ckksControl
;
53 @
property (nullable
) id mockCKKSKeychainBackedKey
;
55 @
property (nullable
) NSError
* keychainFetchError
;
57 // A single trusted SOSPeer, but without any CKKS keys
58 @
property (nullable
) CKKSSOSPeer
* remoteSOSOnlyPeer
;
60 // Set this to false after calling -setUp if you want to initialize the views yourself
61 @property
bool automaticallyBeginCKKSViewCloudKitOperation
;
63 // Fill these in before allowing initialization to use your own mock instead of a default stub
64 @property id suggestTLKUpload
;
65 @property id requestPolicyCheck
;
67 @property NSMutableSet
<CKKSKeychainView
*>* ckksViews
;
68 @property NSMutableSet
<CKRecordZoneID
*>* ckksZones
;
69 @
property (nullable
) NSMutableDictionary
<CKRecordZoneID
*, ZoneKeys
*>* keys
;
71 // Pass in an oldTLK to wrap it to the new TLK; otherwise, pass nil
72 - (ZoneKeys
*)createFakeKeyHierarchy
:(CKRecordZoneID
*)zoneID oldTLK
:(CKKSKey
* _Nullable
)oldTLK
;
73 - (void)saveFakeKeyHierarchyToLocalDatabase
:(CKRecordZoneID
*)zoneID
;
74 - (void)putFakeKeyHierarchyInCloudKit
:(CKRecordZoneID
*)zoneID
;
75 - (void)saveTLKMaterialToKeychain
:(CKRecordZoneID
*)zoneID
;
76 - (void)deleteTLKMaterialFromKeychain
:(CKRecordZoneID
*)zoneID
;
77 - (void)saveTLKMaterialToKeychainSimulatingSOS
:(CKRecordZoneID
*)zoneID
;
78 - (void)putFakeDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
;
79 - (void)putFakeDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
80 zonekeys
:(ZoneKeys
*)zonekeys
;
82 - (void)putFakeOctagonOnlyDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
;
83 - (void)putFakeOctagonOnlyDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
84 zonekeys
:(ZoneKeys
*)zonekeys
;
86 - (void)SOSPiggyBackAddToKeychain
:(NSDictionary
*)piggydata
;
87 - (NSMutableDictionary
*)SOSPiggyBackCopyFromKeychain
;
88 - (NSMutableArray
<NSData
*>*)SOSPiggyICloudIdentities
;
90 // Octagon is responsible for telling CKKS that it's trusted.
91 // But, in these tests, use these to pretend that SOS is the only trust source around.
92 - (void)beginSOSTrustedOperationForAllViews
;
93 - (void)beginSOSTrustedViewOperation
:(CKKSKeychainView
*)view
;
94 - (void)endSOSTrustedOperationForAllViews
;
95 - (void)endSOSTrustedViewOperation
:(CKKSKeychainView
*)view
;
97 - (void)putTLKShareInCloudKit
:(CKKSKey
*)key
98 from
:(id
<CKKSSelfPeer
>)sharingPeer
99 to
:(id
<CKKSPeer
>)receivingPeer
100 zoneID
:(CKRecordZoneID
*)zoneID
;
101 - (void)putTLKSharesInCloudKit
:(CKKSKey
*)key from
:(CKKSSOSSelfPeer
*)sharingPeer zoneID
:(CKRecordZoneID
*)zoneID
;
102 - (void)putSelfTLKSharesInCloudKit
:(CKRecordZoneID
*)zoneID
;
103 - (void)saveTLKSharesInLocalDatabase
:(CKRecordZoneID
*)zoneID
;
105 - (void)saveClassKeyMaterialToKeychain
:(CKRecordZoneID
*)zoneID
;
107 // Call this to fake out your test: all keys are created, saved in cloudkit, and saved locally (as if the key state machine had processed them)
108 - (void)createAndSaveFakeKeyHierarchy
:(CKRecordZoneID
*)zoneID
;
110 - (void)rollFakeKeyHierarchyInCloudKit
:(CKRecordZoneID
*)zoneID
;
112 - (NSArray
<CKRecord
*>*)putKeySetInCloudKit
:(CKKSCurrentKeySet
*)keyset
;
113 - (void)performOctagonTLKUpload
:(NSSet
<CKKSKeychainView
*>*)views
;
114 - (void)performOctagonTLKUpload
:(NSSet
<CKKSKeychainView
*>*)views afterUpload
:(void (^_Nullable
)(void))afterUpload
;
116 - (NSDictionary
*)fakeRecordDictionary
:(NSString
* _Nullable
)account zoneID
:(CKRecordZoneID
*)zoneID
;
117 - (CKRecord
*)createFakeRecord
:(CKRecordZoneID
*)zoneID recordName
:(NSString
*)recordName
;
118 - (CKRecord
*)createFakeRecord
:(CKRecordZoneID
*)zoneID recordName
:(NSString
*)recordName withAccount
:(NSString
* _Nullable
)account
;
119 - (CKRecord
*)createFakeRecord
:(CKRecordZoneID
*)zoneID
120 recordName
:(NSString
*)recordName
121 withAccount
:(NSString
* _Nullable
)account
122 key
:(CKKSKey
* _Nullable
)key
;
124 - (CKRecord
*)createFakeTombstoneRecord
:(CKRecordZoneID
*)zoneID recordName
:(NSString
*)recordName account
:(NSString
*)account
;
126 - (CKKSItem
*)newItem
:(CKRecordID
*)recordID withNewItemData
:(NSDictionary
*) dictionary key
:(CKKSKey
*)key
;
127 - (CKRecord
*)newRecord
:(CKRecordID
*)recordID withNewItemData
:(NSDictionary
*)dictionary
;
128 - (CKRecord
*)newRecord
:(CKRecordID
*)recordID withNewItemData
:(NSDictionary
*)dictionary key
:(CKKSKey
*)key
;
129 - (NSDictionary
*)decryptRecord
:(CKRecord
*)record
;
131 - (void)addItemToCloudKitZone
:(NSDictionary
*)itemDict recordName
:(NSString
*)recordName zoneID
:(CKRecordZoneID
*)zoneID
;
133 // Do keychain things:
134 - (void)addGenericPassword
:(NSString
*)password account
:(NSString
*)account
;
135 - (void)addGenericPassword
:(NSString
*)password account
:(NSString
*)account viewHint
:(NSString
* _Nullable
)viewHint
;
136 - (void)addGenericPassword
:(NSString
*)password account
:(NSString
*)account accessGroup
:(NSString
*)accessGroup
;
137 - (void)addGenericPassword
:(NSString
*)password
138 account
:(NSString
*)account
139 viewHint
:(NSString
* _Nullable
)viewHint
140 access
:(NSString
*)access
141 expecting
:(OSStatus
)status
142 message
:(NSString
*)message
;
144 - (BOOL
)addGenericPassword
:(NSString
*)password
145 account
:(NSString
*)account
146 access
:(NSString
*)access
147 viewHint
:(NSString
* _Nullable
)viewHint
148 accessGroup
:(NSString
* _Nullable
)accessGroup
149 expecting
:(OSStatus
)status
150 message
:(NSString
*)message
;
152 - (void)addGenericPassword
:(NSString
*)password account
:(NSString
*)account expecting
:(OSStatus
)status message
:(NSString
*)message
;
154 - (void)updateGenericPassword
:(NSString
*)newPassword account
:(NSString
*)account
;
155 - (void)updateAccountOfGenericPassword
:(NSString
*)newAccount account
:(NSString
*)account
;
157 - (void)checkNoCKKSData
:(CKKSKeychainView
*)view
;
159 - (void)deleteGenericPassword
:(NSString
*)account
;
160 - (void)deleteGenericPasswordWithoutTombstones
:(NSString
*)account
;
162 - (void)findGenericPassword
:(NSString
*)account expecting
:(OSStatus
)status
;
163 - (void)checkGenericPassword
:(NSString
*)password account
:(NSString
*)account
;
165 - (void)checkGenericPasswordStoredUUID
:(NSString
*)uuid account
:(NSString
*)account
;
166 - (void)setGenericPasswordStoredUUID
:(NSString
*)uuid account
:(NSString
*)account
;
168 - (void)createClassCItemAndWaitForUpload
:(CKRecordZoneID
*)zoneID account
:(NSString
*)account
;
169 - (void)createClassAItemAndWaitForUpload
:(CKRecordZoneID
*)zoneID account
:(NSString
*)account
;
171 // Pass the blocks created with these to expectCKModifyItemRecords to check if all items were encrypted with a particular class key
172 - (BOOL (^)(CKRecord
*))checkClassABlock
:(CKRecordZoneID
*)zoneID message
:(NSString
*)message
;
173 - (BOOL (^)(CKRecord
*))checkClassCBlock
:(CKRecordZoneID
*)zoneID message
:(NSString
*)message
;
175 - (BOOL (^)(CKRecord
*))checkPasswordBlock
:(CKRecordZoneID
*)zoneID account
:(NSString
*)account password
:(NSString
*)password
;
177 - (void)checkNSyncableTLKsInKeychain
:(size_t)n
;
179 // Returns an expectation that someone will send an NSNotification that this view changed
180 - (XCTestExpectation
*)expectChangeForView
:(NSString
*)view
;
182 // Establish an assertion that CKKS will cause a server extension error soon.
183 - (void)expectCKReceiveSyncKeyHierarchyError
:(CKRecordZoneID
*)zoneID
;
185 // Add expectations that CKKS will upload a single TLK share
186 - (void)expectCKKSTLKSelfShareUpload
:(CKRecordZoneID
*)zoneID
;
188 // Can't call OCMVerifyMock due to Swift? Use this.
189 - (void)verifyDatabaseMocks
;
192 NS_ASSUME_NONNULL_END