]> git.saurik.com Git - apple/security.git/blob - keychain/TrustedPeersHelper/Client.swift
Security-59306.61.1.tar.gz
[apple/security.git] / keychain / TrustedPeersHelper / Client.swift
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
25
26 class Client: TrustedPeersHelperProtocol {
27
28 let endpoint: NSXPCListenerEndpoint?
29 let containerMap: ContainerMap
30
31 init(endpoint: NSXPCListenerEndpoint?, containerMap: ContainerMap) {
32 self.endpoint = endpoint
33 self.containerMap = containerMap
34 }
35
36 func ping(reply: @escaping (() -> Void)) {
37 reply()
38 }
39
40 func logComplete(function: String, container: ContainerName, error: Error?) {
41 if let error = error {
42 os_log("%@ errored for %@: %@", log: tplogDebug, type: .default, function, container.description, error as CVarArg)
43 } else {
44 os_log("%@ finished for %@", log: tplogDebug, type: .default, function, container.description)
45 }
46 }
47
48 internal func getContainer(withContainer container: String, context: String) throws -> Container {
49 let containerName = ContainerName(container: container, context: context)
50 return try self.containerMap.findOrCreate(name: containerName)
51 }
52
53 func dump(withContainer container: String, context: String, reply: @escaping ([AnyHashable: Any]?, Error?) -> Void) {
54 do {
55 let containerName = ContainerName(container: container, context: context)
56 os_log("Dumping for %@", log: tplogDebug, type: .default, containerName.description)
57 let container = try self.containerMap.findOrCreate(name: containerName)
58 container.dump { result, error in
59 self.logComplete(function: "Dumping", container: container.name, error: error)
60 reply(result, CKXPCSuitableError(error))
61 }
62 } catch {
63 os_log("Dumping failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
64 reply(nil, CKXPCSuitableError(error))
65 }
66 }
67
68 func dumpEgoPeer(withContainer container: String,
69 context: String,
70 reply: @escaping (String?, TPPeerPermanentInfo?, TPPeerStableInfo?, TPPeerDynamicInfo?, Error?) -> Void) {
71 do {
72 let containerName = ContainerName(container: container, context: context)
73 os_log("Dumping peer for %@", log: tplogDebug, type: .default, containerName.description)
74 let container = try self.containerMap.findOrCreate(name: containerName)
75 container.dumpEgoPeer { peerID, perm, stable, dyn, error in
76 self.logComplete(function: "Dumping peer", container: container.name, error: error)
77 reply(peerID, perm, stable, dyn, CKXPCSuitableError(error))
78 }
79 } catch {
80 os_log("Dumping peer failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
81 reply(nil, nil, nil, nil, CKXPCSuitableError(error))
82 }
83 }
84
85 func trustStatus(withContainer container: String, context: String, reply: @escaping (TrustedPeersHelperEgoPeerStatus, Error?) -> Void) {
86 do {
87 let containerName = ContainerName(container: container, context: context)
88 let container = try self.containerMap.findOrCreate(name: containerName)
89 container.trustStatus(reply: reply)
90 } catch {
91 os_log("Trust status failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
92 reply(TrustedPeersHelperEgoPeerStatus(egoPeerID: nil,
93 status: TPPeerStatus.unknown,
94 viablePeerCountsByModelID: [:],
95 peerCountsByMachineID: [:],
96 isExcluded: false,
97 isLocked: false),
98 CKXPCSuitableError(error))
99 }
100 }
101
102 func fetchTrustState(withContainer container: String, context: String, reply: @escaping (TrustedPeersHelperPeerState?, [TrustedPeersHelperPeer]?, Error?) -> Void) {
103 do {
104 let containerName = ContainerName(container: container, context: context)
105 os_log("Fetch Trust State for %@", log: tplogDebug, type: .default, containerName.description)
106 let container = try self.containerMap.findOrCreate(name: containerName)
107 container.fetchTrustState(reply: reply)
108 } catch {
109 os_log("Fetch Trust State failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
110 reply(nil, nil, CKXPCSuitableError(error))
111 }
112 }
113
114 func reset(withContainer container: String, context: String, resetReason: CuttlefishResetReason, reply: @escaping (Error?) -> Void) {
115 do {
116 let containerName = ContainerName(container: container, context: context)
117 os_log("Resetting for %@", log: tplogDebug, type: .default, containerName.description)
118 let container = try self.containerMap.findOrCreate(name: containerName)
119 container.reset(resetReason: resetReason) { error in
120 self.logComplete(function: "Resetting", container: container.name, error: error)
121 reply(CKXPCSuitableError(error)) }
122 } catch {
123 os_log("Resetting failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
124 reply(CKXPCSuitableError(error))
125 }
126 }
127
128 func localReset(withContainer container: String, context: String, reply: @escaping (Error?) -> Void) {
129 do {
130 let containerName = ContainerName(container: container, context: context)
131 os_log("Performing local reset for %@", log: tplogDebug, type: .default, containerName.description)
132 let container = try self.containerMap.findOrCreate(name: containerName)
133 container.localReset { error in
134 self.logComplete(function: "Local reset", container: container.name, error: error)
135 reply(CKXPCSuitableError(error))
136 }
137 } catch {
138 os_log("Local reset failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
139 reply(CKXPCSuitableError(error))
140 }
141 }
142
143 func setAllowedMachineIDsWithContainer(_ container: String,
144 context: String,
145 allowedMachineIDs: Set<String>,
146 reply: @escaping (Bool, Error?) -> Void) {
147 do {
148 let containerName = ContainerName(container: container, context: context)
149 os_log("Setting allowed machineIDs for %@ to %@", log: tplogDebug, type: .default, containerName.description, allowedMachineIDs)
150 let container = try self.containerMap.findOrCreate(name: containerName)
151 container.setAllowedMachineIDs(allowedMachineIDs) { differences, error in
152 self.logComplete(function: "Setting allowed machineIDs", container: container.name, error: error)
153 reply(differences, CKXPCSuitableError(error))
154 }
155 } catch {
156 os_log("Setting allowed machineIDs failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
157 reply(false, CKXPCSuitableError(error))
158 }
159 }
160
161 func addAllowedMachineIDs(withContainer container: String,
162 context: String,
163 machineIDs: [String],
164 reply: @escaping (Error?) -> Void) {
165 do {
166 let containerName = ContainerName(container: container, context: context)
167 os_log("Adding allowed machineIDs for %@: %@", log: tplogDebug, type: .default, containerName.description, machineIDs)
168 let container = try self.containerMap.findOrCreate(name: containerName)
169 container.addAllow(machineIDs) { error in
170 self.logComplete(function: "Adding allowed machineIDs", container: container.name, error: error)
171 reply(CKXPCSuitableError(error))
172 }
173 } catch {
174 os_log("Adding allowed machineID failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
175 reply(CKXPCSuitableError(error))
176 }
177 }
178
179 func removeAllowedMachineIDs(withContainer container: String,
180 context: String,
181 machineIDs: [String],
182 reply: @escaping (Error?) -> Void) {
183 do {
184 let containerName = ContainerName(container: container, context: context)
185 os_log("Removing allowed machineIDs for %@: %@", log: tplogDebug, type: .default, containerName.description, machineIDs)
186 let container = try self.containerMap.findOrCreate(name: containerName)
187 container.removeAllow(machineIDs) { error in
188 self.logComplete(function: "Removing allowed machineIDs", container: container.name, error: error)
189 reply(CKXPCSuitableError(error))
190 }
191 } catch {
192 os_log("Removing allowed machineID failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
193 reply(CKXPCSuitableError(error))
194 }
195 }
196
197 func fetchAllowedMachineIDs(withContainer container: String, context: String, reply: @escaping (Set<String>?, Error?) -> Void) {
198 do {
199 let containerName = ContainerName(container: container, context: context)
200 os_log("Fetching allowed machineIDs for %@", log: tplogDebug, type: .default, containerName.description)
201 let container = try self.containerMap.findOrCreate(name: containerName)
202 container.fetchAllowedMachineIDs() { mids, error in
203 self.logComplete(function: "Fetched allowed machineIDs", container: container.name, error: error)
204 reply(mids, CKXPCSuitableError(error))
205 }
206 } catch {
207 os_log("Fetching allowed machineIDs failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
208 reply(nil, CKXPCSuitableError(error))
209 }
210 }
211
212 func fetchEgoEpoch(withContainer container: String, context: String, reply: @escaping (UInt64, Error?) -> Void) {
213 do {
214 let containerName = ContainerName(container: container, context: context)
215 os_log("retrieving epoch for %@", log: tplogDebug, type: .default, containerName.description)
216 let container = try self.containerMap.findOrCreate(name: containerName)
217 container.getEgoEpoch { epoch, error in
218 reply(epoch, CKXPCSuitableError(error))
219 }
220 } catch {
221 os_log("Epoch retrieval failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
222 reply(0, CKXPCSuitableError(error))
223 }
224 }
225
226 func prepare(withContainer container: String,
227 context: String,
228 epoch: UInt64,
229 machineID: String,
230 bottleSalt: String,
231 bottleID: String,
232 modelID: String,
233 deviceName: String?,
234 serialNumber: String,
235 osVersion: String,
236 policyVersion: NSNumber?,
237 policySecrets: [String: Data]?,
238 signingPrivKeyPersistentRef: Data?,
239 encPrivKeyPersistentRef: Data?,
240 reply: @escaping (String?, Data?, Data?, Data?, Data?, Error?) -> Void) {
241 do {
242 let containerName = ContainerName(container: container, context: context)
243 os_log("Preparing new identity for %@", log: tplogDebug, type: .default, containerName.description)
244 let container = try self.containerMap.findOrCreate(name: containerName)
245 container.prepare(epoch: epoch,
246 machineID: machineID,
247 bottleSalt: bottleSalt,
248 bottleID: bottleID,
249 modelID: modelID,
250 deviceName: deviceName,
251 serialNumber: serialNumber,
252 osVersion: osVersion,
253 policyVersion: policyVersion?.uint64Value,
254 policySecrets: policySecrets,
255 signingPrivateKeyPersistentRef: signingPrivKeyPersistentRef,
256 encryptionPrivateKeyPersistentRef: encPrivKeyPersistentRef) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in
257 self.logComplete(function: "Prepare", container: container.name, error: error)
258 reply(peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, CKXPCSuitableError(error))
259 }
260 } catch {
261 os_log("Prepare failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
262 reply(nil, nil, nil, nil, nil, CKXPCSuitableError(error))
263 }
264 }
265
266 func establish(withContainer container: String,
267 context: String,
268 ckksKeys: [CKKSKeychainBackedKeySet],
269 tlkShares: [CKKSTLKShare],
270 preapprovedKeys: [Data]?,
271 reply: @escaping (String?, [CKRecord]?, Error?) -> Void) {
272 do {
273 let containerName = ContainerName(container: container, context: context)
274 os_log("Establishing %@", log: tplogDebug, type: .default, containerName.description)
275 let container = try self.containerMap.findOrCreate(name: containerName)
276 container.establish(ckksKeys: ckksKeys,
277 tlkShares: tlkShares,
278 preapprovedKeys: preapprovedKeys) { peerID, keyHierarchyRecords, error in
279 self.logComplete(function: "Establishing", container: container.name, error: error)
280 reply(peerID, keyHierarchyRecords, CKXPCSuitableError(error)) }
281 } catch {
282 os_log("Establishing failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
283 reply(nil, nil, CKXPCSuitableError(error))
284 }
285 }
286
287 func vouch(withContainer container: String,
288 context: String,
289 peerID: String,
290 permanentInfo: Data,
291 permanentInfoSig: Data,
292 stableInfo: Data,
293 stableInfoSig: Data,
294 ckksKeys: [CKKSKeychainBackedKeySet],
295 reply: @escaping (Data?, Data?, Error?) -> Void) {
296 do {
297 let containerName = ContainerName(container: container, context: context)
298 os_log("Vouching %@", log: tplogDebug, type: .default, containerName.description)
299 let container = try self.containerMap.findOrCreate(name: containerName)
300 container.vouch(peerID: peerID,
301 permanentInfo: permanentInfo,
302 permanentInfoSig: permanentInfoSig,
303 stableInfo: stableInfo,
304 stableInfoSig: stableInfoSig,
305 ckksKeys: ckksKeys) { voucher, voucherSig, error in
306 self.logComplete(function: "Vouching", container: container.name, error: error)
307 reply(voucher, voucherSig, CKXPCSuitableError(error)) }
308 } catch {
309 os_log("Vouching failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
310 reply(nil, nil, CKXPCSuitableError(error))
311 }
312 }
313
314 func preflightVouchWithBottle(withContainer container: String,
315 context: String,
316 bottleID: String,
317 reply: @escaping (String?, Error?) -> Void) {
318 do {
319 let containerName = ContainerName(container: container, context: context)
320 os_log("Preflight Vouch With Bottle %@", log: tplogDebug, type: .default, containerName.description)
321 let container = try self.containerMap.findOrCreate(name: containerName)
322 container.preflightVouchWithBottle(bottleID: bottleID) { peerID, error in
323 self.logComplete(function: "Preflight Vouch With Bottle", container: container.name, error: error)
324 reply(peerID, CKXPCSuitableError(error)) }
325 } catch {
326 os_log("Preflighting Vouch With Bottle failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
327 reply(nil, CKXPCSuitableError(error))
328 }
329 }
330
331 func vouchWithBottle(withContainer container: String,
332 context: String,
333 bottleID: String,
334 entropy: Data,
335 bottleSalt: String,
336 tlkShares: [CKKSTLKShare],
337 reply: @escaping (Data?, Data?, Error?) -> Void) {
338 do {
339 let containerName = ContainerName(container: container, context: context)
340 os_log("Vouching With Bottle %@", log: tplogDebug, type: .default, containerName.description)
341 let container = try self.containerMap.findOrCreate(name: containerName)
342 container.vouchWithBottle(bottleID: bottleID, entropy: entropy, bottleSalt: bottleSalt, tlkShares: tlkShares) { voucher, voucherSig, error in
343 self.logComplete(function: "Vouching With Bottle", container: container.name, error: error)
344 reply(voucher, voucherSig, CKXPCSuitableError(error)) }
345 } catch {
346 os_log("Vouching with Bottle failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
347 reply(nil, nil, CKXPCSuitableError(error))
348 }
349 }
350
351 func vouchWithRecoveryKey(withContainer container: String,
352 context: String,
353 recoveryKey: String,
354 salt: String,
355 tlkShares: [CKKSTLKShare],
356 reply: @escaping (Data?, Data?, Error?) -> Void) {
357 do {
358 let containerName = ContainerName(container: container, context: context)
359 os_log("Vouching With Recovery Key %@", log: tplogDebug, type: .default, containerName.description)
360 let container = try self.containerMap.findOrCreate(name: containerName)
361 container.vouchWithRecoveryKey(recoveryKey: recoveryKey, salt: salt, tlkShares: tlkShares) { voucher, voucherSig, error in
362 self.logComplete(function: "Vouching With Recovery Key", container: container.name, error: error)
363 reply(voucher, voucherSig, CKXPCSuitableError(error)) }
364 } catch {
365 os_log("Vouching with Recovery Key failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
366 reply(nil, nil, CKXPCSuitableError(error))
367 }
368 }
369
370 func join(withContainer container: String,
371 context: String,
372 voucherData: Data,
373 voucherSig: Data,
374 ckksKeys: [CKKSKeychainBackedKeySet],
375 tlkShares: [CKKSTLKShare],
376 preapprovedKeys: [Data],
377 reply: @escaping (String?, [CKRecord]?, Error?) -> Void) {
378 do {
379 let containerName = ContainerName(container: container, context: context)
380 os_log("Joining %@", log: tplogDebug, type: .default, containerName.description)
381 let container = try self.containerMap.findOrCreate(name: containerName)
382 container.join(voucherData: voucherData,
383 voucherSig: voucherSig,
384 ckksKeys: ckksKeys,
385 tlkShares: tlkShares,
386 preapprovedKeys: preapprovedKeys) { peerID, keyHierarchyRecords, error in reply(peerID, keyHierarchyRecords, CKXPCSuitableError(error)) }
387 } catch {
388 reply(nil, nil, CKXPCSuitableError(error))
389 }
390 }
391
392 func preflightPreapprovedJoin(withContainer container: String,
393 context: String,
394 reply: @escaping (Bool, Error?) -> Void) {
395 do {
396 let containerName = ContainerName(container: container, context: context)
397 os_log("Attempting to preflight a preapproved join for %@", log: tplogDebug, type: .default, containerName.description)
398 let container = try self.containerMap.findOrCreate(name: containerName)
399 container.preflightPreapprovedJoin { success, error in reply(success, CKXPCSuitableError(error)) }
400 } catch {
401 reply(false, CKXPCSuitableError(error))
402 }
403 }
404
405 func attemptPreapprovedJoin(withContainer container: String,
406 context: String,
407 ckksKeys: [CKKSKeychainBackedKeySet],
408 tlkShares: [CKKSTLKShare],
409 preapprovedKeys: [Data],
410 reply: @escaping (String?, [CKRecord]?, Error?) -> Void) {
411 do {
412 let containerName = ContainerName(container: container, context: context)
413 os_log("Attempting a preapproved join for %@", log: tplogDebug, type: .default, containerName.description)
414 let container = try self.containerMap.findOrCreate(name: containerName)
415 container.preapprovedJoin(ckksKeys: ckksKeys,
416 tlkShares: tlkShares,
417 preapprovedKeys: preapprovedKeys) { peerID, keyHierarchyRecords, error in reply(peerID, keyHierarchyRecords, CKXPCSuitableError(error)) }
418 } catch {
419 reply(nil, nil, CKXPCSuitableError(error))
420 }
421 }
422
423 func update(withContainer container: String,
424 context: String,
425 deviceName: String?,
426 serialNumber: String?,
427 osVersion: String?,
428 policyVersion: NSNumber?,
429 policySecrets: [String: Data]?,
430 reply: @escaping (TrustedPeersHelperPeerState?, Error?) -> Void) {
431 do {
432 let containerName = ContainerName(container: container, context: context)
433 os_log("Updating %@", log: tplogDebug, type: .default, containerName.description)
434 let container = try self.containerMap.findOrCreate(name: containerName)
435 container.update(deviceName: deviceName,
436 serialNumber: serialNumber,
437 osVersion: osVersion,
438 policyVersion: policyVersion?.uint64Value,
439 policySecrets: policySecrets) { state, error in reply(state, CKXPCSuitableError(error)) }
440 } catch {
441 reply(nil, CKXPCSuitableError(error))
442 }
443 }
444
445 func setPreapprovedKeysWithContainer(_ container: String,
446 context: String,
447 preapprovedKeys: [Data],
448 reply: @escaping (Error?) -> Void) {
449 do {
450 let containerName = ContainerName(container: container, context: context)
451 os_log("Updating %@", log: tplogDebug, type: .default, containerName.description)
452 let container = try self.containerMap.findOrCreate(name: containerName)
453 container.set(preapprovedKeys: preapprovedKeys) { error in reply(CKXPCSuitableError(error)) }
454 } catch {
455 reply(CKXPCSuitableError(error))
456 }
457 }
458
459 func updateTLKs(withContainer container: String,
460 context: String,
461 ckksKeys: [CKKSKeychainBackedKeySet],
462 tlkShares: [CKKSTLKShare],
463 reply: @escaping ([CKRecord]?, Error?) -> Void) {
464 do {
465 let containerName = ContainerName(container: container, context: context)
466 os_log("Updating TLKs for %@", log: tplogDebug, type: .default, containerName.description)
467 let container = try self.containerMap.findOrCreate(name: containerName)
468 container.updateTLKs(ckksKeys: ckksKeys,
469 tlkShares: tlkShares,
470 reply: reply)
471 } catch {
472 reply(nil, CKXPCSuitableError(error))
473 }
474 }
475
476 func departByDistrustingSelf(withContainer container: String,
477 context: String,
478 reply: @escaping (Error?) -> Void) {
479 do {
480 let containerName = ContainerName(container: container, context: context)
481 os_log("Departing %@", log: tplogDebug, type: .default, containerName.description)
482 let container = try self.containerMap.findOrCreate(name: containerName)
483 container.departByDistrustingSelf { error in
484 reply(CKXPCSuitableError(error))
485 }
486 } catch {
487 reply(CKXPCSuitableError(error))
488 }
489 }
490
491 func distrustPeerIDs(withContainer container: String,
492 context: String,
493 peerIDs: Set<String>,
494 reply: @escaping (Error?) -> Void) {
495 do {
496 let containerName = ContainerName(container: container, context: context)
497 os_log("Distrusting %@ in %@", log: tplogDebug, type: .default, peerIDs, containerName.description)
498 let container = try self.containerMap.findOrCreate(name: containerName)
499 container.distrust(peerIDs: peerIDs) { error in
500 reply(CKXPCSuitableError(error))
501 }
502 } catch {
503 reply(CKXPCSuitableError(error))
504 }
505 }
506
507 func fetchViableBottles(withContainer container: String, context: String, reply: @escaping ([String]?, [String]?, Error?) -> Void) {
508 do {
509 let containerName = ContainerName(container: container, context: context)
510 os_log("fetchViableBottles in %@", log: tplogDebug, type: .default, containerName.description)
511 let container = try self.containerMap.findOrCreate(name: containerName)
512 container.fetchViableBottles { sortedBottleIDs, partialBottleIDs, error in
513 reply(sortedBottleIDs, partialBottleIDs, CKXPCSuitableError(error))
514 }
515 } catch {
516 reply(nil, nil, CKXPCSuitableError(error))
517 }
518 }
519
520 func fetchEscrowContents(withContainer container: String, context: String, reply: @escaping (Data?, String?, Data?, Error?) -> Void) {
521 do {
522 let containerName = ContainerName(container: container, context: context)
523 os_log("fetchEscrowContents in %@", log: tplogDebug, type: .default, containerName.description)
524 let container = try self.containerMap.findOrCreate(name: containerName)
525 container.fetchEscrowContents { entropy, bottleID, signingPublicKey, error in
526 reply(entropy, bottleID, signingPublicKey, CKXPCSuitableError(error))
527 }
528 } catch {
529 reply(nil, nil, nil, CKXPCSuitableError(error))
530 }
531 }
532
533 func fetchPolicy(withContainer container: String,
534 context: String,
535 reply: @escaping (TPPolicy?, Error?) -> Void) {
536 do {
537 let containerName = ContainerName(container: container, context: context)
538 os_log("Fetching policy for %@", log: tplogDebug, type: .default, containerName.description)
539 let container = try self.containerMap.findOrCreate(name: containerName)
540 container.fetchPolicy { policy, error in
541 reply(policy, CKXPCSuitableError(error))
542 }
543 } catch {
544 reply(nil, CKXPCSuitableError(error))
545 }
546 }
547
548 func fetchPolicyDocuments(withContainer container: String,
549 context: String,
550 keys: [NSNumber: String],
551 reply: @escaping ([NSNumber: [String]]?, Error?) -> Void) {
552 do {
553 let containerName = ContainerName(container: container, context: context)
554 os_log("Fetching policy documents %@ with keys: %@", log: tplogDebug, type: .default, containerName.description, keys)
555 let container = try self.containerMap.findOrCreate(name: containerName)
556 container.fetchPolicyDocuments(keys: keys) { entries, error in
557 reply(entries, CKXPCSuitableError(error))
558 }
559 } catch {
560 reply(nil, CKXPCSuitableError(error))
561 }
562 }
563
564 func validatePeers(withContainer container: String, context: String, reply: @escaping ([AnyHashable: Any]?, Error?) -> Void) {
565 do {
566 let containerName = ContainerName(container: container, context: context)
567 os_log("ValidatePeers for %@", log: tplogDebug, type: .default, containerName.description)
568 let container = try self.containerMap.findOrCreate(name: containerName)
569 let request = ValidatePeersRequest()
570 container.validatePeers(request: request) { result, error in
571 self.logComplete(function: "validatePeers", container: container.name, error: error)
572 reply(result, CKXPCSuitableError(error))
573 }
574 } catch {
575 os_log("ValidatePeers failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
576 reply(nil, CKXPCSuitableError(error))
577 }
578 }
579
580 func setRecoveryKeyWithContainer(_ container: String, context: String, recoveryKey: String, salt: String, ckksKeys: [CKKSKeychainBackedKeySet], reply: @escaping (Error?) -> Void) {
581 do {
582 let containerName = ContainerName(container: container, context: context)
583 os_log("SetRecoveryKey for %@", log: tplogDebug, type: .default, containerName.description)
584 let container = try self.containerMap.findOrCreate(name: containerName)
585 container.setRecoveryKey(recoveryKey: recoveryKey, salt: salt, ckksKeys: ckksKeys) { error in
586 self.logComplete(function: "setRecoveryKey", container: container.name, error: error)
587 reply(CKXPCSuitableError(error))
588 }
589 } catch {
590 os_log("SetRecoveryKey failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
591 reply(CKXPCSuitableError(error))
592 }
593 }
594
595 func reportHealth(withContainer container: String, context: String, stateMachineState: String, trustState: String, reply: @escaping (Error?) -> Void) {
596 do {
597 let containerName = ContainerName(container: container, context: context)
598 os_log("ReportHealth for %@", log: tplogDebug, type: .default, containerName.description)
599 let container = try self.containerMap.findOrCreate(name: containerName)
600 let request = ReportHealthRequest.with {
601 $0.stateMachineState = stateMachineState
602 }
603 container.reportHealth(request: request) { error in
604 self.logComplete(function: "reportHealth", container: container.name, error: error)
605 reply(CKXPCSuitableError(error))
606 }
607 } catch {
608 os_log("ReportHealth failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
609 reply(CKXPCSuitableError(error))
610 }
611 }
612
613 func pushHealthInquiry(withContainer container: String, context: String, reply: @escaping (Error?) -> Void) {
614 do {
615 let containerName = ContainerName(container: container, context: context)
616 os_log("PushHealthInquiry for %@", log: tplogDebug, type: .default, containerName.description)
617 let container = try self.containerMap.findOrCreate(name: containerName)
618 container.pushHealthInquiry { error in
619 self.logComplete(function: "pushHealthInquiry", container: container.name, error: error)
620 reply(CKXPCSuitableError(error))
621 }
622 } catch {
623 os_log("PushHealthInquiry failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
624 reply(CKXPCSuitableError(error))
625 }
626 }
627
628 func getViewsWithContainer(_ container: String, context: String, inViews: [String], reply: @escaping ([String]?, Error?) -> Void) {
629 do {
630 let containerName = ContainerName(container: container, context: context)
631 os_log("GetViews (%@) for %@", log: tplogDebug, type: .default, inViews, containerName.description)
632 let container = try self.containerMap.findOrCreate(name: containerName)
633 container.getViews(inViews: inViews) { outViews, error in
634 reply(outViews, CKXPCSuitableError(error))
635 }
636 } catch {
637 os_log("GetViews failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
638 reply(nil, CKXPCSuitableError(error))
639 }
640 }
641
642 func requestHealthCheck(withContainer container: String, context: String, requiresEscrowCheck: Bool, reply: @escaping (Bool, Bool, Bool, Error?) -> Void) {
643 do {
644 let containerName = ContainerName(container: container, context: context)
645 os_log("Health Check! requiring escrow check? %d for %@", log: tplogDebug, type: .default, requiresEscrowCheck, containerName.description)
646 let container = try self.containerMap.findOrCreate(name: containerName)
647 container.requestHealthCheck(requiresEscrowCheck: requiresEscrowCheck) { postRepair, postEscrow, postReset, error in
648 reply(postRepair, postEscrow, postReset, CKXPCSuitableError(error))
649 }
650 } catch {
651 os_log("Health Check! failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
652 reply(false, false, false, CKXPCSuitableError(error))
653 }
654 }
655
656 func getSupportAppInfo(withContainer container: String, context: String, reply: @escaping (Data?, Error?) -> Void) {
657 do {
658 let containerName = ContainerName(container: container, context: context)
659 os_log("getSupportInfo %d for %@", log: tplogDebug, type: .default, containerName.description)
660 let container = try self.containerMap.findOrCreate(name: containerName)
661 container.getSupportAppInfo { info, error in
662 reply(info, CKXPCSuitableError(error))
663 }
664 } catch {
665 os_log("getSupportInfo failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg)
666 reply(nil, CKXPCSuitableError(error))
667 }
668
669 }
670 }