]> git.saurik.com Git - apple/security.git/blob - keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.m
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / TrustedPeersHelper / TrustedPeersHelperProtocol.m
1
2 #import <Foundation/Foundation.h>
3
4 #if OCTAGON
5 #import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h"
6 #import "utilities/debugging.h"
7 #import <CloudKit/CloudKit.h>
8 #import <CloudKit/CloudKit_Private.h>
9 #import <Security/SecXPCHelper.h>
10 #endif
11
12 NSXPCInterface* TrustedPeersHelperSetupProtocol(NSXPCInterface* interface)
13 {
14 #if OCTAGON
15 static NSMutableSet *errClasses;
16
17 static dispatch_once_t onceToken;
18 dispatch_once(&onceToken, ^{
19 errClasses = [NSMutableSet setWithSet:CKAcceptableValueClasses()];
20 [errClasses unionSet:[SecXPCHelper safeErrorClasses]];
21 });
22
23 @try {
24 NSSet* arrayOfKeySets = [NSSet setWithArray:@[[NSArray class], [CKKSKeychainBackedKeySet class]]];
25 NSSet* arrayOfTLKShares = [NSSet setWithArray:@[[NSArray class], [CKKSTLKShare class]]];
26 NSSet* arrayOfCKRecords = [NSSet setWithArray:@[[NSArray class], [CKRecord class]]];
27 NSSet* arrayOfStrings = [NSSet setWithArray:@[[NSArray class], [NSString class]]];
28 NSSet* trustedPeersHelperPeerState = [NSSet setWithObject:[TrustedPeersHelperPeerState class]];
29
30 NSSet* arrayOfTrustedPeersHelperPeer = [NSSet setWithArray:@[[NSArray class], [TrustedPeersHelperPeer class]]];
31
32 [interface setClasses:errClasses forSelector:@selector(dumpWithContainer:context:reply:) argumentIndex:1 ofReply:YES];
33 [interface setClasses:errClasses forSelector:@selector(departByDistrustingSelfWithContainer:context:reply:) argumentIndex:0 ofReply:YES];
34 [interface setClasses:errClasses forSelector:@selector(distrustPeerIDsWithContainer:context:peerIDs:reply:) argumentIndex:0 ofReply:YES];
35 [interface setClasses:errClasses forSelector:@selector(trustStatusWithContainer:context:reply:) argumentIndex:1 ofReply:YES];
36 [interface setClasses:errClasses forSelector:@selector(resetWithContainer:context:resetReason:reply:) argumentIndex:0 ofReply:YES];
37 [interface setClasses:errClasses forSelector:@selector(localResetWithContainer:context:reply:) argumentIndex:0 ofReply:YES];
38 [interface setClasses:errClasses forSelector:@selector(setAllowedMachineIDsWithContainer:context:allowedMachineIDs:honorIDMSListChanges:reply:) argumentIndex:1 ofReply:YES];
39 [interface setClasses:errClasses forSelector:@selector(addAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:0 ofReply:YES];
40 [interface setClasses:errClasses forSelector:@selector(removeAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:0 ofReply:YES];
41 [interface setClasses:errClasses forSelector:@selector(fetchAllowedMachineIDsWithContainer:context:reply:) argumentIndex:1 ofReply:YES];
42 [interface setClasses:errClasses forSelector:@selector(fetchEgoEpochWithContainer:context:reply:) argumentIndex:1 ofReply:YES];
43 [interface setClasses:errClasses forSelector:@selector(prepareWithContainer:context:epoch:machineID:bottleSalt:bottleID:modelID:deviceName:serialNumber:osVersion:policyVersion:policySecrets:syncUserControllableViews:signingPrivKeyPersistentRef:encPrivKeyPersistentRef:reply:) argumentIndex:6 ofReply:YES];
44 [interface setClasses:errClasses forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:YES];
45 [interface setClasses:errClasses forSelector:@selector(vouchWithContainer:context:peerID:permanentInfo:permanentInfoSig:stableInfo:stableInfoSig:ckksKeys:reply:) argumentIndex:2 ofReply:YES];
46 [interface setClasses:errClasses forSelector:@selector(preflightVouchWithBottleWithContainer:context:bottleID:reply:) argumentIndex:3 ofReply:YES];
47 [interface setClasses:errClasses forSelector:@selector(vouchWithBottleWithContainer:context:bottleID:entropy:bottleSalt:tlkShares:reply:) argumentIndex:4 ofReply:YES];
48 [interface setClasses:errClasses forSelector:@selector(preflightVouchWithRecoveryKeyWithContainer:context:recoveryKey:salt:reply:) argumentIndex:2 ofReply:YES];
49 [interface setClasses:errClasses forSelector:@selector(vouchWithRecoveryKeyWithContainer:context:recoveryKey:salt:tlkShares:reply:) argumentIndex:2 ofReply:YES];
50 [interface setClasses:errClasses forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:YES];
51 [interface setClasses:errClasses forSelector:@selector(preflightPreapprovedJoinWithContainer:context:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
52 [interface setClasses:errClasses forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:YES];
53 [interface setClasses:errClasses forSelector:@selector(updateWithContainer:context:deviceName:serialNumber:osVersion:policyVersion:policySecrets:syncUserControllableViews:reply:) argumentIndex:2 ofReply:YES];
54 [interface setClasses:errClasses forSelector:@selector(setPreapprovedKeysWithContainer:context:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
55 [interface setClasses:errClasses forSelector:@selector(updateTLKsWithContainer:context:ckksKeys:tlkShares:reply:) argumentIndex:1 ofReply:YES];
56 [interface setClasses:errClasses forSelector:@selector(fetchViableBottlesWithContainer:context:reply:) argumentIndex:2 ofReply:YES];
57 [interface setClasses:errClasses forSelector:@selector(fetchViableEscrowRecordsWithContainer:context:forceFetch:reply:) argumentIndex:1 ofReply:YES];
58 [interface setClasses:errClasses forSelector:@selector(fetchEscrowContentsWithContainer:context:reply:) argumentIndex:3 ofReply:YES];
59 [interface setClasses:errClasses forSelector:@selector(fetchPolicyDocumentsWithContainer:context:versions:reply:) argumentIndex:1 ofReply:YES];
60 [interface setClasses:errClasses forSelector:@selector(fetchCurrentPolicyWithContainer:context:modelIDOverride:reply:) argumentIndex:2 ofReply:YES];
61 [interface setClasses:errClasses forSelector:@selector(validatePeersWithContainer:context:reply:) argumentIndex:1 ofReply:YES];
62 [interface setClasses:errClasses forSelector:@selector(fetchTrustStateWithContainer:context:reply:) argumentIndex:2 ofReply:YES];
63 [interface setClasses:errClasses forSelector:@selector(setRecoveryKeyWithContainer:context:recoveryKey:salt:ckksKeys:reply:) argumentIndex:1 ofReply:YES];
64 [interface setClasses:errClasses forSelector:@selector(reportHealthWithContainer:context:stateMachineState:trustState:reply:) argumentIndex:0 ofReply:YES];
65 [interface setClasses:errClasses forSelector:@selector(pushHealthInquiryWithContainer:context:reply:) argumentIndex:0 ofReply:YES];
66 [interface setClasses:errClasses forSelector:@selector(requestHealthCheckWithContainer:context:requiresEscrowCheck:reply:) argumentIndex:4 ofReply:YES];
67 [interface setClasses:errClasses forSelector:@selector(getSupportAppInfoWithContainer:context:reply:) argumentIndex:1 ofReply:YES];
68 [interface setClasses:errClasses forSelector:@selector(removeEscrowCacheWithContainer:context:reply:) argumentIndex:0 ofReply:YES];
69
70
71 [interface setClasses:arrayOfStrings forSelector:@selector(addAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:2 ofReply:NO];
72 [interface setClasses:arrayOfStrings forSelector:@selector(removeAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:2 ofReply:NO];
73
74 [interface setClasses:arrayOfKeySets forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:2 ofReply:NO];
75 [interface setClasses:arrayOfTLKShares forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:NO];
76 [interface setClasses:arrayOfCKRecords forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
77
78 [interface setClasses:arrayOfKeySets forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:4 ofReply:NO];
79 [interface setClasses:arrayOfTLKShares forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:5 ofReply:NO];
80 [interface setClasses:arrayOfCKRecords forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
81
82 [interface setClasses:arrayOfKeySets forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:2 ofReply:NO];
83 [interface setClasses:arrayOfTLKShares forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:NO];
84 [interface setClasses:arrayOfCKRecords forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES];
85
86 [interface setClasses:arrayOfKeySets forSelector:@selector(vouchWithContainer:
87 context:
88 peerID:
89 permanentInfo:
90 permanentInfoSig:
91 stableInfo:
92 stableInfoSig:
93 ckksKeys:
94 reply:) argumentIndex:7 ofReply:NO];
95
96 [interface setClasses:arrayOfTLKShares forSelector:@selector(vouchWithBottleWithContainer:
97 context:
98 bottleID:
99 entropy:
100 bottleSalt:
101 tlkShares:
102 reply:) argumentIndex:5 ofReply:NO];
103 [interface setClasses:arrayOfKeySets forSelector:@selector(setRecoveryKeyWithContainer:
104 context:
105 recoveryKey:
106 salt:
107 ckksKeys:
108 reply:) argumentIndex:4 ofReply:NO];
109 [interface setClasses:arrayOfCKRecords forSelector:@selector(setRecoveryKeyWithContainer:
110 context:
111 recoveryKey:
112 salt:
113 ckksKeys:
114 reply:) argumentIndex:0 ofReply:YES];
115 [interface setClasses:arrayOfTLKShares forSelector:@selector(vouchWithRecoveryKeyWithContainer:
116 context:
117 recoveryKey:
118 salt:
119 tlkShares:
120 reply:) argumentIndex:4 ofReply:NO];
121
122 [interface setClasses:trustedPeersHelperPeerState forSelector:@selector(updateWithContainer:
123 context:
124 deviceName:
125 serialNumber:
126 osVersion:
127 policyVersion:
128 policySecrets:
129 syncUserControllableViews:
130 reply:) argumentIndex:0 ofReply:YES];
131
132 [interface setClasses:trustedPeersHelperPeerState forSelector:@selector(fetchTrustStateWithContainer:
133 context:
134 reply:) argumentIndex:0 ofReply:YES];
135 [interface setClasses:arrayOfTrustedPeersHelperPeer forSelector:@selector(fetchTrustStateWithContainer:
136 context:
137 reply:) argumentIndex:1 ofReply:YES];
138
139 [interface setClasses:arrayOfKeySets forSelector:@selector(updateTLKsWithContainer:
140 context:
141 ckksKeys:
142 tlkShares:
143 reply:) argumentIndex:2 ofReply:NO];
144 [interface setClasses:arrayOfTLKShares forSelector:@selector(updateTLKsWithContainer:
145 context:
146 ckksKeys:
147 tlkShares:
148 reply:) argumentIndex:3 ofReply:NO];
149 [interface setClasses:arrayOfCKRecords forSelector:@selector(updateTLKsWithContainer:
150 context:
151 ckksKeys:
152 tlkShares:
153 reply:) argumentIndex:0 ofReply:YES];
154 }
155 @catch(NSException* e) {
156 secerror("TrustedPeersHelperSetupProtocol failed, continuing, but you might crash later: %@", e);
157 @throw e;
158 }
159 #endif
160
161 return interface;
162 }
163
164 @implementation TrustedPeersHelperPeerState
165
166 - (instancetype)initWithPeerID:(NSString* _Nullable)peerID
167 isPreapproved:(BOOL)isPreapproved
168 status:(TPPeerStatus)peerStatus
169 memberChanges:(BOOL)memberChanges
170 unknownMachineIDs:(BOOL)unknownMachineIDs
171 osVersion:(NSString *)osVersion
172 {
173 if((self = [super init])) {
174 _peerID = peerID;
175 _identityIsPreapproved = isPreapproved;
176 _peerStatus = peerStatus;
177 _memberChanges = memberChanges;
178 _unknownMachineIDsPresent = unknownMachineIDs;
179 _osVersion = osVersion;
180 }
181 return self;
182 }
183
184 - (NSString*)description
185 {
186 return [NSString stringWithFormat:@"<TPHPeerState: %@ preapproved:%d status:%@ memberChanges: %@ unk. mIDs: %@ osVersion: %@>",
187 self.peerID,
188 self.identityIsPreapproved,
189 TPPeerStatusToString(self.peerStatus),
190 self.memberChanges ? @"YES" : @"NO",
191 self.unknownMachineIDsPresent ? @"YES" : @"NO",
192 self.osVersion?:@"unknown"];
193 }
194
195 + (BOOL)supportsSecureCoding {
196 return YES;
197 }
198
199 - (instancetype)initWithCoder:(NSCoder *)coder {
200 if ((self = [super init])) {
201 _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
202 _identityIsPreapproved = [coder decodeBoolForKey:@"identityIsPreapproved"];
203 _peerStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"peerStatus"];
204 _memberChanges = (BOOL)[coder decodeInt64ForKey:@"memberChanges"];
205 _unknownMachineIDsPresent = (BOOL)[coder decodeInt64ForKey:@"unknownMachineIDs"];
206 _osVersion = [coder decodeObjectOfClass:[NSString class] forKey:@"osVersion"];
207 }
208 return self;
209 }
210
211 - (void)encodeWithCoder:(NSCoder *)coder {
212 [coder encodeObject:self.peerID forKey:@"peerID"];
213 [coder encodeBool:self.identityIsPreapproved forKey:@"identityIsPreapproved"];
214 [coder encodeInt64:(int64_t)self.peerStatus forKey:@"peerStatus"];
215 [coder encodeInt64:(int64_t)self.memberChanges forKey:@"memberChanges"];
216 [coder encodeInt64:(int64_t)self.unknownMachineIDsPresent forKey:@"unknownMachineIDs"];
217 [coder encodeObject:self.osVersion forKey:@"osVersion"];
218
219 }
220 @end
221
222 @implementation TrustedPeersHelperEgoPeerStatus
223
224 - (instancetype)initWithEgoPeerID:(NSString* _Nullable)egoPeerID
225 status:(TPPeerStatus)egoStatus
226 viablePeerCountsByModelID:(NSDictionary<NSString*, NSNumber*>*)viablePeerCountsByModelID
227 peerCountsByMachineID:(NSDictionary<NSString *,NSNumber *> * _Nonnull)peerCountsByMachineID
228 isExcluded:(BOOL)isExcluded
229 isLocked:(BOOL)isLocked
230 {
231 if((self = [super init])) {
232 _egoPeerID = egoPeerID;
233 _egoStatus = egoStatus;
234 _viablePeerCountsByModelID = viablePeerCountsByModelID;
235 _peerCountsByMachineID = peerCountsByMachineID;
236 _numberOfPeersInOctagon = 0;
237 for(NSNumber* n in viablePeerCountsByModelID.allValues) {
238 _numberOfPeersInOctagon += [n unsignedIntegerValue];
239 }
240 _isExcluded = isExcluded;
241 _isLocked = isLocked;
242 }
243 return self;
244 }
245
246 - (NSString*)description
247 {
248 return [NSString stringWithFormat:@"<TPHEgoPeerState: %@>", self.egoPeerID];
249 }
250
251 + (BOOL)supportsSecureCoding {
252 return YES;
253 }
254
255 - (instancetype)initWithCoder:(NSCoder *)coder {
256 if ((self = [super init])) {
257 _egoPeerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
258 _egoStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"egoStatus"];
259 _viablePeerCountsByModelID = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSDictionary class], [NSString class], [NSNumber class]]] forKey:@"viablePeerCountsByModelID"];
260 _numberOfPeersInOctagon = 0;
261 for(NSNumber* n in _viablePeerCountsByModelID.allValues) {
262 _numberOfPeersInOctagon += [n unsignedIntegerValue];
263 }
264
265 _peerCountsByMachineID = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSDictionary class], [NSString class], [NSNumber class]]] forKey:@"peerCountsByMachineID"];
266
267 _isExcluded = (BOOL)[coder decodeBoolForKey:@"isExcluded"];
268 _isLocked = (BOOL)[coder decodeBoolForKey:@"isLocked"];
269 }
270 return self;
271 }
272
273 - (void)encodeWithCoder:(NSCoder *)coder {
274 [coder encodeObject:self.egoPeerID forKey:@"peerID"];
275 [coder encodeInt64:self.egoStatus forKey:@"egoStatus"];
276 [coder encodeObject:self.viablePeerCountsByModelID forKey:@"viablePeerCountsByModelID"];
277 [coder encodeObject:self.peerCountsByMachineID forKey:@"peerCountsByMachineID"];
278 [coder encodeBool:self.isExcluded forKey:@"isExcluded"];
279 [coder encodeBool:self.isLocked forKey:@"isLocked"];
280 }
281
282 @end
283
284
285 @implementation TrustedPeersHelperPeer
286 - (instancetype)initWithPeerID:(NSString*)peerID
287 signingSPKI:(NSData*)signingSPKI
288 encryptionSPKI:(NSData*)encryptionSPKI
289 viewList:(NSSet<NSString*>*)viewList
290 {
291 if((self = [super init])) {
292 _peerID = peerID;
293 _signingSPKI = signingSPKI;
294 _encryptionSPKI = encryptionSPKI;
295 _viewList = viewList;
296 }
297 return self;
298 }
299
300 - (NSString*)description
301 {
302 return [NSString stringWithFormat:@"<TPHPeer: %@ %@ %@ (%lu views)>",
303 self.peerID,
304 self.signingSPKI,
305 self.encryptionSPKI,
306 (unsigned long)self.viewList.count];
307 }
308
309 + (BOOL)supportsSecureCoding {
310 return YES;
311 }
312
313 - (instancetype)initWithCoder:(NSCoder *)coder {
314 if ((self = [super init])) {
315 _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"];
316 _signingSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"signingSPKI"];
317 _encryptionSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"encryptionSPKI"];
318 _viewList = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSSet class], [NSString class]]] forKey:@"viewList"];
319 }
320 return self;
321 }
322
323 - (void)encodeWithCoder:(NSCoder *)coder {
324 [coder encodeObject:self.peerID forKey:@"peerID"];
325 [coder encodeObject:self.signingSPKI forKey:@"signingSPKI"];
326 [coder encodeObject:self.encryptionSPKI forKey:@"encryptionSPKI"];
327 [coder encodeObject:self.viewList forKey:@"viewList"];
328 }
329 @end