OTSOSUpdatePreapprovalsOperation.m [plain text]
#if OCTAGON
#import <TargetConditionals.h>
#import <Security/SecKey.h>
#import <Security/SecKeyPriv.h>
#import <CloudKit/CloudKit_Private.h>
#import "keychain/ot/ObjCImprovements.h"
#import "keychain/ot/OTSOSUpdatePreapprovalsOperation.h"
#import "keychain/ot/OTOperationDependencies.h"
#import "keychain/ot/OTCuttlefishAccountStateHolder.h"
#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h"
#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h"
#import "keychain/ckks/CKKSAnalytics.h"
#import "keychain/ckks/CloudKitCategories.h"
@interface OTSOSUpdatePreapprovalsOperation ()
@property OTOperationDependencies* deps;
// Since we're making callback based async calls, use this operation trick to hold off the ending of this operation
@property NSOperation* finishedOp;
@end
@implementation OTSOSUpdatePreapprovalsOperation
@synthesize nextState = _nextState;
@synthesize intendedState = _intendedState;
- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies
intendedState:(OctagonState*)intendedState
sosNotPresentState:(OctagonState*)sosNotPresentState
errorState:(OctagonState*)errorState
{
if((self = [super init])) {
_deps = dependencies;
_intendedState = intendedState;
_sosNotPresentState = sosNotPresentState;
_nextState = errorState;
}
return self;
}
- (void)groupStart
{
WEAKIFY(self);
if(!self.deps.sosAdapter.sosEnabled) {
secnotice("octagon-sos", "SOS not enabled on this platform?");
return;
}
self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{
STRONGIFY(self);
if(self.error) {
if ([self.error retryableCuttlefishError]) {
NSTimeInterval delay = [self.error overallCuttlefishRetry];
secnotice("octagon-sos", "SOS update preapproval error is not fatal: requesting retry in [self.deps.flagHandler handlePendingFlag:[[OctagonPendingFlag alloc] initWithFlag:OctagonFlagAttemptSOSUpdatePreapprovals
delayInSeconds:delay]];
} else {
secnotice("octagon-sos", "SOS update preapproval error is: }
}
}];
[self dependOnBeforeGroupFinished:self.finishedOp];
NSError* sosPreapprovalError = nil;
NSArray<NSData*>* publicSigningSPKIs = [OTSOSAdapterHelpers peerPublicSigningKeySPKIsForCircle:self.deps.sosAdapter error:&sosPreapprovalError];
if(!publicSigningSPKIs || sosPreapprovalError) {
secerror("octagon-sos: Can't fetch trusted peers; stopping preapproved key update: self.error = sosPreapprovalError;
self.nextState = self.sosNotPresentState;
[self runBeforeGroupFinished:self.finishedOp];
return;
}
secnotice("octagon-sos", "Updating SOS preapproved keys to
[self.deps.cuttlefishXPCWrapper setPreapprovedKeysWithContainer:self.deps.containerName
context:self.deps.contextID
preapprovedKeys:publicSigningSPKIs
reply:^(TrustedPeersHelperPeerState* _Nullable peerState, NSError* error) {
STRONGIFY(self);
if(error) {
secerror("octagon-sos: unable to update preapproved keys: self.error = error;
} else {
secnotice("octagon-sos", "Updated SOS preapproved keys");
if (peerState.memberChanges) {
secnotice("octagon", "Member list changed");
[self.deps.octagonAdapter sendTrustedPeerSetChangedUpdate];
}
self.nextState = self.intendedState;
}
[self runBeforeGroupFinished:self.finishedOp];
}];
}
@end
#endif // OCTAGON