]> git.saurik.com Git - apple/security.git/blob - keychain/ot/OTResetCKKSZonesLackingTLKsOperation.m
Security-59306.101.1.tar.gz
[apple/security.git] / keychain / ot / OTResetCKKSZonesLackingTLKsOperation.m
1 #if OCTAGON
2
3 #import "utilities/debugging.h"
4
5 #import <CloudKit/CloudKit_Private.h>
6
7 #import "keychain/ot/OTResetCKKSZonesLackingTLKsOperation.h"
8 #import "keychain/ot/OTCuttlefishAccountStateHolder.h"
9 #import "keychain/ot/OTFetchCKKSKeysOperation.h"
10
11 #import "keychain/ckks/CloudKitCategories.h"
12 #import "keychain/ckks/CKKSCurrentKeyPointer.h"
13 #import "keychain/ckks/CKKSKeychainView.h"
14
15 #import "keychain/ot/ObjCImprovements.h"
16
17 @interface OTResetCKKSZonesLackingTLKsOperation ()
18 @property OTOperationDependencies* deps;
19
20 @property NSOperation* finishedOp;
21 @end
22
23 @implementation OTResetCKKSZonesLackingTLKsOperation
24 @synthesize nextState = _nextState;
25 @synthesize intendedState = _intendedState;
26
27 - (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies
28 intendedState:(OctagonState*)intendedState
29 errorState:(OctagonState*)errorState
30 {
31 if((self = [super init])) {
32 _deps = dependencies;
33
34 _intendedState = intendedState;
35 _nextState = errorState;
36 }
37 return self;
38 }
39
40 - (void)groupStart
41 {
42 secnotice("octagon", "Checking if any CKKS zones need resetting");
43
44 WEAKIFY(self);
45
46 self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{
47 STRONGIFY(self);
48 secnotice("octagon", "Finishing resetting CKKS missing TLKs operation with %@", self.error ?: @"no error");
49 }];
50 [self dependOnBeforeGroupFinished:self.finishedOp];
51
52 OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.deps];
53 [self runBeforeGroupFinished:fetchKeysOp];
54
55 CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"continue-ckks-resets"
56 withBlock:^{
57 STRONGIFY(self);
58 [self proceedWithKeys:fetchKeysOp.viewKeySets
59 incompleteKeySets:fetchKeysOp.incompleteKeySets
60 pendingTLKShares:fetchKeysOp.tlkShares];
61 }];
62
63 [proceedWithKeys addDependency:fetchKeysOp];
64 [self runBeforeGroupFinished:proceedWithKeys];
65 }
66
67 - (void)proceedWithKeys:(NSArray<CKKSKeychainBackedKeySet*>*)viewKeySets
68 incompleteKeySets:(NSArray<CKKSCurrentKeySet*>*)incompleteKeySets
69 pendingTLKShares:(NSArray<CKKSTLKShare*>*)pendingTLKShares
70 {
71 // Now that CKKS has returned, what are we even doing
72 NSMutableSet<CKKSKeychainView*>* viewsToReset = [NSMutableSet set];
73
74 for(CKKSCurrentKeySet* incompleteKeySet in incompleteKeySets) {
75 if(incompleteKeySet.error == nil) {
76 CKKSViewManager* viewManager = self.deps.viewManager;
77 CKKSKeychainView* viewMatchingSet = [viewManager findView:incompleteKeySet.viewName];
78
79 if(!viewMatchingSet) {
80 secnotice("octagon-ckks", "No view matching viewset %@?", incompleteKeySet);
81 continue;
82 }
83
84 if(incompleteKeySet.currentTLKPointer != nil &&
85 incompleteKeySet.tlk == nil) {
86
87 BOOL otherDevicesAlive = [viewMatchingSet otherDevicesReportHavingTLKs:incompleteKeySet];
88 if(otherDevicesAlive) {
89 secnotice("octagon-ckks", "Recently active devices claim to have TLK from key set %@; not scheduling for reset", incompleteKeySet);
90 } else {
91 secnotice("octagon-ckks", "Key set %@ has no TLK; scheduling for reset", incompleteKeySet);
92 [viewsToReset addObject:viewMatchingSet];
93 }
94 }
95 } else {
96 secnotice("octagon-ckks", "Error loading key set %@; not attempting reset", incompleteKeySet);
97 }
98 }
99
100 if(viewsToReset.count == 0) {
101 // Nothing to do; return to ready
102 secnotice("octagon-ckks", "No CKKS views need resetting");
103 self.nextState = self.intendedState;
104 [self runBeforeGroupFinished:self.finishedOp];
105 return;
106 }
107
108 [self resetViews:viewsToReset];
109 }
110
111 - (void)resetViews:(NSSet<CKKSKeychainView*>*)viewsToReset {
112 CKOperationGroup* opGroup = [CKOperationGroup CKKSGroupWithName:@"octagon-reset-missing-tlks"];
113 for (CKKSKeychainView* view in viewsToReset) {
114 secnotice("octagon-ckks", "Resetting CKKS %@", view);
115 CKKSResultOperation* op = [view resetCloudKitZone:opGroup];
116
117 // Use an intermediary operation, just to ensure we have a timeout
118 CKKSResultOperation* waitOp = [CKKSResultOperation named:[NSString stringWithFormat:@"wait-for-%@", view.zoneName]
119 withBlock:^{}];
120 [waitOp timeout:120*NSEC_PER_SEC];
121 [waitOp addDependency:op];
122 [self.operationQueue addOperation:waitOp];
123
124 [self.finishedOp addDependency:waitOp];
125 }
126
127 self.nextState = self.intendedState;
128 [self.operationQueue addOperation:self.finishedOp];
129 }
130
131 @end
132
133 #endif // OCTAGON