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/proto/generated_source/OTAccountMetadataClassC.h"
33 #import "keychain/ot/OTCuttlefishAccountStateHolder.h"
34 #include "OSX/sec/Security/SecItemShim.h"
36 NS_ASSUME_NONNULL_BEGIN
39 @
class CKKSCurrentKeyPointer
;
41 @interface ZoneKeys
: CKKSCurrentKeySet
42 @property CKKSKey
* rolledTLK
;
44 - (instancetype
)initLoadingRecordsFromZone
:(FakeCKZone
*)zone
;
48 * Builds on the CloudKit mock infrastructure and adds keychain helper methods.
51 @interface CloudKitKeychainSyncingMockXCTest
: CloudKitMockXCTest
53 @property CKKSControl
* ckksControl
;
54 @property OTCuttlefishAccountStateHolder
*accountMetaDataStore
;
55 @
property (nullable
) id mockCKKSKeychainBackedKey
;
57 @
property (nullable
) NSError
* keychainFetchError
;
59 // A single trusted SOSPeer, but without any CKKS keys
60 @property CKKSSOSPeer
* remoteSOSOnlyPeer
;
62 // Set this to false after calling -setUp if you want to initialize the views yourself
63 @property
bool automaticallyBeginCKKSViewCloudKitOperation
;
65 // Fill this in before allowing initialization to use your own mock instead of a default stub
66 @property id suggestTLKUpload
;
68 @property NSMutableSet
<CKKSKeychainView
*>* ckksViews
;
69 @property NSMutableSet
<CKRecordZoneID
*>* ckksZones
;
70 @
property (nullable
) NSMutableDictionary
<CKRecordZoneID
*, ZoneKeys
*>* keys
;
72 // Pass in an oldTLK to wrap it to the new TLK; otherwise, pass nil
73 - (ZoneKeys
*)createFakeKeyHierarchy
:(CKRecordZoneID
*)zoneID oldTLK
:(CKKSKey
* _Nullable
)oldTLK
;
74 - (void)saveFakeKeyHierarchyToLocalDatabase
:(CKRecordZoneID
*)zoneID
;
75 - (void)putFakeKeyHierarchyInCloudKit
:(CKRecordZoneID
*)zoneID
;
76 - (void)saveTLKMaterialToKeychain
:(CKRecordZoneID
*)zoneID
;
77 - (void)deleteTLKMaterialFromKeychain
:(CKRecordZoneID
*)zoneID
;
78 - (void)saveTLKMaterialToKeychainSimulatingSOS
:(CKRecordZoneID
*)zoneID
;
79 - (void)putFakeDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
;
80 - (void)putFakeDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
81 zonekeys
:(ZoneKeys
*)zonekeys
;
83 - (void)putFakeOctagonOnlyDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
;
84 - (void)putFakeOctagonOnlyDeviceStatusInCloudKit
:(CKRecordZoneID
*)zoneID
85 zonekeys
:(ZoneKeys
*)zonekeys
;
87 - (void)SOSPiggyBackAddToKeychain
:(NSDictionary
*)piggydata
;
88 - (NSMutableDictionary
*)SOSPiggyBackCopyFromKeychain
;
89 - (NSMutableArray
<NSData
*>*)SOSPiggyICloudIdentities
;
91 // Octagon is responsible for telling CKKS that it's trusted.
92 // But, in these tests, use these to pretend that SOS is the only trust source around.
93 - (void)beginSOSTrustedOperationForAllViews
;
94 - (void)beginSOSTrustedViewOperation
:(CKKSKeychainView
*)view
;
95 - (void)endSOSTrustedOperationForAllViews
;
96 - (void)endSOSTrustedViewOperation
:(CKKSKeychainView
*)view
;
98 - (void)putTLKShareInCloudKit
:(CKKSKey
*)key
99 from
:(id
<CKKSSelfPeer
>)sharingPeer
100 to
:(id
<CKKSPeer
>)receivingPeer
101 zoneID
:(CKRecordZoneID
*)zoneID
;
102 - (void)putTLKSharesInCloudKit
:(CKKSKey
*)key from
:(CKKSSOSSelfPeer
*)sharingPeer zoneID
:(CKRecordZoneID
*)zoneID
;
103 - (void)putSelfTLKSharesInCloudKit
:(CKRecordZoneID
*)zoneID
;
104 - (void)saveTLKSharesInLocalDatabase
:(CKRecordZoneID
*)zoneID
;
106 - (void)saveClassKeyMaterialToKeychain
:(CKRecordZoneID
*)zoneID
;
108 // 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)
109 - (void)createAndSaveFakeKeyHierarchy
:(CKRecordZoneID
*)zoneID
;
111 - (void)rollFakeKeyHierarchyInCloudKit
:(CKRecordZoneID
*)zoneID
;
113 - (NSArray
<CKRecord
*>*)putKeySetInCloudKit
:(CKKSCurrentKeySet
*)keyset
;
114 - (void)performOctagonTLKUpload
:(NSSet
<CKKSKeychainView
*>*)views
;
115 - (void)performOctagonTLKUpload
:(NSSet
<CKKSKeychainView
*>*)views afterUpload
:(void (^_Nullable
)(void))afterUpload
;
117 - (NSDictionary
*)fakeRecordDictionary
:(NSString
* _Nullable
)account zoneID
:(CKRecordZoneID
*)zoneID
;
118 - (CKRecord
*)createFakeRecord
:(CKRecordZoneID
*)zoneID recordName
:(NSString
*)recordName
;
119 - (CKRecord
*)createFakeRecord
:(CKRecordZoneID
*)zoneID recordName
:(NSString
*)recordName withAccount
:(NSString
* _Nullable
)account
;
120 - (CKRecord
*)createFakeRecord
:(CKRecordZoneID
*)zoneID
121 recordName
:(NSString
*)recordName
122 withAccount
:(NSString
* _Nullable
)account
123 key
:(CKKSKey
* _Nullable
)key
;
125 - (CKKSItem
*)newItem
:(CKRecordID
*)recordID withNewItemData
:(NSDictionary
*) dictionary key
:(CKKSKey
*)key
;
126 - (CKRecord
*)newRecord
:(CKRecordID
*)recordID withNewItemData
:(NSDictionary
*)dictionary
;
127 - (CKRecord
*)newRecord
:(CKRecordID
*)recordID withNewItemData
:(NSDictionary
*)dictionary key
:(CKKSKey
*)key
;
128 - (NSDictionary
*)decryptRecord
:(CKRecord
*)record
;
130 // Do keychain things:
131 - (void)addGenericPassword
:(NSString
*)password account
:(NSString
*)account
;
132 - (void)addGenericPassword
:(NSString
*)password account
:(NSString
*)account viewHint
:(NSString
* _Nullable
)viewHint
;
133 - (void)addGenericPassword
:(NSString
*)password
134 account
:(NSString
*)account
135 viewHint
:(NSString
* _Nullable
)viewHint
136 access
:(NSString
*)access
137 expecting
:(OSStatus
)status
138 message
:(NSString
*)message
;
139 - (void)addGenericPassword
:(NSString
*)password account
:(NSString
*)account expecting
:(OSStatus
)status message
:(NSString
*)message
;
141 - (void)updateGenericPassword
:(NSString
*)newPassword account
:(NSString
*)account
;
142 - (void)updateAccountOfGenericPassword
:(NSString
*)newAccount account
:(NSString
*)account
;
144 - (void)checkNoCKKSData
:(CKKSKeychainView
*)view
;
146 - (void)deleteGenericPassword
:(NSString
*)account
;
147 - (void)deleteGenericPasswordWithoutTombstones
:(NSString
*)account
;
149 - (void)findGenericPassword
:(NSString
*)account expecting
:(OSStatus
)status
;
150 - (void)checkGenericPassword
:(NSString
*)password account
:(NSString
*)account
;
152 - (void)createClassCItemAndWaitForUpload
:(CKRecordZoneID
*)zoneID account
:(NSString
*)account
;
153 - (void)createClassAItemAndWaitForUpload
:(CKRecordZoneID
*)zoneID account
:(NSString
*)account
;
155 // Pass the blocks created with these to expectCKModifyItemRecords to check if all items were encrypted with a particular class key
156 - (BOOL (^)(CKRecord
*))checkClassABlock
:(CKRecordZoneID
*)zoneID message
:(NSString
*)message
;
157 - (BOOL (^)(CKRecord
*))checkClassCBlock
:(CKRecordZoneID
*)zoneID message
:(NSString
*)message
;
159 - (BOOL (^)(CKRecord
*))checkPasswordBlock
:(CKRecordZoneID
*)zoneID account
:(NSString
*)account password
:(NSString
*)password
;
161 - (void)checkNSyncableTLKsInKeychain
:(size_t)n
;
163 // Returns an expectation that someone will send an NSNotification that this view changed
164 - (XCTestExpectation
*)expectChangeForView
:(NSString
*)view
;
166 // Establish an assertion that CKKS will cause a server extension error soon.
167 - (void)expectCKReceiveSyncKeyHierarchyError
:(CKRecordZoneID
*)zoneID
;
169 // Add expectations that CKKS will upload a single TLK share
170 - (void)expectCKKSTLKSelfShareUpload
:(CKRecordZoneID
*)zoneID
;
172 // Can't call OCMVerifyMock due to Swift? Use this.
173 - (void)verifyDatabaseMocks
;
176 NS_ASSUME_NONNULL_END