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