]> git.saurik.com Git - apple/security.git/blob - keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h
Security-59306.101.1.tar.gz
[apple/security.git] / keychain / TrustedPeersHelper / TrustedPeersHelperProtocol.h
1 /*
2 * Copyright (c) 2018 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #import <Foundation/Foundation.h>
25 #import <TrustedPeers/TrustedPeers.h>
26
27 #import "keychain/ckks/CKKSKeychainBackedKey.h"
28 #import "keychain/ckks/CKKSTLKShare.h"
29
30 #import "keychain/ot/OTConstants.h"
31
32 NS_ASSUME_NONNULL_BEGIN
33
34 // Any client hoping to use the TrustedPeersHelperProtocol should have an entitlement
35 // 'com.apple.private.trustedpeershelper.client' set to boolean YES.
36
37 @interface TrustedPeersHelperPeerState : NSObject <NSSecureCoding>
38 @property (nullable) NSString* peerID;
39 @property BOOL identityIsPreapproved;
40 @property TPPeerStatus peerStatus;
41 @property BOOL memberChanges;
42 @property BOOL unknownMachineIDsPresent;
43 @property (nullable) NSString* osVersion;
44
45 - (instancetype)initWithPeerID:(NSString* _Nullable)peerID
46 isPreapproved:(BOOL)isPreapproved
47 status:(TPPeerStatus)peerStatus
48 memberChanges:(BOOL)memberChanges
49 unknownMachineIDs:(BOOL)unknownMachineIDs
50 osVersion:(NSString * _Nullable)osVersion;
51 @end
52
53 @interface TrustedPeersHelperPeer : NSObject <NSSecureCoding>
54 @property (nullable) NSString* peerID;
55 @property (nullable) NSData* signingSPKI;
56 @property (nullable) NSData* encryptionSPKI;
57 @property (nullable) NSSet<NSString*>* viewList;
58
59 - (instancetype)initWithPeerID:(NSString*)peerID
60 signingSPKI:(NSData*)signingSPKI
61 encryptionSPKI:(NSData*)encryptionSPKI
62 viewList:(NSSet<NSString*>*)viewList;
63 @end
64
65 @interface TrustedPeersHelperEgoPeerStatus : NSObject <NSSecureCoding>
66 @property TPPeerStatus egoStatus;
67 @property NSString* _Nullable egoPeerID;
68 @property (assign) uint64_t numberOfPeersInOctagon;
69
70 // Note: this field does not include untrusted peers
71 @property NSDictionary<NSString*, NSNumber*>* viablePeerCountsByModelID;
72
73 // Note: this field does include untrusted peers
74 @property NSDictionary<NSString*, NSNumber*>* peerCountsByMachineID;
75
76 @property BOOL isExcluded;
77 @property BOOL isLocked;
78
79 - (instancetype)initWithEgoPeerID:(NSString* _Nullable)egoPeerID
80 status:(TPPeerStatus)egoStatus
81 viablePeerCountsByModelID:(NSDictionary<NSString*, NSNumber*>*)viablePeerCountsByModelID
82 peerCountsByMachineID:(NSDictionary<NSString*, NSNumber*>*)peerCountsByMachineID
83 isExcluded:(BOOL)isExcluded
84 isLocked:(BOOL)isLocked;
85
86 @end
87
88 // This protocol describes the interface of the TrustedPeersHelper XPC service.
89 @protocol TrustedPeersHelperProtocol
90
91 // This is used by a unit test which exercises the XPC-service plumbing.
92 - (void)pingWithReply:(void (^)(void))reply;
93
94 - (void)dumpWithContainer:(NSString *)container
95 context:(NSString *)context
96 reply:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply;
97
98 - (void)departByDistrustingSelfWithContainer:(NSString *)container
99 context:(NSString *)context
100 reply:(void (^)(NSError * _Nullable))reply;
101
102 - (void)distrustPeerIDsWithContainer:(NSString *)container
103 context:(NSString *)context
104 peerIDs:(NSSet<NSString*>*)peerIDs
105 reply:(void (^)(NSError * _Nullable))reply;
106
107 - (void)trustStatusWithContainer:(NSString *)container
108 context:(NSString *)context
109 reply:(void (^)(TrustedPeersHelperEgoPeerStatus *status,
110 NSError* _Nullable error))reply;
111
112 - (void)resetWithContainer:(NSString *)container
113 context:(NSString *)context
114 resetReason:(CuttlefishResetReason)reason
115 reply:(void (^)(NSError * _Nullable error))reply;
116
117 - (void)localResetWithContainer:(NSString *)container
118 context:(NSString *)context
119 reply:(void (^)(NSError * _Nullable error))reply;
120
121 // The following three machine ID list manipulation functions do not attempt to apply the results to the model
122 // If you'd like that to occur, please call update()
123
124 // TODO: how should we communicate TLK rolling when the update() call will remove a peer?
125 // <rdar://problem/46633449> Octagon: must be able to roll TLKs when a peer departs due to machine ID list
126
127 // listDifferences: False if the allowedMachineIDs list passed in exactly matches the previous state,
128 // True if there were any differences
129 - (void)setAllowedMachineIDsWithContainer:(NSString *)container
130 context:(NSString *)context
131 allowedMachineIDs:(NSSet<NSString*> *)allowedMachineIDs
132 honorIDMSListChanges:(BOOL)honorIDMSListChanges
133 reply:(void (^)(BOOL listDifferences, NSError * _Nullable error))reply;
134
135 - (void)addAllowedMachineIDsWithContainer:(NSString *)container
136 context:(NSString *)context
137 machineIDs:(NSArray<NSString*> *)machineIDs
138 reply:(void (^)(NSError * _Nullable error))reply;
139
140 - (void)removeAllowedMachineIDsWithContainer:(NSString *)container
141 context:(NSString *)context
142 machineIDs:(NSArray<NSString*> *)machineIDs
143 reply:(void (^)(NSError * _Nullable error))reply;
144
145 - (void)fetchAllowedMachineIDsWithContainer:(NSString *)container
146 context:(NSString *)context
147 reply:(void (^)(NSSet<NSString*>* _Nullable machineIDs, NSError* _Nullable error))reply;
148
149 - (void)fetchEgoEpochWithContainer:(NSString *)container
150 context:(NSString *)context
151 reply:(void (^)(unsigned long long epoch,
152 NSError * _Nullable error))reply;
153
154 - (void)prepareWithContainer:(NSString *)container
155 context:(NSString *)context
156 epoch:(unsigned long long)epoch
157 machineID:(NSString *)machineID
158 bottleSalt:(NSString *)bottleSalt
159 bottleID:(NSString *)bottleID
160 modelID:(NSString *)modelID
161 deviceName:(nullable NSString*)deviceName
162 serialNumber:(NSString *)serialNumber
163 osVersion:(NSString *)osVersion
164 policyVersion:(nullable TPPolicyVersion *)policyVersion
165 policySecrets:(nullable NSDictionary<NSString*,NSData*> *)policySecrets
166 signingPrivKeyPersistentRef:(nullable NSData *)spkPr
167 encPrivKeyPersistentRef:(nullable NSData*)epkPr
168 reply:(void (^)(NSString * _Nullable peerID,
169 NSData * _Nullable permanentInfo,
170 NSData * _Nullable permanentInfoSig,
171 NSData * _Nullable stableInfo,
172 NSData * _Nullable stableInfoSig,
173 NSSet<NSString*>* _Nullable syncingViewList,
174 TPPolicy* _Nullable syncingPolicy,
175 NSError * _Nullable error))reply;
176
177 // If there already are existing CKKSViews, please pass in their key sets anyway.
178 // This function will create a self TLK Share for those TLKs.
179 - (void)establishWithContainer:(NSString *)container
180 context:(NSString *)context
181 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
182 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
183 preapprovedKeys:(nullable NSArray<NSData*> *)preapprovedKeys
184 reply:(void (^)(NSString * _Nullable peerID,
185 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
186 NSError * _Nullable error))reply;
187
188 // Returns a voucher for the given peer ID using our own identity
189 // If TLK CKKSViewKeys are given, TLKShares will be created and uploaded for this new peer before this call returns.
190 - (void)vouchWithContainer:(NSString *)container
191 context:(NSString *)context
192 peerID:(NSString *)peerID
193 permanentInfo:(NSData *)permanentInfo
194 permanentInfoSig:(NSData *)permanentInfoSig
195 stableInfo:(NSData *)stableInfo
196 stableInfoSig:(NSData *)stableInfoSig
197 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
198 reply:(void (^)(NSData * _Nullable voucher,
199 NSData * _Nullable voucherSig,
200 NSError * _Nullable error))reply;
201
202 // Preflighting a vouch will return the peer ID associated with the bottle you will be recovering, as well as
203 // the syncing policy used by that peer, and,
204 // You can then use that peer ID to filter the tlkshares provided to vouchWithBottle.
205 - (void)preflightVouchWithBottleWithContainer:(NSString *)container
206 context:(NSString *)context
207 bottleID:(NSString*)bottleID
208 reply:(void (^)(NSString* _Nullable peerID,
209 NSSet<NSString*>* _Nullable peerSyncingViewList,
210 TPPolicy * _Nullable peerSyncingPolicy,
211 NSError * _Nullable error))reply;
212
213 // Returns a voucher for our own identity, created by the identity inside this bottle
214 - (void)vouchWithBottleWithContainer:(NSString *)container
215 context:(NSString *)context
216 bottleID:(NSString*)bottleID
217 entropy:(NSData*)entropy
218 bottleSalt:(NSString*)bottleSalt
219 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
220 reply:(void (^)(NSData * _Nullable voucher,
221 NSData * _Nullable voucherSig,
222 int64_t uniqueTLKsRecovered,
223 int64_t totalTLKSharesRecovered,
224 NSError * _Nullable error))reply;
225
226 // Preflighting a vouch will return the RK ID, view list and policy associated with the RK you will be recovering.
227 // You can then use that peer ID to filter the tlkshares provided to vouchWithRecoveryKey.
228 - (void)preflightVouchWithRecoveryKeyWithContainer:(NSString*)container
229 context:(NSString*)context
230 recoveryKey:(NSString*)recoveryKey
231 salt:(NSString*)salt
232 reply:(void (^)(NSString* _Nullable recoveryKeyID,
233 NSSet<NSString*>* _Nullable peerSyncingViewList,
234 TPPolicy * _Nullable peerSyncingPolicy,
235 NSError * _Nullable error))reply;
236
237 // Returns a voucher for our own identity, using recovery key
238 - (void)vouchWithRecoveryKeyWithContainer:(NSString *)container
239 context:(NSString *)context
240 recoveryKey:(NSString*)recoveryKey
241 salt:(NSString*)salt
242 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
243 reply:(void (^)(NSData * _Nullable voucher,
244 NSData * _Nullable voucherSig,
245 NSError * _Nullable error))reply;
246
247 // As of right now, join and attemptPreapprovedJoin will upload TLKShares for any TLKs that this peer already has.
248 // Note that in The Future, a device might decide to join an existing Octagon set while introducing a new view.
249 // These interfaces will have to change...
250 - (void)joinWithContainer:(NSString *)container
251 context:(NSString *)context
252 voucherData:(NSData *)voucherData
253 voucherSig:(NSData *)voucherSig
254 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
255 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
256 preapprovedKeys:(NSArray<NSData*> *)preapprovedKeys
257 reply:(void (^)(NSString * _Nullable peerID,
258 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
259 NSSet<NSString*>* _Nullable syncingViewList,
260 TPPolicy* _Nullable syncingPolicy,
261 NSError * _Nullable error))reply;
262
263 // Preflighting a preapproved join suggests whether or not you expect to succeed in an immediate preapprovedJoin() call
264 // This only inspects the Octagon model, and ignores the trusted device list, so that you can preflight the preapprovedJoin()
265 // before fetching that list.
266 // This will return YES if there are no existing peers, or if the existing peers preapprove your prepared identity.
267 // This will return NO otherwise.
268 - (void)preflightPreapprovedJoinWithContainer:(NSString *)container
269 context:(NSString *)context
270 reply:(void (^)(BOOL launchOkay,
271 NSError * _Nullable error))reply;
272
273 // A preapproved join might do a join, but it also might do an establish.
274 // Therefore, it needs all the TLKs and TLKShares as establish does
275 - (void)attemptPreapprovedJoinWithContainer:(NSString *)container
276 context:(NSString *)context
277 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
278 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
279 preapprovedKeys:(NSArray<NSData*> *)preapprovedKeys
280 reply:(void (^)(NSString * _Nullable peerID,
281 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
282 NSSet<NSString*>* _Nullable syncingViewList,
283 TPPolicy* _Nullable syncingPolicy,
284 NSError * _Nullable error))reply;
285
286 // TODO: if the new policy causes someone to lose access to a view, how should this API work?
287 - (void)updateWithContainer:(NSString *)container
288 context:(NSString *)context
289 deviceName:(nullable NSString *)deviceName
290 serialNumber:(nullable NSString *)serialNumber
291 osVersion:(nullable NSString *)osVersion
292 policyVersion:(nullable NSNumber *)policyVersion
293 policySecrets:(nullable NSDictionary<NSString*,NSData*> *)policySecrets
294 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable peerState, NSError * _Nullable error))reply;
295
296 - (void)setPreapprovedKeysWithContainer:(NSString *)container
297 context:(NSString *)context
298 preapprovedKeys:(NSArray<NSData*> *)preapprovedKeys
299 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable peerState, NSError * _Nullable error))reply;
300
301 /* Rather thin pass-through for uploading new TLKs (for zones which may have disappeared) */
302 - (void)updateTLKsWithContainer:(NSString *)container
303 context:(NSString *)context
304 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
305 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
306 reply:(void (^)(NSArray<CKRecord*>* _Nullable keyHierarchyRecords, NSError * _Nullable error))reply;
307
308 - (void)fetchViableBottlesWithContainer:(NSString *)container
309 context:(NSString *)context
310 reply:(void (^)(NSArray<NSString*>* _Nullable sortedBottleIDs, NSArray<NSString*>* _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply;
311
312 - (void)fetchEscrowContentsWithContainer:(NSString *)container
313 context:(NSString *)context
314 reply:(void (^)(NSData* _Nullable entropy,
315 NSString* _Nullable bottleID,
316 NSData* _Nullable signingPublicKey,
317 NSError* _Nullable error))reply;
318
319 - (void)fetchPolicyDocumentsWithContainer:(NSString*)container
320 context:(NSString*)context
321 versions:(NSSet<TPPolicyVersion*>*)versions
322 reply:(void (^)(NSDictionary<TPPolicyVersion*, NSData*>* _Nullable entries,
323 NSError * _Nullable error))reply;
324
325 // Fetch the policy and view list for current peer.
326 - (void)fetchCurrentPolicyWithContainer:(NSString*)container
327 context:(NSString*)context
328 reply:(void (^)(NSSet<NSString*>* _Nullable syncingViewList,
329 TPPolicy * _Nullable syncingPolicy,
330 NSError * _Nullable error))reply;
331
332 - (void)validatePeersWithContainer:(NSString *)container
333 context:(NSString *)context
334 reply:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply;
335
336
337 // TODO: merge this and trustStatusWithContainer
338 - (void)fetchTrustStateWithContainer:(NSString *)container
339 context:(NSString *)context
340 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable selfPeerState,
341 NSArray<TrustedPeersHelperPeer*>* _Nullable trustedPeers,
342 NSError* _Nullable error))reply;
343
344 - (void)setRecoveryKeyWithContainer:(NSString *)container
345 context:(NSString *)context
346 recoveryKey:(NSString *)recoveryKey
347 salt:(NSString *)salt
348 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
349 reply:(void (^)(NSError* _Nullable error))reply;
350
351 - (void)reportHealthWithContainer:(NSString *)container
352 context:(NSString *)context
353 stateMachineState:(NSString *)state
354 trustState:(NSString *)trustState
355 reply:(void (^)(NSError* _Nullable error))reply;
356
357 - (void)pushHealthInquiryWithContainer:(NSString *)container
358 context:(NSString *)context
359 reply:(void (^)(NSError* _Nullable error))reply;
360
361 - (void)requestHealthCheckWithContainer:(NSString *)container
362 context:(NSString *)context
363 requiresEscrowCheck:(BOOL)requiresEscrowCheck
364 reply:(void (^)(BOOL postRepairCFU, BOOL postEscrowCFU, BOOL resetOctagon, BOOL leaveTrust, NSError* _Nullable))reply;
365
366 - (void)getSupportAppInfoWithContainer:(NSString *)container
367 context:(NSString *)context
368 reply:(void (^)(NSData * _Nullable, NSError * _Nullable))reply;
369
370 @end
371
372 /*
373 To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this:
374
375 _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.TrustedPeersHelper"];
376 _connectionToService.remoteObjectInterface = TrustedPeersHelperSetupProtocol([NSXPCInterface interfaceWithProtocol:@protocol(TrustedPeersHelperProtocol)]);
377 [_connectionToService resume];
378
379 Once you have a connection to the service, you can use it like this:
380
381 [[_connectionToService remoteObjectProxy] upperCaseString:@"hello" withReply:^(NSString *aString) {
382 // We have received a response. Update our text field, but do it on the main thread.
383 NSLog(@"Result string was: %@", aString);
384 }];
385
386 And, when you are finished with the service, clean up the connection like this:
387
388 [_connectionToService invalidate];
389 */
390
391
392 // Use this at protocol creation time to tell NSXPC to do its job
393 NSXPCInterface* TrustedPeersHelperSetupProtocol(NSXPCInterface* interface);
394
395 NS_ASSUME_NONNULL_END