]> git.saurik.com Git - apple/security.git/blob - keychain/ot/CuttlefishXPCWrapper.m
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / ot / CuttlefishXPCWrapper.m
1 /*
2 * Copyright (c) 2019 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_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 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #import "keychain/ot/CuttlefishXPCWrapper.h"
25
26 @implementation CuttlefishXPCWrapper
27 - (instancetype) initWithCuttlefishXPCConnection: (id<NSXPCProxyCreating>)cuttlefishXPCConnection
28 {
29 if ((self = [super init])) {
30 _cuttlefishXPCConnection = cuttlefishXPCConnection;
31 }
32 return self;
33 }
34
35 + (bool)retryable:(NSError *_Nonnull)error
36 {
37 return error.domain == NSCocoaErrorDomain && error.code == NSXPCConnectionInterrupted;
38 }
39
40 enum {NUM_RETRIES = 5};
41
42 - (void)pingWithReply:(void (^)(void))reply
43 {
44 __block int i = 0;
45 __block bool retry;
46 do {
47 retry = false;
48 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
49 if (i < NUM_RETRIES && [self.class retryable:error]) {
50 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
51 retry = true;
52 } else {
53 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
54 }
55 ++i;
56 }] pingWithReply:reply];
57 } while (retry);
58 }
59
60 - (void)dumpWithContainer:(NSString *)container
61 context:(NSString *)context
62 reply:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply
63 {
64 __block int i = 0;
65 __block bool retry;
66 do {
67 retry = false;
68 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
69 if (i < NUM_RETRIES && [self.class retryable:error]) {
70 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
71 retry = true;
72 } else {
73 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
74 reply(nil, error);
75 }
76 ++i;
77 }] dumpWithContainer:container context:context reply:reply];
78 } while (retry);
79 }
80
81 - (void)departByDistrustingSelfWithContainer:(NSString *)container
82 context:(NSString *)context
83 reply:(void (^)(NSError * _Nullable))reply
84 {
85 __block int i = 0;
86 __block bool retry;
87 do {
88 retry = false;
89 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
90 if (i < NUM_RETRIES && [self.class retryable:error]) {
91 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
92 retry = true;
93 } else {
94 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
95 reply(error);
96 }
97 ++i;
98 }] departByDistrustingSelfWithContainer:container context:context reply:reply];
99 } while (retry);
100 }
101
102 - (void)distrustPeerIDsWithContainer:(NSString *)container
103 context:(NSString *)context
104 peerIDs:(NSSet<NSString*>*)peerIDs
105 reply:(void (^)(NSError * _Nullable))reply
106 {
107 __block int i = 0;
108 __block bool retry;
109 do {
110 retry = false;
111 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
112 if (i < NUM_RETRIES && [self.class retryable:error]) {
113 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
114 retry = true;
115 } else {
116 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
117 reply(error);
118 }
119 ++i;
120 }] distrustPeerIDsWithContainer:container context:context peerIDs:peerIDs reply:reply];
121 } while (retry);
122 }
123
124 - (void)trustStatusWithContainer:(NSString *)container
125 context:(NSString *)context
126 reply:(void (^)(TrustedPeersHelperEgoPeerStatus *status,
127 NSError* _Nullable error))reply
128 {
129 __block int i = 0;
130 __block bool retry;
131 do {
132 retry = false;
133 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
134 if (i < NUM_RETRIES && [self.class retryable:error]) {
135 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
136 retry = true;
137 } else {
138 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
139 reply(nil, error);
140 }
141 ++i;
142 }] trustStatusWithContainer:container context:context reply:reply];
143 } while (retry);
144 }
145
146 - (void)resetWithContainer:(NSString *)container
147 context:(NSString *)context
148 resetReason:(CuttlefishResetReason)reason
149 reply:(void (^)(NSError * _Nullable error))reply
150 {
151 __block int i = 0;
152 __block bool retry;
153 do {
154 retry = false;
155 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
156 if (i < NUM_RETRIES && [self.class retryable:error]) {
157 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
158 retry = true;
159 } else {
160 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
161 reply(error);
162 }
163 ++i;
164 }] resetWithContainer:container context:context resetReason:reason reply:reply];
165 } while (retry);
166 }
167
168 - (void)localResetWithContainer:(NSString *)container
169 context:(NSString *)context
170 reply:(void (^)(NSError * _Nullable error))reply
171 {
172 __block int i = 0;
173 __block bool retry;
174 do {
175 retry = false;
176 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
177 if (i < NUM_RETRIES && [self.class retryable:error]) {
178 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
179 retry = true;
180 } else {
181 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
182 reply(error);
183 }
184 ++i;
185 }] localResetWithContainer:container context:context reply:reply];
186 } while (retry);
187 }
188
189 - (void)setAllowedMachineIDsWithContainer:(NSString *)container
190 context:(NSString *)context
191 allowedMachineIDs:(NSSet<NSString*> *)allowedMachineIDs
192 honorIDMSListChanges:(BOOL)accountIsDemo
193 reply:(void (^)(BOOL listDifferences, NSError * _Nullable error))reply
194 {
195 __block int i = 0;
196 __block bool retry;
197 do {
198 retry = false;
199 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
200 if (i < NUM_RETRIES && [self.class retryable:error]) {
201 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
202 retry = true;
203 } else {
204 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
205 reply(NO, error);
206 }
207 ++i;
208 }] setAllowedMachineIDsWithContainer:container context:context allowedMachineIDs:allowedMachineIDs honorIDMSListChanges:accountIsDemo reply:reply];
209 } while (retry);
210 }
211
212 - (void)addAllowedMachineIDsWithContainer:(NSString *)container
213 context:(NSString *)context
214 machineIDs:(NSArray<NSString*> *)machineIDs
215 reply:(void (^)(NSError * _Nullable error))reply
216 {
217 __block int i = 0;
218 __block bool retry;
219 do {
220 retry = false;
221 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
222 if (i < NUM_RETRIES && [self.class retryable:error]) {
223 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
224 retry = true;
225 } else {
226 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
227 reply(error);
228 }
229 ++i;
230 }] addAllowedMachineIDsWithContainer:container
231 context:context
232 machineIDs:machineIDs
233 reply:reply];
234 } while (retry);
235 }
236
237 - (void)removeAllowedMachineIDsWithContainer:(NSString *)container
238 context:(NSString *)context
239 machineIDs:(NSArray<NSString*> *)machineIDs
240 reply:(void (^)(NSError * _Nullable error))reply
241 {
242 __block int i = 0;
243 __block bool retry;
244 do {
245 retry = false;
246 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
247 if (i < NUM_RETRIES && [self.class retryable:error]) {
248 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
249 retry = true;
250 } else {
251 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
252 reply(error);
253 }
254 ++i;
255 }] removeAllowedMachineIDsWithContainer:container context:context machineIDs:machineIDs reply:reply];
256 } while (retry);
257 }
258
259
260 - (void)fetchAllowedMachineIDsWithContainer:(nonnull NSString *)container
261 context:(nonnull NSString *)context
262 reply:(nonnull void (^)(NSSet<NSString *> * _Nullable, NSError * _Nullable))reply {
263 __block int i = 0;
264 __block bool retry;
265 do {
266 retry = false;
267 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
268 if (i < NUM_RETRIES && [self.class retryable:error]) {
269 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
270 retry = true;
271 } else {
272 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
273 reply(nil, error);
274 }
275 ++i;
276 }] fetchAllowedMachineIDsWithContainer:container context:context reply:reply];
277 } while (retry);
278 }
279
280
281 - (void)fetchEgoEpochWithContainer:(NSString *)container
282 context:(NSString *)context
283 reply:(void (^)(unsigned long long epoch,
284 NSError * _Nullable error))reply
285 {
286 __block int i = 0;
287 __block bool retry;
288 do {
289 retry = false;
290 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
291 if (i < NUM_RETRIES && [self.class retryable:error]) {
292 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
293 retry = true;
294 } else {
295 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
296 reply(0, error);
297 }
298 ++i;
299 }] fetchEgoEpochWithContainer:container context:context reply:reply];
300 } while (retry);
301 }
302
303 - (void)prepareWithContainer:(NSString *)container
304 context:(NSString *)context
305 epoch:(unsigned long long)epoch
306 machineID:(NSString *)machineID
307 bottleSalt:(NSString *)bottleSalt
308 bottleID:(NSString *)bottleID
309 modelID:(NSString *)modelID
310 deviceName:(nullable NSString*)deviceName
311 serialNumber:(NSString *)serialNumber
312 osVersion:(NSString *)osVersion
313 policyVersion:(nullable TPPolicyVersion *)policyVersion
314 policySecrets:(nullable NSDictionary<NSString*,NSData*> *)policySecrets
315 syncUserControllableViews:(TPPBPeerStableInfo_UserControllableViewStatus)syncUserControllableViews
316 signingPrivKeyPersistentRef:(nullable NSData *)spkPr
317 encPrivKeyPersistentRef:(nullable NSData*)epkPr
318 reply:(void (^)(NSString * _Nullable peerID,
319 NSData * _Nullable permanentInfo,
320 NSData * _Nullable permanentInfoSig,
321 NSData * _Nullable stableInfo,
322 NSData * _Nullable stableInfoSig,
323 TPSyncingPolicy* _Nullable syncingPolicy,
324 NSError * _Nullable error))reply
325 {
326 __block int i = 0;
327 __block bool retry;
328 do {
329 retry = false;
330 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
331 if (i < NUM_RETRIES && [self.class retryable:error]) {
332 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
333 retry = true;
334 } else {
335 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
336 reply(nil, nil, nil, nil, nil, nil, error);
337 }
338 ++i;
339 }] prepareWithContainer:container
340 context:context
341 epoch:epoch
342 machineID:machineID
343 bottleSalt:bottleSalt
344 bottleID:bottleID
345 modelID:modelID
346 deviceName:deviceName
347 serialNumber:serialNumber
348 osVersion:osVersion
349 policyVersion:policyVersion
350 policySecrets:policySecrets
351 syncUserControllableViews:syncUserControllableViews
352 signingPrivKeyPersistentRef:spkPr
353 encPrivKeyPersistentRef:epkPr
354 reply:reply];
355 } while (retry);
356 }
357
358 - (void)establishWithContainer:(NSString *)container
359 context:(NSString *)context
360 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
361 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
362 preapprovedKeys:(nullable NSArray<NSData*> *)preapprovedKeys
363 reply:(void (^)(NSString * _Nullable peerID,
364 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
365 TPSyncingPolicy* _Nullable syncingPolicy,
366 NSError * _Nullable error))reply
367 {
368 __block int i = 0;
369 __block bool retry;
370 do {
371 retry = false;
372 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
373 if (i < NUM_RETRIES && [self.class retryable:error]) {
374 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
375 retry = true;
376 } else {
377 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
378 reply(nil, nil, nil, error);
379 }
380 ++i;
381 }] establishWithContainer:container context:context ckksKeys:viewKeySets tlkShares:tlkShares preapprovedKeys:preapprovedKeys reply:reply];
382 } while (retry);
383 }
384
385 - (void)vouchWithContainer:(NSString *)container
386 context:(NSString *)context
387 peerID:(NSString *)peerID
388 permanentInfo:(NSData *)permanentInfo
389 permanentInfoSig:(NSData *)permanentInfoSig
390 stableInfo:(NSData *)stableInfo
391 stableInfoSig:(NSData *)stableInfoSig
392 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
393 reply:(void (^)(NSData * _Nullable voucher,
394 NSData * _Nullable voucherSig,
395 NSError * _Nullable error))reply
396 {
397 __block int i = 0;
398 __block bool retry;
399 do {
400 retry = false;
401 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
402 if (i < NUM_RETRIES && [self.class retryable:error]) {
403 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
404 retry = true;
405 } else {
406 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
407 reply(nil, nil, error);
408 }
409 ++i;
410 }] vouchWithContainer:container context:context peerID:peerID permanentInfo:permanentInfo permanentInfoSig:permanentInfoSig stableInfo:stableInfo stableInfoSig:stableInfoSig ckksKeys:viewKeySets reply:reply];
411 } while (retry);
412 }
413
414
415 - (void)preflightVouchWithBottleWithContainer:(nonnull NSString *)container
416 context:(nonnull NSString *)context
417 bottleID:(nonnull NSString *)bottleID
418 reply:(nonnull void (^)(NSString * _Nullable,
419 TPSyncingPolicy* _Nullable peerSyncingPolicy,
420 BOOL refetchWasNeeded,
421 NSError * _Nullable))reply {
422 __block int i = 0;
423 __block bool retry;
424 do {
425 retry = false;
426 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
427 if (i < NUM_RETRIES && [self.class retryable:error]) {
428 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
429 retry = true;
430 } else {
431 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
432 reply(nil, nil, false, error);
433 }
434 ++i;
435 }] preflightVouchWithBottleWithContainer:container
436 context:context
437 bottleID:bottleID
438 reply:reply];
439 } while (retry);
440 }
441
442 - (void)vouchWithBottleWithContainer:(NSString *)container
443 context:(NSString *)context
444 bottleID:(NSString*)bottleID
445 entropy:(NSData*)entropy
446 bottleSalt:(NSString*)bottleSalt
447 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
448 reply:(void (^)(NSData * _Nullable voucher,
449 NSData * _Nullable voucherSig,
450 int64_t uniqueTLKsRecovered,
451 int64_t totalTLKSharesRecovered,
452 NSError * _Nullable error))reply
453 {
454 __block int i = 0;
455 __block bool retry;
456 do {
457 retry = false;
458 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
459 if (i < NUM_RETRIES && [self.class retryable:error]) {
460 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
461 retry = true;
462 } else {
463 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
464 reply(nil, nil, 0, 0, error);
465 }
466 ++i;
467 }] vouchWithBottleWithContainer:container context:context bottleID:bottleID entropy:entropy bottleSalt:bottleSalt tlkShares:tlkShares reply:reply];
468 } while (retry);
469 }
470
471 - (void)preflightVouchWithRecoveryKeyWithContainer:(nonnull NSString *)container
472 context:(nonnull NSString *)context
473 recoveryKey:(NSString*)recoveryKey
474 salt:(NSString*)salt
475 reply:(nonnull void (^)(NSString * _Nullable,
476 TPSyncingPolicy* _Nullable peerSyncingPolicy,
477 NSError * _Nullable))reply {
478 __block int i = 0;
479 __block bool retry;
480 do {
481 retry = false;
482 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
483 if (i < NUM_RETRIES && [self.class retryable:error]) {
484 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
485 retry = true;
486 } else {
487 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
488 reply(nil, nil, error);
489 }
490 ++i;
491 }] preflightVouchWithRecoveryKeyWithContainer:container
492 context:context
493 recoveryKey:recoveryKey
494 salt:salt
495 reply:reply];
496 } while (retry);
497 }
498
499 - (void)vouchWithRecoveryKeyWithContainer:(NSString *)container
500 context:(NSString *)context
501 recoveryKey:(NSString*)recoveryKey
502 salt:(NSString*)salt
503 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
504 reply:(void (^)(NSData * _Nullable voucher,
505 NSData * _Nullable voucherSig,
506 NSError * _Nullable error))reply
507 {
508 __block int i = 0;
509 __block bool retry;
510 do {
511 retry = false;
512 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
513 if (i < NUM_RETRIES && [self.class retryable:error]) {
514 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
515 retry = true;
516 } else {
517 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
518 reply(nil, nil, error);
519 }
520 ++i;
521 }] vouchWithRecoveryKeyWithContainer:container context:context recoveryKey:recoveryKey salt:salt tlkShares:tlkShares reply:reply];
522 } while (retry);
523 }
524
525 - (void)joinWithContainer:(NSString *)container
526 context:(NSString *)context
527 voucherData:(NSData *)voucherData
528 voucherSig:(NSData *)voucherSig
529 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
530 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
531 preapprovedKeys:(nullable NSArray<NSData*> *)preapprovedKeys
532 reply:(void (^)(NSString * _Nullable peerID,
533 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
534 TPSyncingPolicy* _Nullable syncingPolicy,
535 NSError * _Nullable error))reply
536 {
537 __block int i = 0;
538 __block bool retry;
539 do {
540 retry = false;
541 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
542 if (i < NUM_RETRIES && [self.class retryable:error]) {
543 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
544 retry = true;
545 } else {
546 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
547 reply(nil, nil, nil, error);
548 }
549 ++i;
550 }] joinWithContainer:container context:context voucherData:voucherData voucherSig:voucherSig ckksKeys:viewKeySets tlkShares:tlkShares preapprovedKeys:preapprovedKeys reply:reply];
551 } while (retry);
552 }
553
554 - (void)preflightPreapprovedJoinWithContainer:(NSString *)container
555 context:(NSString *)context
556 preapprovedKeys:(nullable NSArray<NSData*> *)preapprovedKeys
557 reply:(void (^)(BOOL launchOkay,
558 NSError * _Nullable error))reply
559 {
560 __block int i = 0;
561 __block bool retry;
562 do {
563 retry = false;
564 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
565 if (i < NUM_RETRIES && [self.class retryable:error]) {
566 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
567 retry = true;
568 } else {
569 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
570 reply(NO, error);
571 }
572 ++i;
573 }] preflightPreapprovedJoinWithContainer:container context:context preapprovedKeys:preapprovedKeys reply:reply];
574 } while (retry);
575 }
576
577 - (void)attemptPreapprovedJoinWithContainer:(NSString *)container
578 context:(NSString *)context
579 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
580 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
581 preapprovedKeys:(nullable NSArray<NSData*> *)preapprovedKeys
582 reply:(void (^)(NSString * _Nullable peerID,
583 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
584 TPSyncingPolicy* _Nullable syncingPolicy,
585 NSError * _Nullable error))reply
586 {
587 __block int i = 0;
588 __block bool retry;
589 do {
590 retry = false;
591 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
592 if (i < NUM_RETRIES && [self.class retryable:error]) {
593 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
594 retry = true;
595 } else {
596 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
597 reply(nil, nil, nil, error);
598 }
599 ++i;
600 }] attemptPreapprovedJoinWithContainer:container
601 context:context
602 ckksKeys:ckksKeys
603 tlkShares:tlkShares
604 preapprovedKeys:preapprovedKeys
605 reply:reply];
606 } while (retry);
607 }
608
609 - (void)updateWithContainer:(NSString *)container
610 context:(NSString *)context
611 deviceName:(nullable NSString *)deviceName
612 serialNumber:(nullable NSString *)serialNumber
613 osVersion:(nullable NSString *)osVersion
614 policyVersion:(nullable NSNumber *)policyVersion
615 policySecrets:(nullable NSDictionary<NSString*,NSData*> *)policySecrets
616 syncUserControllableViews:(nullable NSNumber *)syncUserControllableViews
617 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable peerState, TPSyncingPolicy* _Nullable policy, NSError * _Nullable error))reply
618 {
619 __block int i = 0;
620 __block bool retry;
621 do {
622 retry = false;
623 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
624 if (i < NUM_RETRIES && [self.class retryable:error]) {
625 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
626 retry = true;
627 } else {
628 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
629 reply(nil, nil, error);
630 }
631 ++i;
632 }] updateWithContainer:container
633 context:context
634 deviceName:deviceName
635 serialNumber:serialNumber
636 osVersion:osVersion
637 policyVersion:policyVersion
638 policySecrets:policySecrets
639 syncUserControllableViews:syncUserControllableViews
640 reply:reply];
641 } while (retry);
642 }
643
644 - (void)setPreapprovedKeysWithContainer:(NSString *)container
645 context:(NSString *)context
646 preapprovedKeys:(NSArray<NSData*> *)preapprovedKeys
647 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable peerState, NSError * _Nullable error))reply
648 {
649 __block int i = 0;
650 __block bool retry;
651 do {
652 retry = false;
653 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
654 if (i < NUM_RETRIES && [self.class retryable:error]) {
655 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
656 retry = true;
657 } else {
658 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
659 reply(nil, error);
660 }
661 ++i;
662 }] setPreapprovedKeysWithContainer:container context:context preapprovedKeys:preapprovedKeys reply:reply];
663 } while (retry);
664 }
665
666 - (void)updateTLKsWithContainer:(NSString *)container
667 context:(NSString *)context
668 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
669 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
670 reply:(void (^)(NSArray<CKRecord*>* _Nullable keyHierarchyRecords, NSError * _Nullable error))reply
671 {
672 __block int i = 0;
673 __block bool retry;
674 do {
675 retry = false;
676 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
677 if (i < NUM_RETRIES && [self.class retryable:error]) {
678 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
679 retry = true;
680 } else {
681 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
682 reply(nil, error);
683 }
684 ++i;
685 }] updateTLKsWithContainer:container context:context ckksKeys:ckksKeys tlkShares:tlkShares reply:reply];
686 } while (retry);
687 }
688
689 - (void)fetchViableBottlesWithContainer:(NSString *)container
690 context:(NSString *)context
691 reply:(void (^)(NSArray<NSString*>* _Nullable sortedBottleIDs, NSArray<NSString*>* _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply
692 {
693 __block int i = 0;
694 __block bool retry;
695 do {
696 retry = false;
697 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
698 if (i < NUM_RETRIES && [self.class retryable:error]) {
699 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
700 retry = true;
701 } else {
702 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
703 reply(nil, nil, error);
704 }
705 ++i;
706 }] fetchViableBottlesWithContainer:container context:context reply:reply];
707 } while (retry);
708 }
709
710 - (void)fetchEscrowContentsWithContainer:(NSString *)container
711 context:(NSString *)context
712 reply:(void (^)(NSData* _Nullable entropy,
713 NSString* _Nullable bottleID,
714 NSData* _Nullable signingPublicKey,
715 NSError* _Nullable error))reply
716 {
717 __block int i = 0;
718 __block bool retry;
719 do {
720 retry = false;
721 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
722 if (i < NUM_RETRIES && [self.class retryable:error]) {
723 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
724 retry = true;
725 } else {
726 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
727 reply(nil, nil, nil, error);
728 }
729 ++i;
730 }] fetchEscrowContentsWithContainer:container context:context reply:reply];
731 } while (retry);
732 }
733
734 - (void)fetchPolicyDocumentsWithContainer:(NSString*)container
735 context:(NSString*)context
736 versions:(NSSet<TPPolicyVersion*>*)versions
737 reply:(void (^)(NSDictionary<TPPolicyVersion*, NSData*>* _Nullable entries,
738 NSError * _Nullable error))reply
739 {
740 __block int i = 0;
741 __block bool retry;
742 do {
743 retry = false;
744 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
745 if (i < NUM_RETRIES && [self.class retryable:error]) {
746 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
747 retry = true;
748 } else {
749 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
750 reply(nil, error);
751 }
752 ++i;
753 }] fetchPolicyDocumentsWithContainer:container context:context versions:versions reply:reply];
754 } while (retry);
755 }
756
757 - (void)fetchCurrentPolicyWithContainer:(NSString*)container
758 context:(NSString*)context
759 modelIDOverride:(NSString* _Nullable)modelIDOverride
760 reply:(void (^)(TPSyncingPolicy* _Nullable syncingPolicy,
761 TPPBPeerStableInfo_UserControllableViewStatus userControllableViewStatusOfPeers,
762 NSError * _Nullable error))reply
763 {
764 __block int i = 0;
765 __block bool retry;
766 do {
767 retry = false;
768 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
769 if (i < NUM_RETRIES && [self.class retryable:error]) {
770 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
771 retry = true;
772 } else {
773 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
774 reply(nil,
775 TPPBPeerStableInfo_UserControllableViewStatus_UNKNOWN,
776 error);
777 }
778 ++i;
779 }] fetchCurrentPolicyWithContainer:container context:context modelIDOverride:modelIDOverride reply:reply];
780 } while (retry);
781 }
782
783
784 - (void)validatePeersWithContainer:(NSString *)container
785 context:(NSString *)context
786 reply:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply
787 {
788 __block int i = 0;
789 __block bool retry;
790 do {
791 retry = false;
792 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
793 if (i < NUM_RETRIES && [self.class retryable:error]) {
794 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
795 retry = true;
796 } else {
797 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
798 reply(nil, error);
799 }
800 ++i;
801 }] validatePeersWithContainer:container context:context reply:reply];
802 } while (retry);
803 }
804
805 - (void)fetchTrustStateWithContainer:(NSString *)container
806 context:(NSString *)context
807 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable selfPeerState,
808 NSArray<TrustedPeersHelperPeer*>* _Nullable trustedPeers,
809 NSError* _Nullable error))reply
810 {
811 __block int i = 0;
812 __block bool retry;
813 do {
814 retry = false;
815 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
816 if (i < NUM_RETRIES && [self.class retryable:error]) {
817 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
818 retry = true;
819 } else {
820 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
821 reply(nil, nil, error);
822 }
823 ++i;
824 }] fetchTrustStateWithContainer:container context:context reply:reply];
825 } while (retry);
826 }
827
828 - (void)setRecoveryKeyWithContainer:(NSString *)container
829 context:(NSString *)context
830 recoveryKey:(NSString *)recoveryKey
831 salt:(NSString *)salt
832 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
833 reply:(void (^)(NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
834 NSError* _Nullable error))reply
835 {
836 __block int i = 0;
837 __block bool retry;
838 do {
839 retry = false;
840 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
841 if (i < NUM_RETRIES && [self.class retryable:error]) {
842 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
843 retry = true;
844 } else {
845 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
846 reply(nil, error);
847 }
848 ++i;
849 }] setRecoveryKeyWithContainer:container context:context recoveryKey:recoveryKey salt:salt ckksKeys:ckksKeys reply:reply];
850 } while (retry);
851 }
852
853 - (void)reportHealthWithContainer:(NSString *)container
854 context:(NSString *)context
855 stateMachineState:(NSString *)state
856 trustState:(NSString *)trustState
857 reply:(void (^)(NSError* _Nullable error))reply
858 {
859 __block int i = 0;
860 __block bool retry;
861 do {
862 retry = false;
863 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
864 if (i < NUM_RETRIES && [self.class retryable:error]) {
865 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
866 retry = true;
867 } else {
868 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
869 reply(error);
870 }
871 ++i;
872 }] reportHealthWithContainer:container context:context stateMachineState:state trustState:trustState reply:reply];
873 } while (retry);
874 }
875
876 - (void)pushHealthInquiryWithContainer:(NSString *)container
877 context:(NSString *)context
878 reply:(void (^)(NSError* _Nullable error))reply
879 {
880 __block int i = 0;
881 __block bool retry;
882 do {
883 retry = false;
884 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
885 if (i < NUM_RETRIES && [self.class retryable:error]) {
886 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
887 retry = true;
888 } else {
889 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
890 reply(error);
891 }
892 ++i;
893 }] pushHealthInquiryWithContainer:container context:context reply:reply];
894 } while (retry);
895 }
896
897 - (void)requestHealthCheckWithContainer:(NSString *)container
898 context:(NSString *)context
899 requiresEscrowCheck:(BOOL)requiresEscrowCheck
900 reply:(void (^)(BOOL postRepairCFU, BOOL postEscrowCFU, BOOL resetOctagon, BOOL leaveTrust, NSError* _Nullable))reply
901 {
902 __block int i = 0;
903 __block bool retry;
904 do {
905 retry = false;
906 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
907 if (i < NUM_RETRIES && [self.class retryable:error]) {
908 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
909 retry = true;
910 } else {
911 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
912 reply(NO, NO, NO, NO, error);
913 }
914 ++i;
915 }] requestHealthCheckWithContainer:container context:context requiresEscrowCheck:requiresEscrowCheck reply:reply];
916 } while (retry);
917 }
918
919 - (void)getSupportAppInfoWithContainer:(NSString *)container
920 context:(NSString *)context
921 reply:(void (^)(NSData * _Nullable, NSError * _Nullable))reply
922 {
923 __block int i = 0;
924 __block bool retry;
925 do {
926 retry = false;
927 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
928 if (i < NUM_RETRIES && [self.class retryable:error]) {
929 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
930 retry = true;
931 } else {
932 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
933 reply(nil, error);
934 }
935 ++i;
936 }] getSupportAppInfoWithContainer:container context:context reply:reply];
937 } while (retry);
938
939 }
940
941 - (void)fetchViableEscrowRecordsWithContainer:(nonnull NSString *)container context:(nonnull NSString *)context forceFetch:(BOOL)forceFetch reply:(nonnull void (^)(NSArray<NSData *> * _Nullable, NSError * _Nullable))reply
942 {
943 __block int i = 0;
944 __block bool retry;
945 do {
946 retry = false;
947 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
948 if (i < NUM_RETRIES && [self.class retryable:error]) {
949 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
950 retry = true;
951 } else {
952 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
953 reply(nil, error);
954 }
955 ++i;
956 }] fetchViableEscrowRecordsWithContainer:container context:context forceFetch:forceFetch reply:reply];
957 } while (retry);
958 }
959
960 - (void)removeEscrowCacheWithContainer:(nonnull NSString *)container context:(nonnull NSString *)context reply:(nonnull void (^)(NSError * _Nullable))reply {
961 __block int i = 0;
962 __block bool retry;
963 do {
964 retry = false;
965 [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *_Nonnull error) {
966 if (i < NUM_RETRIES && [self.class retryable:error]) {
967 secnotice("octagon", "retrying cuttlefish XPC, (%d, %@)", i, error);
968 retry = true;
969 } else {
970 secerror("octagon: Can't talk with TrustedPeersHelper: %@", error);
971 reply(error);
972 }
973 ++i;
974 }] removeEscrowCacheWithContainer:container context:context reply:reply];
975 } while (retry);
976 }
977
978
979
980 @end