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