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