]> git.saurik.com Git - apple/security.git/blob - keychain/ot/OTUploadNewCKKSTLKsOperation.m
Security-59306.101.1.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 CKKSViewManager* viewManager = self.deps.viewManager;
55 for(CKKSKeychainView* view in viewManager.currentViews) {
56 if([view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateWaitForTLKUpload] ||
57 [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateWaitForTLKCreation]) {
58 secnotice("octagon-ckks", "CKKS view %@ needs TLK uploads!", view);
59 [viewsToUpload addObject: view];
60 }
61 }
62
63 if(viewsToUpload.count == 0) {
64 // Nothing to do; return to ready
65 secnotice("octagon-ckks", "No CKKS views need uploads");
66 self.nextState = self.intendedState;
67 return;
68 }
69
70 self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{
71 STRONGIFY(self);
72 secnotice("octagon", "Finishing an update TLKs operation with %@", self.error ?: @"no error");
73 }];
74 [self dependOnBeforeGroupFinished:self.finishedOp];
75
76 OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithViews:viewsToUpload];
77 [self runBeforeGroupFinished:fetchKeysOp];
78
79 CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"upload-tlks-with-keys"
80 withBlock:^{
81 STRONGIFY(self);
82 [self proceedWithKeys:fetchKeysOp.viewKeySets
83 pendingTLKShares:fetchKeysOp.tlkShares
84 viewsToUpload:viewsToUpload];
85 }];
86
87 [proceedWithKeys addDependency:fetchKeysOp];
88 [self runBeforeGroupFinished:proceedWithKeys];
89 }
90
91 - (void)proceedWithKeys:(NSArray<CKKSKeychainBackedKeySet*>*)viewKeySets
92 pendingTLKShares:(NSArray<CKKSTLKShare*>*)pendingTLKShares
93 viewsToUpload:(NSSet<CKKSKeychainView*>*)viewsToUpload
94 {
95 WEAKIFY(self);
96
97 secnotice("octagon-ckks", "Beginning tlk upload with keys: %@", viewKeySets);
98 [self.deps.cuttlefishXPCWrapper updateTLKsWithContainer:self.deps.containerName
99 context:self.deps.contextID
100 ckksKeys:viewKeySets
101 tlkShares:pendingTLKShares
102 reply:^(NSArray<CKRecord*>* _Nullable keyHierarchyRecords, NSError * _Nullable error) {
103 STRONGIFY(self);
104
105 if(error) {
106 if ([error isCuttlefishError:CuttlefishErrorKeyHierarchyAlreadyExists]) {
107 secnotice("octagon-ckks", "A CKKS key hierarchy is out of date; moving to '%@'", self.ckksConflictState);
108 self.nextState = self.ckksConflictState;
109 } else {
110 secerror("octagon: Error calling tlk upload: %@", error);
111 self.error = error;
112 }
113 } else {
114 // Tell CKKS about our shiny new records!
115 for(CKKSKeychainView* view in viewsToUpload) {
116 secnotice("octagon-ckks", "Providing records to %@", view);
117 [view receiveTLKUploadRecords: keyHierarchyRecords];
118 }
119
120 self.nextState = self.intendedState;
121 }
122 [self runBeforeGroupFinished:self.finishedOp];
123 }];
124 }
125
126 @end
127
128 #endif // OCTAGON