]> git.saurik.com Git - apple/security.git/blob - keychain/TrustedPeersHelper/Container_EscrowRecords.swift
Security-59754.60.13.tar.gz
[apple/security.git] / keychain / TrustedPeersHelper / Container_EscrowRecords.swift
1 import CoreData
2 import Foundation
3
4 extension Container {
5
6 func onqueueCachedRecordsContainEgoPeerBottle(cachedRecords: [OTEscrowRecord]) -> Bool {
7 guard let egoPeerID = self.containerMO.egoPeerID else {
8 os_log("onqueueCachedRecordsContainEgoPeerBottle: No identity.", log: tplogDebug, type: .default)
9 return false
10 }
11 guard let bottles: Set<BottleMO> = self.containerMO.bottles as? Set<BottleMO> else {
12 os_log("onqueueCachedRecordsContainEgoPeerBottle: No Bottles.", log: tplogDebug, type: .default)
13 return false
14 }
15 var matchesCached: Bool = false
16 for bottle in bottles {
17 guard let bottleID: String = bottle.bottleID else {
18 continue
19 }
20 if bottle.peerID == egoPeerID && (cachedRecords.compactMap { $0.escrowInformationMetadata.bottleId }).contains(bottleID) {
21 matchesCached = true
22 break
23 }
24 }
25 return matchesCached
26 }
27
28 func escrowRecordMOToEscrowRecords(record: EscrowRecordMO, viability: Viability) -> OTEscrowRecord? {
29 let escrowRecord = OTEscrowRecord()
30 let escrowRecordMetadata = OTEscrowRecordMetadata()
31 let clientMetadata = OTEscrowRecordMetadataClientMetadata()
32
33 if let e = escrowRecord {
34 if let creationDate = record.creationDate {
35 e.creationDate = UInt64(creationDate.timeIntervalSince1970)
36 }
37 e.label = record.label ?? ""
38 e.remainingAttempts = UInt64(record.remainingAttempts)
39 e.silentAttemptAllowed = UInt64(record.silentAttemptAllowed)
40 e.recordStatus = record.recordStatus == 0 ? .RECORD_STATUS_VALID : .RECORD_STATUS_INVALID
41
42 switch viability {
43 case .full:
44 e.recordViability = .RECORD_VIABILITY_FULLY_VIABLE
45 case .partial:
46 e.recordViability = .RECORD_VIABILITY_PARTIALLY_VIABLE
47 case .none:
48 e.recordViability = .RECORD_VIABILITY_LEGACY
49 }
50
51 switch record.sosViability {
52 case 0:
53 e.viabilityStatus = .SOS_VIABLE_UNKNOWN
54 case 1:
55 e.viabilityStatus = .SOS_VIABLE
56 case 2:
57 e.viabilityStatus = .SOS_NOT_VIABLE
58 default:
59 e.viabilityStatus = .SOS_VIABLE_UNKNOWN
60 }
61
62 if let metadata = escrowRecordMetadata {
63 if let m = record.escrowMetadata {
64 metadata.backupKeybagDigest = m.backupKeybagDigest ?? Data()
65 if let timestamp = m.secureBackupTimestamp {
66 metadata.secureBackupTimestamp = UInt64(timestamp.timeIntervalSince1970)
67 }
68 metadata.secureBackupUsesMultipleIcscs = UInt64(m.secureBackupUsesMultipleiCSCS)
69 metadata.bottleId = m.bottleID ?? ""
70 metadata.escrowedSpki = m.escrowedSPKI ?? Data()
71 metadata.peerInfo = m.peerInfo ?? Data()
72 metadata.serial = m.serial ?? ""
73 if let cmToFill = clientMetadata {
74 if let cm = m.clientMetadata {
75 cmToFill.deviceMid = cm.deviceMid ?? ""
76 cmToFill.deviceColor = cm.deviceColor ?? ""
77 cmToFill.deviceModel = cm.deviceModel ?? ""
78 cmToFill.deviceName = cm.deviceName ?? ""
79 cmToFill.devicePlatform = UInt64(cm.devicePlatform)
80 cmToFill.deviceModelClass = cm.deviceModelClass ?? ""
81 cmToFill.deviceModelVersion = cm.deviceModelVersion ?? ""
82 cmToFill.deviceEnclosureColor = cm.deviceEnclosureColor ?? ""
83 if let timestamp = cm.secureBackupMetadataTimestamp {
84 cmToFill.secureBackupMetadataTimestamp = UInt64(timestamp.timeIntervalSince1970)
85 }
86 cmToFill.secureBackupUsesComplexPassphrase = UInt64(cm.secureBackupUsesComplexPassphrase)
87 cmToFill.secureBackupUsesNumericPassphrase = UInt64(cm.secureBackupUsesNumericPassphrase)
88 cmToFill.secureBackupNumericPassphraseLength = UInt64(cm.secureBackupNumericPassphraseLength)
89 }
90 }
91 metadata.clientMetadata = clientMetadata
92 }
93 e.escrowInformationMetadata = metadata
94 }
95 }
96
97 return escrowRecord
98 }
99
100 func setEscrowRecord(record: EscrowInformation, viability: Viability) {
101 let escrowRecordMO = EscrowRecordMO(context: self.moc)
102 escrowRecordMO.label = record.label
103 escrowRecordMO.creationDate = record.creationDate.date
104 escrowRecordMO.remainingAttempts = Int64(record.remainingAttempts)
105 escrowRecordMO.silentAttemptAllowed = Int64(record.silentAttemptAllowed)
106 escrowRecordMO.recordStatus = Int64(record.recordStatus.rawValue)
107 escrowRecordMO.sosViability = Int64(record.viabilityStatus.rawValue)
108
109 let escrowRecordMetadataMO = EscrowMetadataMO(context: self.moc)
110 escrowRecordMetadataMO.backupKeybagDigest = record.escrowInformationMetadata.backupKeybagDigest
111 escrowRecordMetadataMO.secureBackupUsesMultipleiCSCS = Int64(record.escrowInformationMetadata.secureBackupUsesMultipleIcscs)
112 escrowRecordMetadataMO.bottleID = record.escrowInformationMetadata.bottleID
113 escrowRecordMetadataMO.secureBackupTimestamp = record.escrowInformationMetadata.secureBackupTimestamp.date
114 escrowRecordMetadataMO.escrowedSPKI = record.escrowInformationMetadata.escrowedSpki
115 escrowRecordMetadataMO.peerInfo = record.escrowInformationMetadata.peerInfo
116 escrowRecordMetadataMO.serial = record.escrowInformationMetadata.serial
117 escrowRecordMO.escrowMetadata = escrowRecordMetadataMO
118
119 let escrowRecordClientMetadataMO = EscrowClientMetadataMO(context: self.moc)
120 escrowRecordClientMetadataMO.secureBackupMetadataTimestamp = record.escrowInformationMetadata.clientMetadata.secureBackupMetadataTimestamp.date
121 escrowRecordClientMetadataMO.secureBackupNumericPassphraseLength = Int64(record.escrowInformationMetadata.clientMetadata.secureBackupNumericPassphraseLength)
122 escrowRecordClientMetadataMO.secureBackupUsesComplexPassphrase = Int64(record.escrowInformationMetadata.clientMetadata.secureBackupUsesComplexPassphrase)
123 escrowRecordClientMetadataMO.secureBackupUsesNumericPassphrase = Int64(record.escrowInformationMetadata.clientMetadata.secureBackupUsesNumericPassphrase)
124 escrowRecordClientMetadataMO.deviceColor = record.escrowInformationMetadata.clientMetadata.deviceColor
125 escrowRecordClientMetadataMO.deviceEnclosureColor = record.escrowInformationMetadata.clientMetadata.deviceEnclosureColor
126 escrowRecordClientMetadataMO.deviceMid = record.escrowInformationMetadata.clientMetadata.deviceMid
127 escrowRecordClientMetadataMO.deviceModel = record.escrowInformationMetadata.clientMetadata.deviceModel
128 escrowRecordClientMetadataMO.deviceModelClass = record.escrowInformationMetadata.clientMetadata.deviceModelClass
129 escrowRecordClientMetadataMO.deviceModelVersion = record.escrowInformationMetadata.clientMetadata.deviceModelVersion
130 escrowRecordClientMetadataMO.deviceName = record.escrowInformationMetadata.clientMetadata.deviceName
131 escrowRecordClientMetadataMO.devicePlatform = Int64(record.escrowInformationMetadata.clientMetadata.devicePlatform)
132
133 escrowRecordMetadataMO.clientMetadata = escrowRecordClientMetadataMO
134
135 os_log("setEscrowRecord saving new escrow record: %@", log: tplogDebug, type: .default, escrowRecordMO)
136 switch viability {
137 case .full:
138 self.containerMO.addToFullyViableEscrowRecords(escrowRecordMO)
139 break
140 case .partial:
141 self.containerMO.addToPartiallyViableEscrowRecords(escrowRecordMO)
142 break
143 case .none:
144 self.containerMO.addToLegacyEscrowRecords(escrowRecordMO)
145 break
146 }
147 }
148
149 func onqueueCachedBottlesFromEscrowRecords() -> (TPCachedViableBottles) {
150 var viableRecords: [String] = []
151 var partiallyViableRecords: [String] = []
152
153 if let fullyViableEscrowRecords = self.containerMO.fullyViableEscrowRecords as? Set<EscrowRecordMO> {
154 viableRecords = fullyViableEscrowRecords.compactMap { $0.escrowMetadata?.bottleID }
155 }
156 if let partiallyViableEscrowRecords = self.containerMO.partiallyViableEscrowRecords as? Set<EscrowRecordMO> {
157 partiallyViableRecords = partiallyViableEscrowRecords.compactMap { $0.escrowMetadata?.bottleID }
158 }
159 return TPCachedViableBottles(viableBottles: viableRecords, partialBottles: partiallyViableRecords)
160 }
161
162 func onqueueCachedEscrowRecords() -> ([OTEscrowRecord]) {
163 var escrowRecords: [OTEscrowRecord] = []
164
165 if let fullyViableEscrowRecords = self.containerMO.fullyViableEscrowRecords as? Set<EscrowRecordMO> {
166 for record in fullyViableEscrowRecords {
167 let convertedRecord = escrowRecordMOToEscrowRecords(record: record, viability: .full)
168 if let r = convertedRecord {
169 escrowRecords.append(r)
170 }
171 }
172 }
173 if let partiallyViableEscrowRecords = self.containerMO.partiallyViableEscrowRecords as? Set<EscrowRecordMO> {
174 for record in partiallyViableEscrowRecords {
175 let convertedRecord = escrowRecordMOToEscrowRecords(record: record, viability: .partial)
176 if let r = convertedRecord {
177 escrowRecords.append(r)
178 }
179 }
180 }
181 if let legacyEscrowRecords = self.containerMO.legacyEscrowRecords as? Set<EscrowRecordMO> {
182 for record in legacyEscrowRecords {
183 let convertedRecord = escrowRecordMOToEscrowRecords(record: record, viability: .none)
184 if let r = convertedRecord {
185 escrowRecords.append(r)
186 }
187 }
188 }
189 return escrowRecords
190 }
191
192 func fetchEscrowRecords(forceFetch: Bool, reply: @escaping ([Data]?, Error?) -> Void) {
193 self.semaphore.wait()
194 let reply: ([Data]?, Error?) -> Void = {
195 os_log("fetchEscrowRecords complete: %@", log: tplogTrace, type: .info, traceError($1))
196 self.semaphore.signal()
197 reply($0, $1)
198 }
199
200 self.fetchEscrowRecordsWithSemaphore(forceFetch: forceFetch, reply: reply)
201 }
202 }