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