]> git.saurik.com Git - apple/security.git/blob - keychain/ckks/tests/CKKSMockSOSPresentAdapter.m
Security-59306.101.1.tar.gz
[apple/security.git] / keychain / ckks / tests / CKKSMockSOSPresentAdapter.m
1 #import "keychain/ckks/CKKSListenerCollection.h"
2 #import "keychain/ckks/tests/CKKSMockSOSPresentAdapter.h"
3
4 @interface CKKSMockSOSPresentAdapter()
5 @property CKKSListenerCollection* peerChangeListeners;
6 @end
7
8 @implementation CKKSMockSOSPresentAdapter
9 @synthesize essential = _essential;
10 @synthesize sosEnabled = _sosEnabled;
11
12 - (instancetype)initWithSelfPeer:(CKKSSOSSelfPeer*)selfPeer
13 trustedPeers:(NSSet<CKKSSOSPeer*>*)trustedPeers
14 essential:(BOOL)essential
15 {
16 if((self = [super init])) {
17 _sosEnabled = true;
18 _essential = essential;
19
20 _circleStatus = kSOSCCInCircle;
21
22 _excludeSelfPeerFromTrustSet = false;
23
24 _peerChangeListeners = [[CKKSListenerCollection alloc] initWithName:@"ckks-mock-sos"];
25
26 _selfPeer = selfPeer;
27 _trustedPeers = [trustedPeers mutableCopy];
28 }
29 return self;
30 }
31
32 - (NSString*)providerID
33 {
34 return [NSString stringWithFormat:@"[CKKSMockSOSPresentAdapter: %@]", self.selfPeer.peerID];
35 }
36
37 - (SOSCCStatus)circleStatus:(NSError * _Nullable __autoreleasing * _Nullable)error
38 {
39 if(!self.sosEnabled || self.circleStatus == kSOSCCError) {
40 if(error && self.circleStatus == kSOSCCError) {
41 // I'm not at all sure that the second error here actually is any error in particular
42 *error = self.circleStatusError ?: [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:self.circleStatus userInfo:nil];
43 }
44 return kSOSCCError;
45 }
46
47 return self.circleStatus;
48 }
49
50 // I currently don't understand when SOS returns a self or not. I've seen it return a self while not in kSOSCCInCircle,
51 // which seems wrong. So, always return a self, unless we're in an obvious error state.
52 - (id<CKKSSelfPeer> _Nullable)currentSOSSelf:(NSError * _Nullable __autoreleasing * _Nullable)error
53 {
54 if(self.selfPeerError) {
55 if(error) {
56 *error = self.selfPeerError;
57 }
58 return nil;
59 }
60
61 if(self.sosEnabled && self.circleStatus == kSOSCCInCircle) {
62 return self.selfPeer;
63 } else {
64 if(error) {
65 *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:self.circleStatus userInfo:nil];
66 }
67 return nil;
68 }
69 }
70
71 - (CKKSSelves * _Nullable)fetchSelfPeers:(NSError *__autoreleasing _Nullable * _Nullable)error
72 {
73 id<CKKSSelfPeer> peer = [self currentSOSSelf:error];
74 if(!peer) {
75 return nil;
76 }
77
78 return [[CKKSSelves alloc] initWithCurrent:peer allSelves:nil];
79 }
80
81 - (NSSet<id<CKKSRemotePeerProtocol>> * _Nullable)fetchTrustedPeers:(NSError * _Nullable __autoreleasing * _Nullable)error
82 {
83 if(self.trustedPeersError) {
84 if(*error) {
85 *error = self.trustedPeersError;
86 }
87 return nil;
88 }
89
90 // TODO: I'm actually not entirely sure what SOS does if it's not in circle?
91 if(self.sosEnabled && self.circleStatus == kSOSCCInCircle) {
92 if(self.excludeSelfPeerFromTrustSet) {
93 return self.trustedPeers;
94 } else {
95 return [self allPeers];
96 }
97 } else {
98 if(error) {
99 *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:kSOSCCNotInCircle userInfo:nil];
100 }
101 return nil;
102 }
103 }
104
105 - (void)updateOctagonKeySetWithAccount:(nonnull id<CKKSSelfPeer>)currentSelfPeer error:(NSError *__autoreleasing _Nullable * _Nullable)error {
106 if(self.updateOctagonKeySetListener) {
107 self.updateOctagonKeySetListener(currentSelfPeer);
108 }
109 return;
110 }
111
112 - (void)registerForPeerChangeUpdates:(nonnull id<CKKSPeerUpdateListener>)listener {
113 [self.peerChangeListeners registerListener:listener];
114 }
115
116 - (void)sendSelfPeerChangedUpdate {
117 [self.peerChangeListeners iterateListeners: ^(id<CKKSPeerUpdateListener> listener) {
118 [listener selfPeerChanged:self];
119 }];
120 }
121
122 - (void)sendTrustedPeerSetChangedUpdate {
123 [self.peerChangeListeners iterateListeners: ^(id<CKKSPeerUpdateListener> listener) {
124 [listener trustedPeerSetChanged:self];
125 }];
126 }
127
128 - (nonnull CKKSPeerProviderState *)currentState {
129 return [CKKSPeerProviderState createFromProvider:self];
130 }
131
132 - (NSSet<id<CKKSRemotePeerProtocol>>*)allPeers
133 {
134 // include the self peer, but as a CKKSSOSPeer object instead of a self peer
135 CKKSSOSPeer* s = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.selfPeer.peerID
136 encryptionPublicKey:self.selfPeer.publicEncryptionKey
137 signingPublicKey:self.selfPeer.publicSigningKey
138 viewList:self.selfPeer.viewList];
139
140 return [self.trustedPeers setByAddingObject: s];
141 }
142
143 @end