3 class OctagonSOSTests: OctagonTestsBase {
5 func testSOSOctagonKeyConsistency() throws {
6 self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID)
7 self.putSelfTLKShares(inCloudKit: self.manateeZoneID)
8 self.saveTLKMaterial(toKeychain: self.manateeZoneID)
10 self.startCKAccountStatusMock()
12 self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle)
14 XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on")
15 self.cuttlefishContext.startOctagonStateMachine()
17 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC)
18 self.assertConsidersSelfTrusted(context: self.cuttlefishContext)
20 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)
22 self.verifyDatabaseMocks()
23 self.waitForCKModifications()
25 self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext)
27 let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID()
28 XCTAssertNotNil(peerID, "Should have a peer ID")
30 // CKKS will upload new TLKShares
31 self.assertAllCKKSViewsUpload(tlkShares: 2)
32 let newSOSPeer = createSOSPeer(peerID: peerID)
33 self.mockSOSAdapter.selfPeer = newSOSPeer
34 self.mockSOSAdapter.trustedPeers.add(newSOSPeer)
36 // Now restart the context
37 self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext)
38 self.restartCKKSViews()
39 self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext)
41 self.cuttlefishContext.startOctagonStateMachine()
42 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC)
44 self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext)
46 let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID()
47 XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting")
49 XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting")
50 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)
52 self.verifyDatabaseMocks()
55 func testSOSOctagonKeyConsistencyLocked() throws {
56 self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID)
57 self.putSelfTLKShares(inCloudKit: self.manateeZoneID)
58 self.saveTLKMaterial(toKeychain: self.manateeZoneID)
60 self.startCKAccountStatusMock()
62 self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle)
64 XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on")
65 self.cuttlefishContext.startOctagonStateMachine()
67 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC)
68 self.assertConsidersSelfTrusted(context: self.cuttlefishContext)
70 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)
72 self.verifyDatabaseMocks()
73 self.waitForCKModifications()
75 self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext)
77 let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID()
78 XCTAssertNotNil(peerID, "Should have a peer ID")
80 let newSOSPeer = createSOSPeer(peerID: peerID)
81 self.mockSOSAdapter.selfPeer = newSOSPeer
83 self.mockSOSAdapter.trustedPeers.add(newSOSPeer)
85 self.aksLockState = true
86 self.lockStateTracker.recheck()
88 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)
90 // Now restart the context
91 self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext)
92 self.restartCKKSViews()
93 self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext)
95 self.cuttlefishContext.startOctagonStateMachine()
97 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC)
98 assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC)
100 self.assertAllCKKSViewsUpload(tlkShares: 2)
101 self.aksLockState = false
102 self.lockStateTracker.recheck()
104 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC)
105 self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext)
107 let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID()
108 XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting")
110 XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting")
112 self.verifyDatabaseMocks()
113 self.waitForCKModifications()
114 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)
117 func testSOSOctagonKeyConsistencySucceedsAfterUpdatingSOS() throws {
118 self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID!)
119 self.putSelfTLKShares(inCloudKit: self.manateeZoneID!)
120 self.saveTLKMaterial(toKeychain: self.manateeZoneID!)
122 self.startCKAccountStatusMock()
124 self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle)
126 XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on")
127 self.cuttlefishContext.startOctagonStateMachine()
129 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC)
130 self.assertConsidersSelfTrusted(context: self.cuttlefishContext)
132 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)
134 self.verifyDatabaseMocks()
135 self.waitForCKModifications()
137 self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext)
139 let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID()
140 XCTAssertNotNil(peerID, "Should have a peer ID")
142 let newSOSPeer = createSOSPeer(peerID: peerID)
143 self.mockSOSAdapter.selfPeer = newSOSPeer
145 self.mockSOSAdapter.trustedPeers.add(newSOSPeer)
147 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC)
148 self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext)
149 self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext)
150 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)
152 // Now restart the context
153 self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext)
154 self.restartCKKSViews()
155 self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext)
157 self.cuttlefishContext.startOctagonStateMachine()
159 self.aksLockState = true
160 self.lockStateTracker.recheck()
162 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC)
163 assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC)
165 self.assertAllCKKSViewsUpload(tlkShares: 2)
166 self.aksLockState = false
167 self.lockStateTracker.recheck()
169 self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC)
170 self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext)
172 let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID()
173 XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting")
175 XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting")
177 self.verifyDatabaseMocks()
178 self.waitForCKModifications()
179 assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC)