]> git.saurik.com Git - apple/security.git/blob - KeychainCircle/Tests/FakeSOSControl.m
Security-59754.41.1.tar.gz
[apple/security.git] / KeychainCircle / Tests / FakeSOSControl.m
1
2 #import "FakeSOSControl.h"
3
4 @implementation FakeNSXPCConnection
5 - (instancetype) initWithControl:(id<SOSControlProtocol>)control
6 {
7 if ((self = [super init])) {
8 _control = control;
9 }
10 return self;
11 }
12 - (id)remoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler
13 {
14 (void)failureHandler;
15 return _control;
16 }
17 @end
18
19 @implementation FCPairingFakeSOSControl
20
21 - (instancetype)initWithRandomAccountKey:(bool)randomAccountKey circle:(SOSCircleRef)circle
22 {
23 if ((self = [super init])) {
24 SecKeyRef publicKey = NULL;
25 NSDictionary* parameters = @{
26 (__bridge NSString*)kSecAttrKeyType:(__bridge NSString*) kSecAttrKeyTypeEC,
27 (__bridge NSString*)kSecAttrKeySizeInBits: @(256),
28 (__bridge NSString*)kSecUseDataProtectionKeychain : @YES,
29 (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock,
30 (__bridge id)kSecPrivateKeyAttrs : @{
31 (__bridge NSString*)kSecAttrLabel : @"delete me test case - private",
32 (__bridge NSString*)kSecAttrIsPermanent : @YES,
33 (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock,
34 },
35 (__bridge id)kSecPublicKeyAttrs : @{
36 (__bridge NSString*)kSecAttrLabel : @"delete me test case - public",
37 (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock,
38 }
39 };
40 if(SecKeyGeneratePair((__bridge CFDictionaryRef)parameters, &publicKey, &_deviceKey) != 0) {
41 NSLog(@"failed to create device key");
42 return nil;
43 }
44 CFReleaseNull(publicKey);
45
46 NSMutableDictionary* octagonParameters = [parameters mutableCopy];
47 octagonParameters[(__bridge NSString*)kSecAttrKeySizeInBits] = @(384);
48 if(SecKeyGeneratePair((__bridge CFDictionaryRef)octagonParameters, &publicKey, &_octagonSigningKey) != 0) {
49 NSLog(@"failed to create octagon signing key");
50 return nil;
51 }
52 CFReleaseNull(publicKey);
53
54 if(SecKeyGeneratePair((__bridge CFDictionaryRef)octagonParameters, &publicKey, &_octagonEncryptionKey) != 0) {
55 NSLog(@"failed to create octagon signing key");
56 return nil;
57 }
58 CFReleaseNull(publicKey);
59
60
61 _circle = (SOSCircleRef)CFRetain(circle);
62
63 CFErrorRef error = NULL;
64
65 CFDictionaryRef gestalt = (__bridge CFDictionaryRef)@{
66 @"ComputerName" : @"name",
67 };
68
69 _fullPeerInfo = SOSFullPeerInfoCreate(NULL, gestalt, NULL, _deviceKey, _octagonSigningKey, _octagonEncryptionKey, &error);
70 CFReleaseNull(error);
71
72 if (randomAccountKey) {
73
74 NSDictionary* accountParams = @{
75 (__bridge NSString*)kSecAttrKeyType:(__bridge NSString*) kSecAttrKeyTypeEC,
76 (__bridge NSString*)kSecAttrKeySizeInBits: @(256),
77 (__bridge NSString*)kSecUseDataProtectionKeychain : @YES,
78 (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock,
79 };
80
81 if(SecKeyGeneratePair((__bridge CFDictionaryRef)accountParams, &publicKey, &_accountPrivateKey) != 0) {
82 NSLog(@"failed to create account signing key");
83 return nil;
84 }
85 CFReleaseNull(publicKey);
86
87 _accountPublicKey = SecKeyCopyPublicKey(_accountPrivateKey);
88
89 [self signApplicationIfNeeded];
90 }
91 }
92 return self;
93 }
94
95 - (void)dealloc
96 {
97 if (_accountPrivateKey) {
98 SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_accountPrivateKey });
99 CFReleaseNull(_accountPrivateKey);
100 }
101 if (_deviceKey) {
102 SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_deviceKey });
103 CFReleaseNull(_deviceKey);
104 }
105 if (_octagonSigningKey) {
106 SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_octagonSigningKey });
107 CFReleaseNull(_octagonSigningKey);
108 }
109 if (_octagonEncryptionKey) {
110 SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_octagonEncryptionKey });
111 CFReleaseNull(_octagonEncryptionKey);
112 }
113 CFReleaseNull(_circle);
114 CFReleaseNull(_fullPeerInfo);
115 }
116
117 - (SOSPeerInfoRef)peerInfo
118 {
119 return SOSFullPeerInfoGetPeerInfo(_fullPeerInfo);
120 }
121
122 - (void)signApplicationIfNeeded
123 {
124 CFErrorRef error = NULL;
125
126 _application = SOSFullPeerInfoPromoteToApplication(_fullPeerInfo, _accountPrivateKey, &error);
127 if (!_application)
128 abort();
129 }
130
131 - (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete
132 {
133 // Make up a fake TLK
134 NSMutableArray<NSDictionary *> *items = [NSMutableArray array];
135 if (flags & SOSControlInitialSyncFlagTLK) {
136 NSString *tlkUUID = [[NSUUID UUID] UUIDString];
137 NSDictionary *fakeTLK = @{
138 @"class": @"inet",
139 @"agrp": @"com.apple.security.ckks",
140 @"vwht": @"PCS-master",
141 @"pdmn": @"ck",
142 @"desc": @"tlk",
143 @"srvr": @"fakeZone",
144 @"acct": tlkUUID,
145 @"path": tlkUUID,
146 @"v_Data": [NSData data],
147 };
148 [items addObject:fakeTLK];
149 }
150 complete(items, nil);
151 }
152
153 - (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete
154 {
155 complete(true, nil);
156 }
157
158 - (void)rpcTriggerSync:(NSArray<NSString *> *)peers complete:(void(^)(bool success, NSError *))complete
159 {
160 complete(true, NULL);
161 }
162
163 //MARK - FCPairingFakeSOSControl SOSControlProtocol
164
165 - (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))complete
166 {
167 complete(false, NULL, NULL);
168 }
169
170 - (void)performanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))complete
171 {
172 complete(@{});
173 }
174 - (void)kvsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))complete
175 {
176 complete(@{});
177 }
178
179 - (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary <NSString *, NSString *> *))complete
180 {
181 complete(@{});
182 }
183 - (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))complete
184 {
185 NSData *publicKey = NULL;
186 NSError *error = NULL;
187 if (self.accountPrivateKey) {
188 publicKey = CFBridgingRelease(SecKeyCopySubjectPublicKeyInfo(self.accountPrivateKey));
189 } else {
190 error = [NSError errorWithDomain:@"FCPairingFakeSOSControl" code:2 userInfo:NULL];
191 }
192 complete(publicKey, error);
193 }
194
195 - (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))complete
196 {
197 complete(self.accountPrivateKey != NULL, NULL);
198 }
199
200 - (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete
201 {
202 NSData *key = NULL;
203 CFErrorRef error = NULL;
204 if (self.accountPrivateKey) {
205 key = CFBridgingRelease(SecKeyCopyExternalRepresentation(self.accountPrivateKey, &error));
206 } else {
207 error = (CFErrorRef)CFBridgingRetain([NSError errorWithDomain:@"FCPairingFakeSOSControl" code:1 userInfo:NULL]);
208 }
209 complete(key, (__bridge NSError *)error);
210 CFReleaseNull(error);
211 }
212
213 - (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete
214 {
215 SecKeyRef accountPrivateKey = NULL;
216 CFErrorRef error = NULL;
217 NSDictionary *attributes = @{
218 (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPrivate,
219 (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC,
220 };
221
222 accountPrivateKey = SecKeyCreateWithData((__bridge CFDataRef)credential, (__bridge CFDictionaryRef)attributes, &error);
223 if (accountPrivateKey == NULL) {
224 complete(false, (__bridge NSError *)error);
225 CFReleaseNull(error);
226 return;
227 }
228
229 _accountPrivateKey = accountPrivateKey;
230 _accountPublicKey = SecKeyCopyPublicKey(_accountPrivateKey);
231
232 [self signApplicationIfNeeded];
233
234 complete(true, NULL);
235 }
236
237 - (void)myPeerInfo:(void(^)(NSData *application, NSError *error))complete
238 {
239 CFErrorRef error = NULL;
240
241 [self signApplicationIfNeeded];
242
243 NSData *application = CFBridgingRelease(SOSPeerInfoCopyEncodedData([self peerInfo], NULL, &error));
244 complete(application, (__bridge NSError *)error);
245
246 CFReleaseNull(error);
247 }
248
249 - (void)circleHash:(void (^)(NSString *, NSError *))complete
250 {
251 NSString *data = CFBridgingRelease(SOSCircleCopyHashString(_circle));
252 complete(data, NULL);
253 }
254
255 - (void)circleJoiningBlob:(NSData *)applicantData complete:(void (^)(NSData *blob, NSError *))complete
256 {
257 CFErrorRef error = NULL;
258 CFDataRef signature = NULL;
259 SOSCircleRef prunedCircle = SOSCircleCopyCircle(NULL, _circle, &error);
260 (void)SOSCirclePreGenerationSign(prunedCircle, _accountPublicKey, &error);
261
262 SOSGenCountRef gencount = SOSGenerationIncrementAndCreate(SOSCircleGetGeneration(prunedCircle));
263 if (gencount == NULL)
264 abort();
265
266
267 SOSPeerInfoRef applicant = SOSPeerInfoCreateFromData(NULL, &error, (__bridge CFDataRef)applicantData);
268 if (applicant == NULL)
269 abort();
270
271 signature = SOSCircleCopyNextGenSignatureWithPeerAdded(prunedCircle, applicant, _deviceKey, &error);
272 if(applicant) {
273 CFRelease(applicant);
274 applicant = NULL;
275 }
276
277 NSData *pbblob = CFBridgingRelease(SOSPiggyBackBlobCopyEncodedData(gencount, _deviceKey, signature, &error));
278
279 CFReleaseNull(signature);
280 CFReleaseNull(gencount);
281 CFReleaseNull(prunedCircle);
282
283 complete(pbblob, NULL);
284 }
285
286 - (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete
287 {
288 SOSGenCountRef gencount = NULL;
289 SecKeyRef pubKey = NULL;
290 CFDataRef signature = NULL;
291 CFErrorRef error = NULL;
292 bool setInitialSyncTimeoutToV0 = false;
293
294 if (!SOSPiggyBackBlobCreateFromData(&gencount, &pubKey, &signature, (__bridge CFDataRef)blob, kPiggyV1, &setInitialSyncTimeoutToV0, &error)) {
295 complete(true, (__bridge NSError *)error);
296 CFReleaseNull(error);
297 return;
298 }
299
300 (void)SOSCircleAcceptPeerFromHSA2(_circle,
301 _accountPrivateKey,
302 gencount,
303 pubKey,
304 signature,
305 _fullPeerInfo,
306 &error);
307
308 CFReleaseNull(gencount);
309 CFReleaseNull(pubKey);
310 CFReleaseNull(signature);
311
312 complete(true, (__bridge NSError *)error);
313
314 CFReleaseNull(error);
315
316 }
317
318 - (void)getWatchdogParameters:(void (^)(NSDictionary*, NSError*))complete
319 {
320 // intentionally left blank
321 // these are used by the security/2 tool and are only declared here to make the compiler happy about conforming the protocol we shoved the methods into
322 }
323
324
325 - (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError*))complete
326 {
327 // intentionally left blank
328 // these are used by the security/2 tool and are only declared here to make the compiler happy about conforming the protocol we shoved the methods into
329 }
330
331 - (void)ghostBust:(SOSAccountGhostBustingOptions)options complete:(void (^)(bool, NSError *))complete {
332 complete(false, nil);
333 }
334
335 - (void)ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete{
336 complete(false, nil);
337 }
338
339 - (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete {
340 complete(false, nil);
341 }
342
343 - (void) ghostBustInfo: (void(^)(NSData *json, NSError *error))complete {
344 complete(nil, nil);
345 }
346
347 - (void)iCloudIdentityStatus_internal: (void(^)(NSDictionary *tableSpid, NSError *error))complete {
348 complete(nil, nil);
349 }
350
351 - (void) iCloudIdentityStatus: (void(^)(NSData *json, NSError *error))complete {
352 complete(nil, nil);
353 }
354
355 - (void)rpcTriggerBackup:(NSArray<NSString *> *)backupPeers complete:(void (^)(NSError *))complete {
356 complete(nil);
357 }
358
359 - (void)rpcTriggerRingUpdate:(void (^)(NSError *))complete {
360 complete(nil);
361 }
362
363
364 @end