]> git.saurik.com Git - apple/security.git/blob - keychain/ot/OTUploadNewCKKSTLKsOperation.m
Security-59306.41.2.tar.gz
[apple/security.git] / keychain / ot / OTUploadNewCKKSTLKsOperation.m
1
2 #if OCTAGON
3
4 #import "utilities/debugging.h"
5
6 #import <CloudKit/CloudKit_Private.h>
7
8 #import "keychain/ot/OTUploadNewCKKSTLKsOperation.h"
9 #import "keychain/ot/OTCuttlefishAccountStateHolder.h"
10 #import "keychain/ot/OTFetchCKKSKeysOperation.h"
11 #import "keychain/ckks/CKKSCurrentKeyPointer.h"
12 #import "keychain/ckks/CKKSKeychainView.h"
13 #import "keychain/ckks/CKKSNearFutureScheduler.h"
14 #import "keychain/ckks/CloudKitCategories.h"
15
16 #import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h"
17 #import "keychain/ot/ObjCImprovements.h"
18
19 @interface OTUploadNewCKKSTLKsOperation ()
20 @property OTOperationDependencies* deps;
21
22 @property OctagonState* ckksConflictState;
23
24 @property NSOperation* finishedOp;
25 @end
26
27 @implementation OTUploadNewCKKSTLKsOperation
28 @synthesize intendedState = _intendedState;
29
30 - (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies
31 intendedState:(OctagonState*)intendedState
32 ckksConflictState:(OctagonState*)ckksConflictState
33 errorState:(OctagonState*)errorState
34 {
35 if((self = [super init])) {
36 _deps = dependencies;
37
38 _intendedState = intendedState;
39 _ckksConflictState = ckksConflictState;
40 _nextState = errorState;
41 }
42 return self;
43 }
44
45 - (void)groupStart
46 {
47 secnotice("octagon", "Beginning to upload any pending CKKS tlks operation");
48
49 WEAKIFY(self);
50
51 NSMutableSet<CKKSKeychainView*>* viewsToUpload = [NSMutableSet set];
52
53 // One (or more) of our sub-CKKSes believes it needs to upload new TLKs.
54 for(CKKSKeychainView* view in [self.deps.viewManager currentViews]) {
55 if([view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateWaitForTLKUpload] ||
56 [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateWaitForTLKCreation]) {
57 secnotice("octagon-ckks", "CKKS view %@ needs TLK uploads!", view);
58 [viewsToUpload addObject: view];
59 }
60 }
61
62 if(viewsToUpload.count == 0) {
63 // Nothing to do; return to ready
64 secnotice("octagon-ckks", "No CKKS views need uploads");
65 self.nextState = self.intendedState;
66 return;
67 }
68
69 self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{
70 STRONGIFY(self);
71 secnotice("octagon", "Finishing an update TLKs operation with %@", self.error ?: @"no error");
72 }];
73 [self dependOnBeforeGroupFinished:self.finishedOp];
74
75 OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithViews:viewsToUpload];
76 [self runBeforeGroupFinished:fetchKeysOp];
77
78 CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"upload-tlks-with-keys"
79 withBlock:^{
80 STRONGIFY(self);
81 [self proceedWithKeys:fetchKeysOp.viewKeySets
82 pendingTLKShares:fetchKeysOp.tlkShares
83 viewsToUpload:viewsToUpload];
84 }];
85
86 [proceedWithKeys addDependency:fetchKeysOp];
87 [self runBeforeGroupFinished:proceedWithKeys];
88 }
89
90 - (void)proceedWithKeys:(NSArray<CKKSKeychainBackedKeySet*>*)viewKeySets
91 pendingTLKShares:(NSArray<CKKSTLKShare*>*)pendingTLKShares
92 viewsToUpload:(NSSet<CKKSKeychainView*>*)viewsToUpload
93 {
94 WEAKIFY(self);
95
96 secnotice("octagon-ckks", "Beginning tlk upload with keys: %@", viewKeySets);
97 [self.deps.cuttlefishXPCWrapper updateTLKsWithContainer:self.deps.containerName
98 context:self.deps.contextID
99 ckksKeys:viewKeySets
100 tlkShares:pendingTLKShares
101 reply:^(NSArray<CKRecord*>* _Nullable keyHierarchyRecords, NSError * _Nullable error) {
102 STRONGIFY(self);
103
104 if(error) {
105 if ([error isCuttlefishError:CuttlefishErrorKeyHierarchyAlreadyExists]) {
106 secnotice("octagon-ckks", "A CKKS key hierarchy is out of date; moving to '%@'", self.ckksConflictState);
107 self.nextState = self.ckksConflictState;
108 } else {
109 secerror("octagon: Error calling tlk upload: %@", error);
110 self.error = error;
111 }
112 } else {
113 // Tell CKKS about our shiny new records!
114 for(CKKSKeychainView* view in viewsToUpload) {
115 secnotice("octagon-ckks", "Providing records to %@", view);
116 [view receiveTLKUploadRecords: keyHierarchyRecords];
117 }
118
119 self.nextState = self.intendedState;
120 }
121 [self runBeforeGroupFinished:self.finishedOp];
122 }];
123 }
124
125 @end
126
127 #endif // OCTAGON