]> git.saurik.com Git - apple/security.git/blob - keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h
Security-59306.80.4.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 reply:(void (^)(BOOL listDifferences, NSError * _Nullable error))reply;
133
134 - (void)addAllowedMachineIDsWithContainer:(NSString *)container
135 context:(NSString *)context
136 machineIDs:(NSArray<NSString*> *)machineIDs
137 reply:(void (^)(NSError * _Nullable error))reply;
138
139 - (void)removeAllowedMachineIDsWithContainer:(NSString *)container
140 context:(NSString *)context
141 machineIDs:(NSArray<NSString*> *)machineIDs
142 reply:(void (^)(NSError * _Nullable error))reply;
143
144 - (void)fetchAllowedMachineIDsWithContainer:(NSString *)container
145 context:(NSString *)context
146 reply:(void (^)(NSSet<NSString*>* _Nullable machineIDs, NSError* _Nullable error))reply;
147
148 - (void)fetchEgoEpochWithContainer:(NSString *)container
149 context:(NSString *)context
150 reply:(void (^)(unsigned long long epoch,
151 NSError * _Nullable error))reply;
152
153 - (void)prepareWithContainer:(NSString *)container
154 context:(NSString *)context
155 epoch:(unsigned long long)epoch
156 machineID:(NSString *)machineID
157 bottleSalt:(NSString *)bottleSalt
158 bottleID:(NSString *)bottleID
159 modelID:(NSString *)modelID
160 deviceName:(nullable NSString*)deviceName
161 serialNumber:(NSString *)serialNumber
162 osVersion:(NSString *)osVersion
163 policyVersion:(nullable NSNumber *)policyVersion
164 policySecrets:(nullable NSDictionary<NSString*,NSData*> *)policySecrets
165 signingPrivKeyPersistentRef:(nullable NSData *)spkPr
166 encPrivKeyPersistentRef:(nullable NSData*)epkPr
167 reply:(void (^)(NSString * _Nullable peerID,
168 NSData * _Nullable permanentInfo,
169 NSData * _Nullable permanentInfoSig,
170 NSData * _Nullable stableInfo,
171 NSData * _Nullable stableInfoSig,
172 NSError * _Nullable error))reply;
173
174 // If there already are existing CKKSViews, please pass in their key sets anyway.
175 // This function will create a self TLK Share for those TLKs.
176 - (void)establishWithContainer:(NSString *)container
177 context:(NSString *)context
178 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
179 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
180 preapprovedKeys:(nullable NSArray<NSData*> *)preapprovedKeys
181 reply:(void (^)(NSString * _Nullable peerID,
182 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
183 NSError * _Nullable error))reply;
184
185 // Returns a voucher for the given peer ID using our own identity
186 // If TLK CKKSViewKeys are given, TLKShares will be created and uploaded for this new peer before this call returns.
187 - (void)vouchWithContainer:(NSString *)container
188 context:(NSString *)context
189 peerID:(NSString *)peerID
190 permanentInfo:(NSData *)permanentInfo
191 permanentInfoSig:(NSData *)permanentInfoSig
192 stableInfo:(NSData *)stableInfo
193 stableInfoSig:(NSData *)stableInfoSig
194 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
195 reply:(void (^)(NSData * _Nullable voucher,
196 NSData * _Nullable voucherSig,
197 NSError * _Nullable error))reply;
198
199 // Preflighting a vouch will return the peer ID associated with the bottle you will be recovering.
200 // You can then use that peer ID to filter the tlkshares provided to vouchWithBottle.
201 - (void)preflightVouchWithBottleWithContainer:(NSString *)container
202 context:(NSString *)context
203 bottleID:(NSString*)bottleID
204 reply:(void (^)(NSString* _Nullable peerID,
205 NSError * _Nullable error))reply;
206
207 // Returns a voucher for our own identity, created by the identity inside this bottle
208 - (void)vouchWithBottleWithContainer:(NSString *)container
209 context:(NSString *)context
210 bottleID:(NSString*)bottleID
211 entropy:(NSData*)entropy
212 bottleSalt:(NSString*)bottleSalt
213 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
214 reply:(void (^)(NSData * _Nullable voucher,
215 NSData * _Nullable voucherSig,
216 NSError * _Nullable error))reply;
217
218 // Returns a voucher for our own identity, using recovery key
219 - (void)vouchWithRecoveryKeyWithContainer:(NSString *)container
220 context:(NSString *)context
221 recoveryKey:(NSString*)recoveryKey
222 salt:(NSString*)salt
223 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
224 reply:(void (^)(NSData * _Nullable voucher,
225 NSData * _Nullable voucherSig,
226 NSError * _Nullable error))reply;
227
228 // As of right now, join and attemptPreapprovedJoin will upload TLKShares for any TLKs that this peer already has.
229 // Note that in The Future, a device might decide to join an existing Octagon set while introducing a new view.
230 // These interfaces will have to change...
231 - (void)joinWithContainer:(NSString *)container
232 context:(NSString *)context
233 voucherData:(NSData *)voucherData
234 voucherSig:(NSData *)voucherSig
235 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)viewKeySets
236 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
237 preapprovedKeys:(NSArray<NSData*> *)preapprovedKeys
238 reply:(void (^)(NSString * _Nullable peerID,
239 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
240 NSError * _Nullable error))reply;
241
242 // Preflighting a preapproved join suggests whether or not you expect to succeed in an immediate preapprovedJoin() call
243 // This only inspects the Octagon model, and ignores the trusted device list, so that you can preflight the preapprovedJoin()
244 // before fetching that list.
245 // This will return YES if there are no existing peers, or if the existing peers preapprove your prepared identity.
246 // This will return NO otherwise.
247 - (void)preflightPreapprovedJoinWithContainer:(NSString *)container
248 context:(NSString *)context
249 reply:(void (^)(BOOL launchOkay,
250 NSError * _Nullable error))reply;
251
252 // A preapproved join might do a join, but it also might do an establish.
253 // Therefore, it needs all the TLKs and TLKShares as establish does
254 - (void)attemptPreapprovedJoinWithContainer:(NSString *)container
255 context:(NSString *)context
256 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
257 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
258 preapprovedKeys:(NSArray<NSData*> *)preapprovedKeys
259 reply:(void (^)(NSString * _Nullable peerID,
260 NSArray<CKRecord*>* _Nullable keyHierarchyRecords,
261 NSError * _Nullable error))reply;
262
263 // TODO: if the new policy causes someone to lose access to a view, how should this API work?
264 - (void)updateWithContainer:(NSString *)container
265 context:(NSString *)context
266 deviceName:(nullable NSString *)deviceName
267 serialNumber:(nullable NSString *)serialNumber
268 osVersion:(nullable NSString *)osVersion
269 policyVersion:(nullable NSNumber *)policyVersion
270 policySecrets:(nullable NSDictionary<NSString*,NSData*> *)policySecrets
271 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable peerState, NSError * _Nullable error))reply;
272
273 - (void)setPreapprovedKeysWithContainer:(NSString *)container
274 context:(NSString *)context
275 preapprovedKeys:(NSArray<NSData*> *)preapprovedKeys
276 reply:(void (^)(NSError * _Nullable error))reply;
277
278 /* Rather thin pass-through for uploading new TLKs (for zones which may have disappeared) */
279 - (void)updateTLKsWithContainer:(NSString *)container
280 context:(NSString *)context
281 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
282 tlkShares:(NSArray<CKKSTLKShare*> *)tlkShares
283 reply:(void (^)(NSArray<CKRecord*>* _Nullable keyHierarchyRecords, NSError * _Nullable error))reply;
284
285 - (void)fetchViableBottlesWithContainer:(NSString *)container
286 context:(NSString *)context
287 reply:(void (^)(NSArray<NSString*>* _Nullable sortedBottleIDs, NSArray<NSString*>* _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply;
288
289 - (void)fetchEscrowContentsWithContainer:(NSString *)container
290 context:(NSString *)context
291 reply:(void (^)(NSData* _Nullable entropy,
292 NSString* _Nullable bottleID,
293 NSData* _Nullable signingPublicKey,
294 NSError* _Nullable error))reply;
295
296 // The argument contains N [version:hash] keys,
297 // the reply block contains 0<=N [version:[hash, data]] entries.
298 - (void)fetchPolicyDocumentsWithContainer:(NSString*)container
299 context:(NSString*)context
300 keys:(NSDictionary<NSNumber*,NSString*>*)keys
301 reply:(void (^)(NSDictionary<NSNumber*,NSArray<NSString*>*>* _Nullable entries,
302 NSError * _Nullable error))reply;
303
304 // Fetch the policy for current peer.
305 - (void)fetchPolicyWithContainer:(NSString*)container
306 context:(NSString*)context
307 reply:(void (^)(TPPolicy * _Nullable policy,
308 NSError * _Nullable error))reply;
309
310 - (void)validatePeersWithContainer:(NSString *)container
311 context:(NSString *)context
312 reply:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply;
313
314
315 // TODO: merge this and trustStatusWithContainer
316 - (void)fetchTrustStateWithContainer:(NSString *)container
317 context:(NSString *)context
318 reply:(void (^)(TrustedPeersHelperPeerState* _Nullable selfPeerState,
319 NSArray<TrustedPeersHelperPeer*>* _Nullable trustedPeers,
320 NSError* _Nullable error))reply;
321
322 - (void)setRecoveryKeyWithContainer:(NSString *)container
323 context:(NSString *)context
324 recoveryKey:(NSString *)recoveryKey
325 salt:(NSString *)salt
326 ckksKeys:(NSArray<CKKSKeychainBackedKeySet*> *)ckksKeys
327 reply:(void (^)(NSError* _Nullable error))reply;
328
329 - (void)reportHealthWithContainer:(NSString *)container
330 context:(NSString *)context
331 stateMachineState:(NSString *)state
332 trustState:(NSString *)trustState
333 reply:(void (^)(NSError* _Nullable error))reply;
334
335 - (void)pushHealthInquiryWithContainer:(NSString *)container
336 context:(NSString *)context
337 reply:(void (^)(NSError* _Nullable error))reply;
338
339 - (void)getViewsWithContainer:(NSString *)container
340 context:(NSString *)context
341 inViews:(NSArray<NSString*>*)inViews
342 reply:(void (^)(NSArray<NSString*>* _Nullable, NSError* _Nullable))reply;
343
344 - (void)requestHealthCheckWithContainer:(NSString *)container
345 context:(NSString *)context
346 requiresEscrowCheck:(BOOL)requiresEscrowCheck
347 reply:(void (^)(BOOL postRepairCFU, BOOL postEscrowCFU, BOOL resetOctagon, NSError* _Nullable))reply;
348
349 - (void)getSupportAppInfoWithContainer:(NSString *)container
350 context:(NSString *)context
351 reply:(void (^)(NSData * _Nullable, NSError * _Nullable))reply;
352
353 @end
354
355 /*
356 To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this:
357
358 _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.TrustedPeersHelper"];
359 _connectionToService.remoteObjectInterface = TrustedPeersHelperSetupProtocol([NSXPCInterface interfaceWithProtocol:@protocol(TrustedPeersHelperProtocol)]);
360 [_connectionToService resume];
361
362 Once you have a connection to the service, you can use it like this:
363
364 [[_connectionToService remoteObjectProxy] upperCaseString:@"hello" withReply:^(NSString *aString) {
365 // We have received a response. Update our text field, but do it on the main thread.
366 NSLog(@"Result string was: %@", aString);
367 }];
368
369 And, when you are finished with the service, clean up the connection like this:
370
371 [_connectionToService invalidate];
372 */
373
374
375 // Use this at protocol creation time to tell NSXPC to do its job
376 NSXPCInterface* TrustedPeersHelperSetupProtocol(NSXPCInterface* interface);
377
378 NS_ASSUME_NONNULL_END