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