/ keychain / TrustedPeersHelperUnitTests / ContainerSync.swift
ContainerSync.swift
  1  //
  2  //  SessionSync.swift
  3  //  Security_ios
  4  //
  5  //  Created by Ben Williamson on 6/8/18.
  6  //
  7  
  8  import XCTest
  9  
 10  extension Container {
 11      func dumpSync(test: XCTestCase) -> ([AnyHashable: Any]?, Error?) {
 12          let expectation = XCTestExpectation(description: "dump replied")
 13          var reta: [AnyHashable: Any]?, reterr: Error?
 14          self.dump { a, err in
 15              reta = a
 16              reterr = err
 17              expectation.fulfill()
 18          }
 19          test.wait(for: [expectation], timeout: 10.0)
 20          return (reta, reterr)
 21      }
 22  
 23      func resetSync(resetReason: CuttlefishResetReason, test: XCTestCase) -> Error? {
 24          let expectation = XCTestExpectation(description: "reset replied")
 25          var reterr: Error?
 26          self.reset(resetReason: resetReason) { error in
 27              reterr = error
 28              expectation.fulfill()
 29          }
 30          test.wait(for: [expectation], timeout: 10.0)
 31          return reterr
 32      }
 33  
 34      func localResetSync(test: XCTestCase) -> Error? {
 35          let expectation = XCTestExpectation(description: "reset replied")
 36          var reterr: Error?
 37          self.localReset { error in
 38              reterr = error
 39              expectation.fulfill()
 40          }
 41          test.wait(for: [expectation], timeout: 10.0)
 42          return reterr
 43      }
 44  
 45      func prepareSync(test: XCTestCase,
 46                       epoch: UInt64,
 47                       machineID: String,
 48                       bottleSalt: String,
 49                       bottleID: String,
 50                       modelID: String,
 51                       deviceName: String = "test device name",
 52                       serialNumber: String = "456",
 53                       osVersion: String = "123",
 54                       policyVersion: TPPolicyVersion? = nil,
 55                       policySecrets: [String: Data]? = nil,
 56                       syncUserControllableViews: TPPBPeerStableInfo_UserControllableViewStatus = .UNKNOWN,
 57                       signingPrivateKeyPersistentRef: Data? = nil,
 58                       encryptionPrivateKeyPersistentRef: Data? = nil
 59      ) -> (String?, Data?, Data?, Data?, Data?, TPSyncingPolicy?, Error?) {
 60          let expectation = XCTestExpectation(description: "prepare replied")
 61          var reta: String?, retb: Data?, retc: Data?, retd: Data?, rete: Data?, reterr: Error?
 62          var retpolicy: TPSyncingPolicy?
 63          self.prepare(epoch: epoch,
 64                       machineID: machineID,
 65                       bottleSalt: bottleSalt,
 66                       bottleID: bottleID,
 67                       modelID: modelID,
 68                       deviceName: deviceName,
 69                       serialNumber: serialNumber,
 70                       osVersion: osVersion,
 71                       policyVersion: policyVersion,
 72                       policySecrets: policySecrets,
 73                       syncUserControllableViews: syncUserControllableViews,
 74                       signingPrivateKeyPersistentRef: signingPrivateKeyPersistentRef,
 75                       encryptionPrivateKeyPersistentRef: encryptionPrivateKeyPersistentRef
 76          ) { a, b, c, d, e, f, err in
 77              reta = a
 78              retb = b
 79              retc = c
 80              retd = d
 81              rete = e
 82              retpolicy = f
 83              reterr = err
 84              expectation.fulfill()
 85          }
 86          test.wait(for: [expectation], timeout: 10.0)
 87          return (reta, retb, retc, retd, rete, retpolicy, reterr)
 88      }
 89  
 90      func establishSync(test: XCTestCase,
 91                         ckksKeys: [CKKSKeychainBackedKeySet],
 92                         tlkShares: [CKKSTLKShare],
 93                         preapprovedKeys: [Data]?) -> (String?, [CKRecord], TPSyncingPolicy?, Error?) {
 94          let expectation = XCTestExpectation(description: "prepare replied")
 95          var reta: String?, retkhr: [CKRecord]?, reterr: Error?
 96          var retpolicy: TPSyncingPolicy?
 97          self.establish(ckksKeys: ckksKeys,
 98                         tlkShares: tlkShares,
 99                         preapprovedKeys: preapprovedKeys) { a, khr, policy, err in
100                          reta = a
101                          retkhr = khr
102                          retpolicy = policy
103                          reterr = err
104                          expectation.fulfill()
105          }
106          test.wait(for: [expectation], timeout: 10.0)
107          return (reta, retkhr!, retpolicy, reterr)
108      }
109  
110      func vouchSync(test: XCTestCase,
111                     peerID: String,
112                     permanentInfo: Data,
113                     permanentInfoSig: Data,
114                     stableInfo: Data,
115                     stableInfoSig: Data,
116                     ckksKeys: [CKKSKeychainBackedKeySet]) -> (Data?, Data?, Error?) {
117          let expectation = XCTestExpectation(description: "vouch replied")
118          var reta: Data?, retb: Data?, reterr: Error?
119          self.vouch(peerID: peerID,
120                     permanentInfo: permanentInfo,
121                     permanentInfoSig: permanentInfoSig,
122                     stableInfo: stableInfo,
123                     stableInfoSig: stableInfoSig,
124                     ckksKeys: ckksKeys) { a, b, err in
125                      reta = a
126                      retb = b
127                      reterr = err
128                      expectation.fulfill()
129          }
130          test.wait(for: [expectation], timeout: 10.0)
131          return (reta, retb, reterr)
132      }
133  
134      func preflightVouchWithBottleSync(test: XCTestCase, bottleID: String) -> (String?, TPSyncingPolicy?, Bool, Error?) {
135          let expectation = XCTestExpectation(description: "preflightVouchWithBottle replied")
136          var reta: String?, reterr: Error?
137          var retrefetched: Bool = false
138          var retpolicy: TPSyncingPolicy?
139          self.preflightVouchWithBottle(bottleID: bottleID) { a, policy, refetched, err in
140              reta = a
141              retpolicy = policy
142              retrefetched = refetched
143              reterr = err
144              expectation.fulfill()
145          }
146          test.wait(for: [expectation], timeout: 10.0)
147          return (reta, retpolicy, retrefetched, reterr)
148      }
149  
150      func vouchWithBottleSync(test: XCTestCase, b: String, entropy: Data, bottleSalt: String, tlkShares: [CKKSTLKShare]) -> (Data?, Data?, Int64, Int64, Error?) {
151          let expectation = XCTestExpectation(description: "vouchWithBottle replied")
152          var reta: Data?, retb: Data?, retc: Int64 = 0, retd: Int64 = 0, reterr: Error?
153          self.vouchWithBottle(bottleID: b, entropy: entropy, bottleSalt: bottleSalt, tlkShares: tlkShares) { a, b, c, d, err in
154              reta = a
155              retb = b
156              retc = c
157              retd = d
158              reterr = err
159              expectation.fulfill()
160          }
161          test.wait(for: [expectation], timeout: 10.0)
162          return (reta, retb, retc, retd, reterr)
163      }
164  
165      func joinSync(test: XCTestCase,
166                    voucherData: Data,
167                    voucherSig: Data,
168                    ckksKeys: [CKKSKeychainBackedKeySet],
169                    tlkShares: [CKKSTLKShare],
170                    preapprovedKeys: [Data]? = nil) -> (String?, [CKRecord]?, TPSyncingPolicy?, Error?) {
171          let expectation = XCTestExpectation(description: "join replied")
172          var reta: String?, retkhr: [CKRecord]?, reterr: Error?
173          var retpolicy: TPSyncingPolicy?
174          self.join(voucherData: voucherData,
175                    voucherSig: voucherSig,
176                    ckksKeys: ckksKeys,
177                    tlkShares: tlkShares,
178                    preapprovedKeys: preapprovedKeys) { a, khr, policy, err in
179                      reta = a
180                      retkhr = khr
181                      retpolicy = policy
182                      reterr = err
183                      expectation.fulfill()
184          }
185          test.wait(for: [expectation], timeout: 10.0)
186          return (reta, retkhr, retpolicy, reterr)
187      }
188  
189      func preapprovedJoinSync(test: XCTestCase,
190                               ckksKeys: [CKKSKeychainBackedKeySet],
191                               tlkShares: [CKKSTLKShare],
192                               preapprovedKeys: [Data]? = nil) -> (String?, [CKRecord]?, TPSyncingPolicy?, Error?) {
193          let expectation = XCTestExpectation(description: "preapprovedjoin replied")
194          var reta: String?
195          var retkhr: [CKRecord]?
196          var retpolicy: TPSyncingPolicy?
197          var reterr: Error?
198          self.preapprovedJoin(ckksKeys: ckksKeys,
199                               tlkShares: tlkShares,
200                               preapprovedKeys: preapprovedKeys) { a, khr, policy, err in
201                                  reta = a
202                                  retkhr = khr
203                                  retpolicy = policy
204                                  reterr = err
205                                  expectation.fulfill()
206          }
207          test.wait(for: [expectation], timeout: 10.0)
208          return (reta, retkhr, retpolicy, reterr)
209      }
210  
211      func updateSync(test: XCTestCase,
212                      deviceName: String? = nil,
213                      serialNumber: String? = nil,
214                      osVersion: String? = nil,
215                      policyVersion: UInt64? = nil,
216                      policySecrets: [String: Data]? = nil,
217                      syncUserControllableViews: TPPBPeerStableInfo_UserControllableViewStatus? = nil) -> (TrustedPeersHelperPeerState?, TPSyncingPolicy?, Error?) {
218          let expectation = XCTestExpectation(description: "update replied")
219          var reterr: Error?
220          var retstate: TrustedPeersHelperPeerState?
221          var retpolicy: TPSyncingPolicy?
222          self.update(deviceName: deviceName,
223                      serialNumber: serialNumber,
224                      osVersion: osVersion,
225                      policyVersion: policyVersion,
226                      policySecrets: policySecrets,
227                      syncUserControllableViews: syncUserControllableViews) { state, policy, err in
228                          retstate = state
229                          retpolicy = policy
230                          reterr = err
231                          expectation.fulfill()
232          }
233          test.wait(for: [expectation], timeout: 10.0)
234          return (retstate, retpolicy, reterr)
235      }
236  
237      func setAllowedMachineIDsSync(test: XCTestCase, allowedMachineIDs: Set<String>, accountIsDemo: Bool, listDifference: Bool = true) -> (Error?) {
238          let expectation = XCTestExpectation(description: "setAllowedMachineIDs replied")
239          var reterr: Error?
240          let honorIDMSListChanges = accountIsDemo ? false : true
241          self.setAllowedMachineIDs(allowedMachineIDs, honorIDMSListChanges: honorIDMSListChanges) { differences, err in
242              XCTAssertEqual(differences, listDifference, "Reported list difference should match expectation")
243              reterr = err
244              expectation.fulfill()
245          }
246          test.wait(for: [expectation], timeout: 10.0)
247          return reterr
248      }
249  
250      func addAllowedMachineIDsSync(test: XCTestCase, machineIDs: [String]) -> Error? {
251          let expectation = XCTestExpectation(description: "addAllow replied")
252          var reterr: Error?
253          self.addAllow(machineIDs) { err in
254              reterr = err
255              expectation.fulfill()
256          }
257          test.wait(for: [expectation], timeout: 10.0)
258          return reterr
259      }
260  
261      func removeAllowedMachineIDsSync(test: XCTestCase, machineIDs: [String]) -> Error? {
262          let expectation = XCTestExpectation(description: "removeAllow replied")
263          var reterr: Error?
264          self.removeAllow(machineIDs) { err in
265              reterr = err
266              expectation.fulfill()
267          }
268          test.wait(for: [expectation], timeout: 10.0)
269          return reterr
270      }
271  
272      func fetchAllowedMachineIDsSync(test: XCTestCase) -> (Set<String>?, Error?) {
273          let expectation = XCTestExpectation(description: "fetchMIDList replied")
274          var retlist: Set<String>?
275          var reterr: Error?
276          self.fetchAllowedMachineIDs { list, err in
277              retlist = list
278              reterr = err
279              expectation.fulfill()
280          }
281          test.wait(for: [expectation], timeout: 10.0)
282          return (retlist, reterr)
283      }
284  
285      func departByDistrustingSelfSync(test: XCTestCase) -> Error? {
286          let expectation = XCTestExpectation(description: "departByDistrustingSelf replied")
287          var reterr: Error?
288          self.departByDistrustingSelf { error in
289              reterr = error
290              expectation.fulfill()
291          }
292          test.wait(for: [expectation], timeout: 10.0)
293          return reterr
294      }
295  
296      func distrustSync(test: XCTestCase, peerIDs: Set<String>) -> Error? {
297          let expectation = XCTestExpectation(description: "distrustSync replied")
298          var reterr: Error?
299          self.distrust(peerIDs: peerIDs) { error in
300              reterr = error
301              expectation.fulfill()
302          }
303          test.wait(for: [expectation], timeout: 10.0)
304          return reterr
305      }
306  
307      func getStateSync(test: XCTestCase) -> ContainerState {
308          let expectation = XCTestExpectation(description: "getState replied")
309          var retstate: ContainerState?
310          self.getState { state in
311              retstate = state
312              expectation.fulfill()
313          }
314          test.wait(for: [expectation], timeout: 10.0)
315          return retstate!
316      }
317  
318      func loadSecretSync(test: XCTestCase,
319                          label: String) -> (Data?) {
320          var secret: Data?
321          do {
322              secret = try loadSecret(label: label)
323          } catch {
324          }
325          return secret
326      }
327  
328      func setRecoveryKeySync(test: XCTestCase, recoveryKey: String, recoverySalt: String, ckksKeys: [CKKSKeychainBackedKeySet]) -> ([CKRecord]?, Error?) {
329          let expectation = XCTestExpectation(description: "setRecoveryKey replied")
330          var retrecords: [CKRecord]?
331          var reterr: Error?
332  
333          self.setRecoveryKey(recoveryKey: recoveryKey, salt: recoverySalt, ckksKeys: ckksKeys) { records, error in
334              retrecords = records
335              reterr = error
336              expectation.fulfill()
337          }
338          test.wait(for: [expectation], timeout: 10.0)
339          return (retrecords, reterr)
340      }
341  
342      func fetchViableBottlesSync(test: XCTestCase) -> ([String]?, [String]?, Error?) {
343          let expectation = XCTestExpectation(description: "fetchViableBottles replied")
344          var retescrowRecordIDs: [String]?
345          var retpartialEscrowRecordIDs: [String]?
346          var reterror: Error?
347          self.fetchViableBottles { escrowRecordIDs, partialEscrowRecordIDs, error in
348              retescrowRecordIDs = escrowRecordIDs
349              retpartialEscrowRecordIDs = partialEscrowRecordIDs
350              reterror = error
351              expectation.fulfill()
352          }
353          test.wait(for: [expectation], timeout: 10.0)
354          return (retescrowRecordIDs, retpartialEscrowRecordIDs, reterror)
355      }
356  
357      func trustStatusSync(test: XCTestCase) -> (TrustedPeersHelperEgoPeerStatus, Error?) {
358          let expectation = XCTestExpectation(description: "trustStatus replied")
359          var retEgoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: nil,
360                                                             egoPeerMachineID: nil,
361                                                             status: .unknown,
362                                                             viablePeerCountsByModelID: [:],
363                                                             peerCountsByMachineID: [:],
364                                                             isExcluded: false,
365                                                             isLocked: false)
366          var reterror: Error?
367          self.trustStatus { egoStatus, error in
368              retEgoStatus = egoStatus
369              reterror = error
370              expectation.fulfill()
371          }
372          test.wait(for: [expectation], timeout: 10.0)
373          return (retEgoStatus, reterror)
374      }
375  
376      func fetchPolicyDocumentsSync(test: XCTestCase,
377                                    versions: Set<TPPolicyVersion>) -> ([TPPolicyVersion: Data]?, Error?) {
378          let expectation = XCTestExpectation(description: "fetchPolicyDocuments replied")
379          var reta: [TPPolicyVersion: Data]?, reterr: Error?
380          self.fetchPolicyDocuments(versions: versions) { a, err in
381              reta = a
382              reterr = err
383              expectation.fulfill()
384          }
385          test.wait(for: [expectation], timeout: 10.0)
386          return (reta, reterr)
387      }
388  
389      func fetchCurrentPolicySync(test: XCTestCase) -> (TPSyncingPolicy?, TPPBPeerStableInfo_UserControllableViewStatus, Error?) {
390          let expectation = XCTestExpectation(description: "fetchCurrentPolicy replied")
391          var reta: TPSyncingPolicy?, reterr: Error?
392          var retOp: TPPBPeerStableInfo_UserControllableViewStatus = .UNKNOWN
393          self.fetchCurrentPolicy(modelIDOverride: nil) { a, peerOpinion, err in
394              reta = a
395              retOp = peerOpinion
396              reterr = err
397              expectation.fulfill()
398          }
399          test.wait(for: [expectation], timeout: 10.0)
400          return (reta, retOp, reterr)
401      }
402  
403      func fetchEscrowContentsSync(test: XCTestCase) -> (Data?, String?, Data?, Error?) {
404          let expectation = XCTestExpectation(description: "fetchEscrowContents replied")
405          var retentropy: Data?
406          var retbottleID: String?
407          var retspki: Data?
408          var reterror: Error?
409  
410          self.fetchEscrowContents { entropy, bottleID, spki, error in
411              retentropy = entropy
412              retbottleID = bottleID
413              retspki = spki
414              reterror = error
415  
416              expectation.fulfill()
417          }
418          test.wait(for: [expectation], timeout: 10.0)
419          return (retentropy, retbottleID, retspki, reterror)
420      }
421  
422      func requestHealthCheckSync(requiresEscrowCheck: Bool, test: XCTestCase) -> (Bool, Bool, Bool, Bool, Error?) {
423          let expectation = XCTestExpectation(description: "requestHealthCheck replied")
424          var retrepairaccount: Bool = false
425          var retrepairescrow: Bool = false
426          var retresetoctagon: Bool = false
427          var retleavetrust: Bool = false
428          var reterror: Error?
429  
430          self.requestHealthCheck(requiresEscrowCheck: requiresEscrowCheck) { repairAccount, repairEscrow, resetOctagon, leaveTrust, error in
431              retrepairaccount = repairAccount
432              retrepairescrow = repairEscrow
433              retresetoctagon = resetOctagon
434              retleavetrust = leaveTrust
435              reterror = error
436  
437              expectation.fulfill()
438          }
439          test.wait(for: [expectation], timeout: 10.0)
440          return (retrepairaccount, retrepairescrow, retresetoctagon, retleavetrust, reterror)
441      }
442  }