Merge branch 'develop' into feature/attachment_process
This commit is contained in:
commit
ebda12dd76
1
.idea/dictionaries/bmarty.xml
generated
1
.idea/dictionaries/bmarty.xml
generated
@ -22,6 +22,7 @@
|
||||
<w>signin</w>
|
||||
<w>signout</w>
|
||||
<w>signup</w>
|
||||
<w>ssss</w>
|
||||
<w>threepid</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
|
@ -18,7 +18,7 @@ Translations 🗣:
|
||||
-
|
||||
|
||||
SDK API changes ⚠️:
|
||||
-
|
||||
- Get crypto methods through Session.cryptoService()
|
||||
|
||||
Build 🧱:
|
||||
-
|
||||
|
@ -111,22 +111,22 @@ class RxSession(private val session: Session) {
|
||||
}
|
||||
|
||||
fun liveUserCryptoDevices(userId: String): Observable<List<CryptoDeviceInfo>> {
|
||||
return session.getLiveCryptoDeviceInfo(userId).asObservable().startWithCallable {
|
||||
session.getCryptoDeviceInfo(userId)
|
||||
return session.cryptoService().getLiveCryptoDeviceInfo(userId).asObservable().startWithCallable {
|
||||
session.cryptoService().getCryptoDeviceInfo(userId)
|
||||
}
|
||||
}
|
||||
|
||||
fun liveCrossSigningInfo(userId: String): Observable<Optional<MXCrossSigningInfo>> {
|
||||
return session.getCrossSigningService().getLiveCrossSigningKeys(userId).asObservable()
|
||||
return session.cryptoService().crossSigningService().getLiveCrossSigningKeys(userId).asObservable()
|
||||
.startWithCallable {
|
||||
session.getCrossSigningService().getUserCrossSigningKeys(userId).toOptional()
|
||||
session.cryptoService().crossSigningService().getUserCrossSigningKeys(userId).toOptional()
|
||||
}
|
||||
}
|
||||
|
||||
fun liveAccountData(filter: List<String>): Observable<List<UserAccountDataEvent>> {
|
||||
return session.getLiveAccountDataEvents(filter).asObservable()
|
||||
fun liveAccountData(types: Set<String>): Observable<List<UserAccountDataEvent>> {
|
||||
return session.getLiveAccountDataEvents(types).asObservable()
|
||||
.startWithCallable {
|
||||
session.getAccountDataEvents(filter)
|
||||
session.getAccountDataEvents(types)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,9 +230,9 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
|
||||
val aliceRoomId = cryptoTestData.roomId
|
||||
val bobSession = cryptoTestData.secondSession!!
|
||||
|
||||
bobSession.setWarnOnUnknownDevices(false)
|
||||
bobSession.cryptoService().setWarnOnUnknownDevices(false)
|
||||
|
||||
aliceSession.setWarnOnUnknownDevices(false)
|
||||
aliceSession.cryptoService().setWarnOnUnknownDevices(false)
|
||||
|
||||
val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
|
||||
val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
|
||||
|
@ -35,7 +35,7 @@ class XSigningTest : InstrumentedTest {
|
||||
val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
|
||||
|
||||
val aliceLatch = CountDownLatch(1)
|
||||
aliceSession.getCrossSigningService()
|
||||
aliceSession.cryptoService().crossSigningService()
|
||||
.initializeCrossSigning(UserPasswordAuth(
|
||||
user = aliceSession.myUserId,
|
||||
password = TestConstants.PASSWORD
|
||||
@ -43,7 +43,7 @@ class XSigningTest : InstrumentedTest {
|
||||
|
||||
mTestHelper.await(aliceLatch)
|
||||
|
||||
val myCrossSigningKeys = aliceSession.getCrossSigningService().getMyCrossSigningKeys()
|
||||
val myCrossSigningKeys = aliceSession.cryptoService().crossSigningService().getMyCrossSigningKeys()
|
||||
val masterPubKey = myCrossSigningKeys?.masterKey()
|
||||
assertNotNull("Master key should be stored", masterPubKey?.unpaddedBase64PublicKey)
|
||||
val selfSigningKey = myCrossSigningKeys?.selfSigningKey()
|
||||
@ -53,7 +53,7 @@ class XSigningTest : InstrumentedTest {
|
||||
|
||||
assertTrue("Signing Keys should be trusted", myCrossSigningKeys?.isTrusted() == true)
|
||||
|
||||
assertTrue("Signing Keys should be trusted", aliceSession.getCrossSigningService().checkUserTrust(aliceSession.myUserId).isVerified())
|
||||
assertTrue("Signing Keys should be trusted", aliceSession.cryptoService().crossSigningService().checkUserTrust(aliceSession.myUserId).isVerified())
|
||||
|
||||
mTestHelper.signout(aliceSession)
|
||||
}
|
||||
@ -76,23 +76,23 @@ class XSigningTest : InstrumentedTest {
|
||||
|
||||
val latch = CountDownLatch(2)
|
||||
|
||||
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
|
||||
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
|
||||
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
|
||||
bobSession.cryptoService().crossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
|
||||
|
||||
mTestHelper.await(latch)
|
||||
|
||||
// Check that alice can see bob keys
|
||||
val downloadLatch = CountDownLatch(1)
|
||||
aliceSession.downloadKeys(listOf(bobSession.myUserId), true, TestMatrixCallback(downloadLatch))
|
||||
aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true, TestMatrixCallback(downloadLatch))
|
||||
mTestHelper.await(downloadLatch)
|
||||
|
||||
val bobKeysFromAlicePOV = aliceSession.getCrossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
|
||||
val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
|
||||
assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey())
|
||||
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
|
||||
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
|
||||
|
||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
|
||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
|
||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
|
||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
|
||||
|
||||
assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())
|
||||
|
||||
@ -118,22 +118,22 @@ class XSigningTest : InstrumentedTest {
|
||||
|
||||
val latch = CountDownLatch(2)
|
||||
|
||||
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
|
||||
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
|
||||
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
|
||||
bobSession.cryptoService().crossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
|
||||
|
||||
mTestHelper.await(latch)
|
||||
|
||||
// Check that alice can see bob keys
|
||||
val downloadLatch = CountDownLatch(1)
|
||||
val bobUserId = bobSession.myUserId
|
||||
aliceSession.downloadKeys(listOf(bobUserId), true, TestMatrixCallback(downloadLatch))
|
||||
aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true, TestMatrixCallback(downloadLatch))
|
||||
mTestHelper.await(downloadLatch)
|
||||
|
||||
val bobKeysFromAlicePOV = aliceSession.getCrossSigningService().getUserCrossSigningKeys(bobUserId)
|
||||
val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobUserId)
|
||||
assertTrue("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV?.isTrusted() == false)
|
||||
|
||||
val trustLatch = CountDownLatch(1)
|
||||
aliceSession.getCrossSigningService().trustUser(bobUserId, object : MatrixCallback<Unit> {
|
||||
aliceSession.cryptoService().crossSigningService().trustUser(bobUserId, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
trustLatch.countDown()
|
||||
}
|
||||
@ -152,7 +152,7 @@ class XSigningTest : InstrumentedTest {
|
||||
|
||||
// Check that bob first session sees the new login
|
||||
val bobKeysLatch = CountDownLatch(1)
|
||||
bobSession.downloadKeys(listOf(bobUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
bobSession.cryptoService().downloadKeys(listOf(bobUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
fail("Failed to get device")
|
||||
}
|
||||
@ -166,12 +166,12 @@ class XSigningTest : InstrumentedTest {
|
||||
})
|
||||
mTestHelper.await(bobKeysLatch)
|
||||
|
||||
val bobSecondDevicePOVFirstDevice = bobSession.getDeviceInfo(bobUserId, bobSecondDeviceId)
|
||||
val bobSecondDevicePOVFirstDevice = bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId)
|
||||
assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice)
|
||||
|
||||
// Manually mark it as trusted from first session
|
||||
val bobSignLatch = CountDownLatch(1)
|
||||
bobSession.getCrossSigningService().signDevice(bobSecondDeviceId!!, object : MatrixCallback<Unit> {
|
||||
bobSession.cryptoService().crossSigningService().signDevice(bobSecondDeviceId!!, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
bobSignLatch.countDown()
|
||||
}
|
||||
@ -184,7 +184,7 @@ class XSigningTest : InstrumentedTest {
|
||||
|
||||
// Now alice should cross trust bob's second device
|
||||
val aliceKeysLatch = CountDownLatch(1)
|
||||
aliceSession.downloadKeys(listOf(bobUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
fail("Failed to get device")
|
||||
}
|
||||
@ -199,7 +199,7 @@ class XSigningTest : InstrumentedTest {
|
||||
})
|
||||
mTestHelper.await(aliceKeysLatch)
|
||||
|
||||
val result = aliceSession.getCrossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null)
|
||||
val result = aliceSession.cryptoService().crossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null)
|
||||
assertTrue("Bob second device should be trusted from alice POV", result.isCrossSignedVerified())
|
||||
|
||||
mTestHelper.signout(aliceSession)
|
||||
|
@ -77,21 +77,21 @@ class KeysBackupTest : InstrumentedTest {
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
// From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys
|
||||
val cryptoStore = (cryptoTestData.firstSession.getKeysBackupService() as KeysBackup).store
|
||||
val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store
|
||||
val sessions = cryptoStore.inboundGroupSessionsToBackup(100)
|
||||
val sessionsCount = sessions.size
|
||||
|
||||
assertFalse(sessions.isEmpty())
|
||||
assertEquals(sessionsCount, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
|
||||
assertEquals(0, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
|
||||
assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
|
||||
assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
|
||||
|
||||
// - Check backup keys after having marked one as backed up
|
||||
val session = sessions[0]
|
||||
|
||||
cryptoStore.markBackupDoneForInboundGroupSessions(Collections.singletonList(session))
|
||||
|
||||
assertEquals(sessionsCount, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
|
||||
assertEquals(1, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
|
||||
assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
|
||||
assertEquals(1, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
|
||||
|
||||
val sessions2 = cryptoStore.inboundGroupSessionsToBackup(100)
|
||||
assertEquals(sessionsCount - 1, sessions2.size)
|
||||
@ -101,8 +101,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
val sessions3 = cryptoStore.inboundGroupSessionsToBackup(100)
|
||||
assertEquals(sessionsCount, sessions3.size)
|
||||
assertEquals(sessionsCount, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
|
||||
assertEquals(0, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
|
||||
assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
|
||||
assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,9 +112,9 @@ class KeysBackupTest : InstrumentedTest {
|
||||
fun prepareKeysBackupVersionTest() {
|
||||
val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, defaultSessionParams)
|
||||
|
||||
assertNotNull(bobSession.getKeysBackupService())
|
||||
assertNotNull(bobSession.cryptoService().keysBackupService())
|
||||
|
||||
val keysBackup = bobSession.getKeysBackupService()
|
||||
val keysBackup = bobSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -154,7 +154,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
fun createKeysBackupVersionTest() {
|
||||
val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, defaultSessionParams)
|
||||
|
||||
val keysBackup = bobSession.getKeysBackupService()
|
||||
val keysBackup = bobSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -209,12 +209,12 @@ class KeysBackupTest : InstrumentedTest {
|
||||
fun backupAfterCreateKeysBackupVersionTest() {
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val latch = CountDownLatch(1)
|
||||
|
||||
assertEquals(2, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
|
||||
assertEquals(0, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
|
||||
assertEquals(2, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
|
||||
assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
|
||||
|
||||
val stateObserver = StateObserver(keysBackup, latch, 5)
|
||||
|
||||
@ -222,8 +222,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
mTestHelper.await(latch)
|
||||
|
||||
val nbOfKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(false)
|
||||
val backedUpKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(true)
|
||||
val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)
|
||||
val backedUpKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)
|
||||
|
||||
assertEquals(2, nbOfKeys)
|
||||
assertEquals("All keys must have been marked as backed up", nbOfKeys, backedUpKeys)
|
||||
@ -248,14 +248,14 @@ class KeysBackupTest : InstrumentedTest {
|
||||
fun backupAllGroupSessionsTest() {
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
prepareAndCreateKeysBackupData(keysBackup)
|
||||
|
||||
// Check that backupAllGroupSessions returns valid data
|
||||
val nbOfKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(false)
|
||||
val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)
|
||||
|
||||
assertEquals(2, nbOfKeys)
|
||||
|
||||
@ -273,7 +273,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
mTestHelper.await(latch)
|
||||
assertEquals(nbOfKeys, lastBackedUpKeysProgress)
|
||||
|
||||
val backedUpKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(true)
|
||||
val backedUpKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)
|
||||
|
||||
assertEquals("All keys must have been marked as backed up", nbOfKeys, backedUpKeys)
|
||||
|
||||
@ -293,7 +293,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
fun testEncryptAndDecryptKeysBackupData() {
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService() as KeysBackup
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -337,7 +337,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Restore the e2e backup from the homeserver
|
||||
val latch2 = CountDownLatch(1)
|
||||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
||||
null,
|
||||
null,
|
||||
@ -373,7 +373,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
val testData = createKeysBackupScenarioWithPassword(null)
|
||||
|
||||
// - Check the SDK sent key share requests
|
||||
val cryptoStore2 = (testData.aliceSession2.getKeysBackupService() as KeysBackup).store
|
||||
val cryptoStore2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store
|
||||
val unsentRequest = cryptoStore2
|
||||
.getOutgoingRoomKeyRequestByState(setOf(OutgoingRoomKeyRequest.RequestState.UNSENT))
|
||||
val sentRequest = cryptoStore2
|
||||
@ -385,7 +385,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Restore the e2e backup from the homeserver
|
||||
val latch2 = CountDownLatch(1)
|
||||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
||||
null,
|
||||
null,
|
||||
@ -429,17 +429,17 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - And log Alice on a new device
|
||||
val testData = createKeysBackupScenarioWithPassword(null)
|
||||
|
||||
val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
|
||||
val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
|
||||
|
||||
// - The new device must see the previous backup as not trusted
|
||||
assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
|
||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
||||
|
||||
// - Trust the backup from the new device
|
||||
val latch = CountDownLatch(1)
|
||||
testData.aliceSession2.getKeysBackupService().trustKeysBackupVersion(
|
||||
testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersion(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
true,
|
||||
TestMatrixCallback(latch)
|
||||
)
|
||||
@ -449,13 +449,13 @@ class KeysBackupTest : InstrumentedTest {
|
||||
waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
|
||||
|
||||
// - Backup must be enabled on the new device, on the same version
|
||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.getKeysBackupService().keysBackupVersion?.version)
|
||||
assertTrue(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
||||
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
|
||||
// - Retrieve the last version from the server
|
||||
val latch2 = CountDownLatch(1)
|
||||
var keysVersionResult: KeysVersionResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().getCurrentVersion(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(
|
||||
object : TestMatrixCallback<KeysVersionResult?>(latch2) {
|
||||
override fun onSuccess(data: KeysVersionResult?) {
|
||||
keysVersionResult = data
|
||||
@ -470,7 +470,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
val latch3 = CountDownLatch(1)
|
||||
var keysBackupVersionTrust: KeysBackupVersionTrust? = null
|
||||
testData.aliceSession2.getKeysBackupService().getKeysBackupTrust(keysVersionResult!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult!!,
|
||||
object : TestMatrixCallback<KeysBackupVersionTrust>(latch3) {
|
||||
override fun onSuccess(data: KeysBackupVersionTrust) {
|
||||
keysBackupVersionTrust = data
|
||||
@ -503,17 +503,17 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - And log Alice on a new device
|
||||
val testData = createKeysBackupScenarioWithPassword(null)
|
||||
|
||||
val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
|
||||
val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
|
||||
|
||||
// - The new device must see the previous backup as not trusted
|
||||
assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
|
||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
||||
|
||||
// - Trust the backup from the new device with the recovery key
|
||||
val latch = CountDownLatch(1)
|
||||
testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithRecoveryKey(
|
||||
testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
||||
TestMatrixCallback(latch)
|
||||
)
|
||||
@ -523,13 +523,13 @@ class KeysBackupTest : InstrumentedTest {
|
||||
waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
|
||||
|
||||
// - Backup must be enabled on the new device, on the same version
|
||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.getKeysBackupService().keysBackupVersion?.version)
|
||||
assertTrue(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
||||
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
|
||||
// - Retrieve the last version from the server
|
||||
val latch2 = CountDownLatch(1)
|
||||
var keysVersionResult: KeysVersionResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().getCurrentVersion(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(
|
||||
object : TestMatrixCallback<KeysVersionResult?>(latch2) {
|
||||
override fun onSuccess(data: KeysVersionResult?) {
|
||||
keysVersionResult = data
|
||||
@ -544,7 +544,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
val latch3 = CountDownLatch(1)
|
||||
var keysBackupVersionTrust: KeysBackupVersionTrust? = null
|
||||
testData.aliceSession2.getKeysBackupService().getKeysBackupTrust(keysVersionResult!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult!!,
|
||||
object : TestMatrixCallback<KeysBackupVersionTrust>(latch3) {
|
||||
override fun onSuccess(data: KeysBackupVersionTrust) {
|
||||
keysBackupVersionTrust = data
|
||||
@ -575,26 +575,26 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - And log Alice on a new device
|
||||
val testData = createKeysBackupScenarioWithPassword(null)
|
||||
|
||||
val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
|
||||
val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
|
||||
|
||||
// - The new device must see the previous backup as not trusted
|
||||
assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
|
||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
||||
|
||||
// - Try to trust the backup from the new device with a wrong recovery key
|
||||
val latch = CountDownLatch(1)
|
||||
testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithRecoveryKey(
|
||||
testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
"Bad recovery key",
|
||||
TestMatrixCallback(latch, false)
|
||||
)
|
||||
mTestHelper.await(latch)
|
||||
|
||||
// - The new device must still see the previous backup as not trusted
|
||||
assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
|
||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
||||
|
||||
stateObserver.stopAndCheckStates(null)
|
||||
testData.cryptoTestData.close()
|
||||
@ -618,17 +618,17 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - And log Alice on a new device
|
||||
val testData = createKeysBackupScenarioWithPassword(password)
|
||||
|
||||
val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
|
||||
val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
|
||||
|
||||
// - The new device must see the previous backup as not trusted
|
||||
assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
|
||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
||||
|
||||
// - Trust the backup from the new device with the password
|
||||
val latch = CountDownLatch(1)
|
||||
testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithPassphrase(
|
||||
testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithPassphrase(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
password,
|
||||
TestMatrixCallback(latch)
|
||||
)
|
||||
@ -638,13 +638,13 @@ class KeysBackupTest : InstrumentedTest {
|
||||
waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
|
||||
|
||||
// - Backup must be enabled on the new device, on the same version
|
||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.getKeysBackupService().keysBackupVersion?.version)
|
||||
assertTrue(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
||||
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
|
||||
// - Retrieve the last version from the server
|
||||
val latch2 = CountDownLatch(1)
|
||||
var keysVersionResult: KeysVersionResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().getCurrentVersion(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(
|
||||
object : TestMatrixCallback<KeysVersionResult?>(latch2) {
|
||||
override fun onSuccess(data: KeysVersionResult?) {
|
||||
keysVersionResult = data
|
||||
@ -659,7 +659,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
val latch3 = CountDownLatch(1)
|
||||
var keysBackupVersionTrust: KeysBackupVersionTrust? = null
|
||||
testData.aliceSession2.getKeysBackupService().getKeysBackupTrust(keysVersionResult!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult!!,
|
||||
object : TestMatrixCallback<KeysBackupVersionTrust>(latch3) {
|
||||
override fun onSuccess(data: KeysBackupVersionTrust) {
|
||||
keysBackupVersionTrust = data
|
||||
@ -693,26 +693,26 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - And log Alice on a new device
|
||||
val testData = createKeysBackupScenarioWithPassword(password)
|
||||
|
||||
val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
|
||||
val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
|
||||
|
||||
// - The new device must see the previous backup as not trusted
|
||||
assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
|
||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
||||
|
||||
// - Try to trust the backup from the new device with a wrong password
|
||||
val latch = CountDownLatch(1)
|
||||
testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithPassphrase(
|
||||
testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithPassphrase(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
badPassword,
|
||||
TestMatrixCallback(latch, false)
|
||||
)
|
||||
mTestHelper.await(latch)
|
||||
|
||||
// - The new device must still see the previous backup as not trusted
|
||||
assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
|
||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
||||
|
||||
stateObserver.stopAndCheckStates(null)
|
||||
testData.cryptoTestData.close()
|
||||
@ -731,7 +731,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Try to restore the e2e backup with a wrong recovery key
|
||||
val latch2 = CountDownLatch(1)
|
||||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
"EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d",
|
||||
null,
|
||||
null,
|
||||
@ -768,7 +768,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
val steps = ArrayList<StepProgressListener.Step>()
|
||||
|
||||
testData.aliceSession2.getKeysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
password,
|
||||
null,
|
||||
null,
|
||||
@ -828,7 +828,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Try to restore the e2e backup with a wrong password
|
||||
val latch2 = CountDownLatch(1)
|
||||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
wrongPassword,
|
||||
null,
|
||||
null,
|
||||
@ -863,7 +863,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Restore the e2e backup with the recovery key.
|
||||
val latch2 = CountDownLatch(1)
|
||||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
||||
null,
|
||||
null,
|
||||
@ -895,7 +895,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Try to restore the e2e backup with a password
|
||||
val latch2 = CountDownLatch(1)
|
||||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
testData.aliceSession2.getKeysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
"password",
|
||||
null,
|
||||
null,
|
||||
@ -924,7 +924,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Create a backup version
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -967,7 +967,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
val signature = keysBackupVersionTrust!!.signatures[0]
|
||||
assertTrue(signature.valid)
|
||||
assertNotNull(signature.device)
|
||||
assertEquals(cryptoTestData.firstSession.getMyDevice().deviceId, signature.deviceId)
|
||||
assertEquals(cryptoTestData.firstSession.cryptoService().getMyDevice().deviceId, signature.deviceId)
|
||||
assertEquals(signature.device!!.deviceId, cryptoTestData.firstSession.sessionParams.credentials.deviceId)
|
||||
|
||||
stateObserver.stopAndCheckStates(null)
|
||||
@ -986,7 +986,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Create a backup version
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -1002,7 +1002,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
cryptoTestData.close()
|
||||
|
||||
val keysBackup2 = aliceSession2.getKeysBackupService()
|
||||
val keysBackup2 = aliceSession2.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver2 = StateObserver(keysBackup2)
|
||||
|
||||
@ -1046,7 +1046,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Create a backup version
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -1082,11 +1082,11 @@ class KeysBackupTest : InstrumentedTest {
|
||||
val latch = CountDownLatch(1)
|
||||
|
||||
val megolmBackupCreationInfo = mCryptoTestHelper.createFakeMegolmBackupCreationInfo()
|
||||
(keysBackup as KeysBackup).createFakeKeysBackupVersion(megolmBackupCreationInfo, TestMatrixCallback(latch))
|
||||
(keysBackup as DefaultKeysBackupService).createFakeKeysBackupVersion(megolmBackupCreationInfo, TestMatrixCallback(latch))
|
||||
mTestHelper.await(latch)
|
||||
|
||||
// Reset the store backup status for keys
|
||||
(cryptoTestData.firstSession.getKeysBackupService() as KeysBackup).store.resetBackupMarkers()
|
||||
(cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store.resetBackupMarkers()
|
||||
|
||||
// - Make alice back up all her keys again
|
||||
val latch2 = CountDownLatch(1)
|
||||
@ -1121,7 +1121,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Create a backup version
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -1147,14 +1147,14 @@ class KeysBackupTest : InstrumentedTest {
|
||||
val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, defaultSessionParamsWithInitialSync)
|
||||
|
||||
// - Post a message to have a new megolm session
|
||||
aliceSession2.setWarnOnUnknownDevices(false)
|
||||
aliceSession2.cryptoService().setWarnOnUnknownDevices(false)
|
||||
|
||||
val room2 = aliceSession2.getRoom(cryptoTestData.roomId)!!
|
||||
|
||||
mTestHelper.sendTextMessage(room2, "New key", 1)
|
||||
|
||||
// - Try to backup all in aliceSession2, it must fail
|
||||
val keysBackup2 = aliceSession2.getKeysBackupService()
|
||||
val keysBackup2 = aliceSession2.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver2 = StateObserver(keysBackup2)
|
||||
|
||||
@ -1178,7 +1178,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
assertFalse(keysBackup2.isEnabled)
|
||||
|
||||
// - Validate the old device from the new one
|
||||
aliceSession2.setDeviceVerification(DeviceTrustLevel(false, true), aliceSession2.myUserId, oldDeviceId)
|
||||
aliceSession2.cryptoService().setDeviceVerification(DeviceTrustLevel(false, true), aliceSession2.myUserId, oldDeviceId)
|
||||
|
||||
// -> Backup should automatically enable on the new device
|
||||
val latch4 = CountDownLatch(1)
|
||||
@ -1196,14 +1196,14 @@ class KeysBackupTest : InstrumentedTest {
|
||||
mTestHelper.await(latch4)
|
||||
|
||||
// -> It must use the same backup version
|
||||
assertEquals(oldKeyBackupVersion, aliceSession2.getKeysBackupService().currentBackupVersion)
|
||||
assertEquals(oldKeyBackupVersion, aliceSession2.cryptoService().keysBackupService().currentBackupVersion)
|
||||
|
||||
val latch5 = CountDownLatch(1)
|
||||
aliceSession2.getKeysBackupService().backupAllGroupSessions(null, TestMatrixCallback(latch5))
|
||||
aliceSession2.cryptoService().keysBackupService().backupAllGroupSessions(null, TestMatrixCallback(latch5))
|
||||
mTestHelper.await(latch5)
|
||||
|
||||
// -> It must success
|
||||
assertTrue(aliceSession2.getKeysBackupService().isEnabled)
|
||||
assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled)
|
||||
|
||||
stateObserver.stopAndCheckStates(null)
|
||||
stateObserver2.stopAndCheckStates(null)
|
||||
@ -1220,7 +1220,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
// - Create a backup version
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -1254,17 +1254,17 @@ class KeysBackupTest : InstrumentedTest {
|
||||
*/
|
||||
private fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) {
|
||||
// If already in the wanted state, return
|
||||
if (session.getKeysBackupService().state == state) {
|
||||
if (session.cryptoService().keysBackupService().state == state) {
|
||||
return
|
||||
}
|
||||
|
||||
// Else observe state changes
|
||||
val latch = CountDownLatch(1)
|
||||
|
||||
session.getKeysBackupService().addListener(object : KeysBackupStateListener {
|
||||
session.cryptoService().keysBackupService().addListener(object : KeysBackupStateListener {
|
||||
override fun onStateChange(newState: KeysBackupState) {
|
||||
if (newState == state) {
|
||||
session.getKeysBackupService().removeListener(this)
|
||||
session.cryptoService().keysBackupService().removeListener(this)
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
@ -1359,8 +1359,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||
private fun createKeysBackupScenarioWithPassword(password: String?): KeysBackupScenarioData {
|
||||
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
|
||||
|
||||
val cryptoStore = (cryptoTestData.firstSession.getKeysBackupService() as KeysBackup).store
|
||||
val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
|
||||
val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store
|
||||
val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
|
||||
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
@ -1394,7 +1394,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, defaultSessionParamsWithInitialSync)
|
||||
|
||||
// Test check: aliceSession2 has no keys at login
|
||||
assertEquals(0, aliceSession2.inboundGroupSessionsCount(false))
|
||||
assertEquals(0, aliceSession2.cryptoService().inboundGroupSessionsCount(false))
|
||||
|
||||
// Wait for backup state to be NotTrusted
|
||||
waitForKeysBackupToBeInState(aliceSession2, KeysBackupState.NotTrusted)
|
||||
@ -1421,11 +1421,11 @@ class KeysBackupTest : InstrumentedTest {
|
||||
assertEquals(total, imported)
|
||||
|
||||
// - The new device must have the same count of megolm keys
|
||||
assertEquals(testData.aliceKeys.size, testData.aliceSession2.inboundGroupSessionsCount(false))
|
||||
assertEquals(testData.aliceKeys.size, testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false))
|
||||
|
||||
// - Alice must have the same keys on both devices
|
||||
for (aliceKey1 in testData.aliceKeys) {
|
||||
val aliceKey2 = (testData.aliceSession2.getKeysBackupService() as KeysBackup).store
|
||||
val aliceKey2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store
|
||||
.getInboundGroupSession(aliceKey1.olmInboundGroupSession!!.sessionIdentifier(), aliceKey1.senderKey!!)
|
||||
assertNotNull(aliceKey2)
|
||||
assertKeysEquals(aliceKey1.exportKeys(), aliceKey2!!.exportKeys())
|
||||
|
@ -25,24 +25,26 @@ import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.securestorage.Curve25519AesSha2KeySpec
|
||||
import im.vector.matrix.android.api.session.securestorage.EncryptedSecretContent
|
||||
import im.vector.matrix.android.api.session.securestorage.KeySigner
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.SecretStorageKeyContent
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
|
||||
import im.vector.matrix.android.api.util.Optional
|
||||
import im.vector.matrix.android.common.CommonTestHelper
|
||||
import im.vector.matrix.android.common.CryptoTestHelper
|
||||
import im.vector.matrix.android.common.SessionTestParams
|
||||
import im.vector.matrix.android.common.TestConstants
|
||||
import im.vector.matrix.android.common.TestMatrixCallback
|
||||
import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
|
||||
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService
|
||||
import im.vector.matrix.android.internal.crypto.tools.withOlmDecryption
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.fail
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -50,54 +52,38 @@ import org.junit.runners.MethodSorters
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
class QuadSTests : InstrumentedTest {
|
||||
|
||||
private val mTestHelper = CommonTestHelper(context())
|
||||
private val mCryptoTestHelper = CryptoTestHelper(mTestHelper)
|
||||
|
||||
private val emptyKeySigner = object : KeySigner {
|
||||
override fun sign(canonicalJson: String): Map<String, Map<String, String>>? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_Generate4SKey() {
|
||||
val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
|
||||
|
||||
val aliceLatch = CountDownLatch(1)
|
||||
|
||||
val quadS = aliceSession.sharedSecretStorageService
|
||||
|
||||
val emptyKeySigner = object : KeySigner {
|
||||
override fun sign(canonicalJson: String): Map<String, Map<String, String>>? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
var recoveryKey: String? = null
|
||||
|
||||
val TEST_KEY_ID = "my.test.Key"
|
||||
|
||||
quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner,
|
||||
object : MatrixCallback<SsssKeyCreationInfo> {
|
||||
override fun onSuccess(data: SsssKeyCreationInfo) {
|
||||
recoveryKey = data.recoveryKey
|
||||
aliceLatch.countDown()
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Assert.fail("onFailure " + failure.localizedMessage)
|
||||
aliceLatch.countDown()
|
||||
}
|
||||
})
|
||||
|
||||
mTestHelper.await(aliceLatch)
|
||||
val ssssKeyCreationInfo = mTestHelper.doSync<SsssKeyCreationInfo> {
|
||||
quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner, it)
|
||||
}
|
||||
|
||||
// Assert Account data is updated
|
||||
val accountDataLock = CountDownLatch(1)
|
||||
var accountData: UserAccountDataEvent? = null
|
||||
|
||||
val liveAccountData = runBlocking(Dispatchers.Main) {
|
||||
aliceSession.getLiveAccountDataEvent("m.secret_storage.key.$TEST_KEY_ID")
|
||||
aliceSession.getLiveAccountDataEvent("${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID")
|
||||
}
|
||||
val accountDataObserver = Observer<Optional<UserAccountDataEvent>?> { t ->
|
||||
if (t?.getOrNull()?.type == "m.secret_storage.key.$TEST_KEY_ID") {
|
||||
if (t?.getOrNull()?.type == "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID") {
|
||||
accountData = t.getOrNull()
|
||||
accountDataLock.countDown()
|
||||
}
|
||||
@ -106,19 +92,19 @@ class QuadSTests : InstrumentedTest {
|
||||
|
||||
mTestHelper.await(accountDataLock)
|
||||
|
||||
Assert.assertNotNull("Key should be stored in account data", accountData)
|
||||
assertNotNull("Key should be stored in account data", accountData)
|
||||
val parsed = SecretStorageKeyContent.fromJson(accountData!!.content)
|
||||
Assert.assertNotNull("Key Content cannot be parsed", parsed)
|
||||
Assert.assertEquals("Unexpected Algorithm", SSSS_ALGORITHM_CURVE25519_AES_SHA2, parsed!!.algorithm)
|
||||
Assert.assertEquals("Unexpected key name", "Test Key", parsed.name)
|
||||
Assert.assertNull("Key was not generated from passphrase", parsed.passphrase)
|
||||
Assert.assertNotNull("Pubkey should be defined", parsed.publicKey)
|
||||
assertNotNull("Key Content cannot be parsed", parsed)
|
||||
assertEquals("Unexpected Algorithm", SSSS_ALGORITHM_CURVE25519_AES_SHA2, parsed!!.algorithm)
|
||||
assertEquals("Unexpected key name", "Test Key", parsed.name)
|
||||
assertNull("Key was not generated from passphrase", parsed.passphrase)
|
||||
assertNotNull("Pubkey should be defined", parsed.publicKey)
|
||||
|
||||
val privateKeySpec = Curve25519AesSha2KeySpec.fromRecoveryKey(recoveryKey!!)
|
||||
DefaultSharedSecretStorageService.withOlmDecryption { olmPkDecryption ->
|
||||
val pubKey = olmPkDecryption.setPrivateKey(privateKeySpec!!.privateKey)
|
||||
Assert.assertEquals("Unexpected Public Key", pubKey, parsed.publicKey)
|
||||
val privateKeySpec = Curve25519AesSha2KeySpec.fromRecoveryKey(ssssKeyCreationInfo.recoveryKey)
|
||||
val pubKey = withOlmDecryption { olmPkDecryption ->
|
||||
olmPkDecryption.setPrivateKey(privateKeySpec!!.privateKey)
|
||||
}
|
||||
assertEquals("Unexpected Public Key", pubKey, parsed.publicKey)
|
||||
|
||||
// Set as default key
|
||||
quadS.setDefaultKey(TEST_KEY_ID, object : MatrixCallback<Unit> {})
|
||||
@ -139,8 +125,8 @@ class QuadSTests : InstrumentedTest {
|
||||
|
||||
mTestHelper.await(defaultDataLock)
|
||||
|
||||
Assert.assertNotNull(defaultKeyAccountData?.content)
|
||||
Assert.assertEquals("Unexpected default key ${defaultKeyAccountData?.content}", TEST_KEY_ID, defaultKeyAccountData?.content?.get("key"))
|
||||
assertNotNull(defaultKeyAccountData?.content)
|
||||
assertEquals("Unexpected default key ${defaultKeyAccountData?.content}", TEST_KEY_ID, defaultKeyAccountData?.content?.get("key"))
|
||||
|
||||
mTestHelper.signout(aliceSession)
|
||||
}
|
||||
@ -152,52 +138,40 @@ class QuadSTests : InstrumentedTest {
|
||||
val info = generatedSecret(aliceSession, keyId, true)
|
||||
|
||||
// Store a secret
|
||||
|
||||
val storeCountDownLatch = CountDownLatch(1)
|
||||
val clearSecret = Base64.encodeToString("42".toByteArray(), Base64.NO_PADDING or Base64.NO_WRAP)
|
||||
aliceSession.sharedSecretStorageService.storeSecret(
|
||||
"secret.of.life",
|
||||
clearSecret,
|
||||
null, // default key
|
||||
TestMatrixCallback(storeCountDownLatch)
|
||||
)
|
||||
mTestHelper.doSync<Unit> {
|
||||
aliceSession.sharedSecretStorageService.storeSecret(
|
||||
"secret.of.life",
|
||||
clearSecret,
|
||||
null, // default key
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
val secretAccountData = assertAccountData(aliceSession, "secret.of.life")
|
||||
|
||||
val encryptedContent = secretAccountData.content.get("encrypted") as? Map<*, *>
|
||||
Assert.assertNotNull("Element should be encrypted", encryptedContent)
|
||||
Assert.assertNotNull("Secret should be encrypted with default key", encryptedContent?.get(keyId))
|
||||
assertNotNull("Element should be encrypted", encryptedContent)
|
||||
assertNotNull("Secret should be encrypted with default key", encryptedContent?.get(keyId))
|
||||
|
||||
val secret = EncryptedSecretContent.fromJson(encryptedContent?.get(keyId))
|
||||
Assert.assertNotNull(secret?.ciphertext)
|
||||
Assert.assertNotNull(secret?.mac)
|
||||
Assert.assertNotNull(secret?.ephemeral)
|
||||
assertNotNull(secret?.ciphertext)
|
||||
assertNotNull(secret?.mac)
|
||||
assertNotNull(secret?.ephemeral)
|
||||
|
||||
// Try to decrypt??
|
||||
|
||||
val keySpec = Curve25519AesSha2KeySpec.fromRecoveryKey(info.recoveryKey)
|
||||
|
||||
var decryptedSecret: String? = null
|
||||
val decryptedSecret = mTestHelper.doSync<String> {
|
||||
aliceSession.sharedSecretStorageService.getSecret("secret.of.life",
|
||||
null, // default key
|
||||
keySpec!!,
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
val decryptCountDownLatch = CountDownLatch(1)
|
||||
aliceSession.sharedSecretStorageService.getSecret("secret.of.life",
|
||||
null, // default key
|
||||
keySpec!!,
|
||||
object : MatrixCallback<String> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
fail("Fail to decrypt -> " + failure.localizedMessage)
|
||||
decryptCountDownLatch.countDown()
|
||||
}
|
||||
|
||||
override fun onSuccess(data: String) {
|
||||
decryptedSecret = data
|
||||
decryptCountDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
)
|
||||
mTestHelper.await(decryptCountDownLatch)
|
||||
|
||||
Assert.assertEquals("Secret mismatch", clearSecret, decryptedSecret)
|
||||
assertEquals("Secret mismatch", clearSecret, decryptedSecret)
|
||||
mTestHelper.signout(aliceSession)
|
||||
}
|
||||
|
||||
@ -207,24 +181,16 @@ class QuadSTests : InstrumentedTest {
|
||||
|
||||
val quadS = aliceSession.sharedSecretStorageService
|
||||
|
||||
val emptyKeySigner = object : KeySigner {
|
||||
override fun sign(canonicalJson: String): Map<String, Map<String, String>>? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
val TEST_KEY_ID = "my.test.Key"
|
||||
|
||||
val countDownLatch = CountDownLatch(1)
|
||||
quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner,
|
||||
TestMatrixCallback(countDownLatch))
|
||||
|
||||
mTestHelper.await(countDownLatch)
|
||||
mTestHelper.doSync<SsssKeyCreationInfo> {
|
||||
quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner, it)
|
||||
}
|
||||
|
||||
// Test that we don't need to wait for an account data sync to access directly the keyid from DB
|
||||
val defaultLatch = CountDownLatch(1)
|
||||
quadS.setDefaultKey(TEST_KEY_ID, TestMatrixCallback(defaultLatch))
|
||||
mTestHelper.await(defaultLatch)
|
||||
mTestHelper.doSync<Unit> {
|
||||
quadS.setDefaultKey(TEST_KEY_ID, it)
|
||||
}
|
||||
|
||||
mTestHelper.signout(aliceSession)
|
||||
}
|
||||
@ -239,38 +205,39 @@ class QuadSTests : InstrumentedTest {
|
||||
|
||||
val mySecretText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
|
||||
|
||||
val storeLatch = CountDownLatch(1)
|
||||
aliceSession.sharedSecretStorageService.storeSecret(
|
||||
"my.secret",
|
||||
mySecretText.toByteArray().toBase64NoPadding(),
|
||||
listOf(keyId1, keyId2),
|
||||
TestMatrixCallback(storeLatch)
|
||||
)
|
||||
mTestHelper.await(storeLatch)
|
||||
mTestHelper.doSync<Unit> {
|
||||
aliceSession.sharedSecretStorageService.storeSecret(
|
||||
"my.secret",
|
||||
mySecretText.toByteArray().toBase64NoPadding(),
|
||||
listOf(keyId1, keyId2),
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
val accountDataEvent = aliceSession.getAccountDataEvent("my.secret")
|
||||
val encryptedContent = accountDataEvent?.content?.get("encrypted") as? Map<*, *>
|
||||
|
||||
Assert.assertEquals("Content should contains two encryptions", 2, encryptedContent?.keys?.size ?: 0)
|
||||
assertEquals("Content should contains two encryptions", 2, encryptedContent?.keys?.size ?: 0)
|
||||
|
||||
Assert.assertNotNull(encryptedContent?.get(keyId1))
|
||||
Assert.assertNotNull(encryptedContent?.get(keyId2))
|
||||
assertNotNull(encryptedContent?.get(keyId1))
|
||||
assertNotNull(encryptedContent?.get(keyId2))
|
||||
|
||||
// Assert that can decrypt with both keys
|
||||
val decryptCountDownLatch = CountDownLatch(2)
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId1,
|
||||
Curve25519AesSha2KeySpec.fromRecoveryKey(key1Info.recoveryKey)!!,
|
||||
TestMatrixCallback(decryptCountDownLatch)
|
||||
)
|
||||
mTestHelper.doSync<String> {
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId1,
|
||||
Curve25519AesSha2KeySpec.fromRecoveryKey(key1Info.recoveryKey)!!,
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId2,
|
||||
Curve25519AesSha2KeySpec.fromRecoveryKey(key2Info.recoveryKey)!!,
|
||||
TestMatrixCallback(decryptCountDownLatch)
|
||||
)
|
||||
|
||||
mTestHelper.await(decryptCountDownLatch)
|
||||
mTestHelper.doSync<String> {
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId2,
|
||||
Curve25519AesSha2KeySpec.fromRecoveryKey(key2Info.recoveryKey)!!,
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
mTestHelper.signout(aliceSession)
|
||||
}
|
||||
@ -284,16 +251,17 @@ class QuadSTests : InstrumentedTest {
|
||||
|
||||
val mySecretText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
|
||||
|
||||
val storeLatch = CountDownLatch(1)
|
||||
aliceSession.sharedSecretStorageService.storeSecret(
|
||||
"my.secret",
|
||||
mySecretText.toByteArray().toBase64NoPadding(),
|
||||
listOf(keyId1),
|
||||
TestMatrixCallback(storeLatch)
|
||||
)
|
||||
mTestHelper.await(storeLatch)
|
||||
mTestHelper.doSync<Unit> {
|
||||
aliceSession.sharedSecretStorageService.storeSecret(
|
||||
"my.secret",
|
||||
mySecretText.toByteArray().toBase64NoPadding(),
|
||||
listOf(keyId1),
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
val decryptCountDownLatch = CountDownLatch(2)
|
||||
val decryptCountDownLatch = CountDownLatch(1)
|
||||
var error = false
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId1,
|
||||
Curve25519AesSha2KeySpec.fromPassphrase(
|
||||
@ -304,29 +272,32 @@ class QuadSTests : InstrumentedTest {
|
||||
object : MatrixCallback<String> {
|
||||
override fun onSuccess(data: String) {
|
||||
decryptCountDownLatch.countDown()
|
||||
fail("Should not be able to decrypt")
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Assert.assertTrue(true)
|
||||
error = true
|
||||
decryptCountDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// Now try with correct key
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId1,
|
||||
Curve25519AesSha2KeySpec.fromPassphrase(
|
||||
passphrase,
|
||||
key1Info.content?.passphrase?.salt ?: "",
|
||||
key1Info.content?.passphrase?.iterations ?: 0,
|
||||
null),
|
||||
TestMatrixCallback(decryptCountDownLatch)
|
||||
)
|
||||
|
||||
mTestHelper.await(decryptCountDownLatch)
|
||||
|
||||
error shouldBe true
|
||||
|
||||
// Now try with correct key
|
||||
mTestHelper.doSync<String> {
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId1,
|
||||
Curve25519AesSha2KeySpec.fromPassphrase(
|
||||
passphrase,
|
||||
key1Info.content?.passphrase?.salt ?: "",
|
||||
key1Info.content?.passphrase?.iterations ?: 0,
|
||||
null),
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
mTestHelper.signout(aliceSession)
|
||||
}
|
||||
|
||||
@ -346,7 +317,7 @@ class QuadSTests : InstrumentedTest {
|
||||
GlobalScope.launch(Dispatchers.Main) { liveAccountData.observeForever(accountDataObserver) }
|
||||
mTestHelper.await(accountDataLock)
|
||||
|
||||
Assert.assertNotNull("Account Data type:$type should be found", accountData)
|
||||
assertNotNull("Account Data type:$type should be found", accountData)
|
||||
|
||||
return accountData!!
|
||||
}
|
||||
@ -354,78 +325,36 @@ class QuadSTests : InstrumentedTest {
|
||||
private fun generatedSecret(session: Session, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo {
|
||||
val quadS = session.sharedSecretStorageService
|
||||
|
||||
val emptyKeySigner = object : KeySigner {
|
||||
override fun sign(canonicalJson: String): Map<String, Map<String, String>>? {
|
||||
return null
|
||||
}
|
||||
val creationInfo = mTestHelper.doSync<SsssKeyCreationInfo> {
|
||||
quadS.generateKey(keyId, keyId, emptyKeySigner, it)
|
||||
}
|
||||
|
||||
var creationInfo: SsssKeyCreationInfo? = null
|
||||
assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")
|
||||
|
||||
val generateLatch = CountDownLatch(1)
|
||||
|
||||
quadS.generateKey(keyId, keyId, emptyKeySigner,
|
||||
object : MatrixCallback<SsssKeyCreationInfo> {
|
||||
override fun onSuccess(data: SsssKeyCreationInfo) {
|
||||
creationInfo = data
|
||||
generateLatch.countDown()
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Assert.fail("onFailure " + failure.localizedMessage)
|
||||
generateLatch.countDown()
|
||||
}
|
||||
})
|
||||
|
||||
mTestHelper.await(generateLatch)
|
||||
|
||||
Assert.assertNotNull(creationInfo)
|
||||
|
||||
assertAccountData(session, "m.secret_storage.key.$keyId")
|
||||
if (asDefault) {
|
||||
val setDefaultLatch = CountDownLatch(1)
|
||||
quadS.setDefaultKey(keyId, TestMatrixCallback(setDefaultLatch))
|
||||
mTestHelper.await(setDefaultLatch)
|
||||
mTestHelper.doSync<Unit> {
|
||||
quadS.setDefaultKey(keyId, it)
|
||||
}
|
||||
assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
|
||||
}
|
||||
|
||||
return creationInfo!!
|
||||
return creationInfo
|
||||
}
|
||||
|
||||
private fun generatedSecretFromPassphrase(session: Session, passphrase: String, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo {
|
||||
val quadS = session.sharedSecretStorageService
|
||||
|
||||
val emptyKeySigner = object : KeySigner {
|
||||
override fun sign(canonicalJson: String): Map<String, Map<String, String>>? {
|
||||
return null
|
||||
}
|
||||
val creationInfo = mTestHelper.doSync<SsssKeyCreationInfo> {
|
||||
quadS.generateKeyWithPassphrase(
|
||||
keyId,
|
||||
keyId,
|
||||
passphrase,
|
||||
emptyKeySigner,
|
||||
null,
|
||||
it)
|
||||
}
|
||||
|
||||
var creationInfo: SsssKeyCreationInfo? = null
|
||||
|
||||
val generateLatch = CountDownLatch(1)
|
||||
|
||||
quadS.generateKeyWithPassphrase(keyId, keyId,
|
||||
passphrase,
|
||||
emptyKeySigner,
|
||||
null,
|
||||
object : MatrixCallback<SsssKeyCreationInfo> {
|
||||
override fun onSuccess(data: SsssKeyCreationInfo) {
|
||||
creationInfo = data
|
||||
generateLatch.countDown()
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Assert.fail("onFailure " + failure.localizedMessage)
|
||||
generateLatch.countDown()
|
||||
}
|
||||
})
|
||||
|
||||
mTestHelper.await(generateLatch)
|
||||
|
||||
Assert.assertNotNull(creationInfo)
|
||||
|
||||
assertAccountData(session, "m.secret_storage.key.$keyId")
|
||||
assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")
|
||||
if (asDefault) {
|
||||
val setDefaultLatch = CountDownLatch(1)
|
||||
quadS.setDefaultKey(keyId, TestMatrixCallback(setDefaultLatch))
|
||||
@ -433,6 +362,6 @@ class QuadSTests : InstrumentedTest {
|
||||
assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
|
||||
}
|
||||
|
||||
return creationInfo!!
|
||||
return creationInfo
|
||||
}
|
||||
}
|
||||
|
@ -62,8 +62,8 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
|
||||
val aliceVerificationService = aliceSession.getVerificationService()
|
||||
val bobVerificationService = bobSession!!.getVerificationService()
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
|
||||
val bobTxCreatedLatch = CountDownLatch(1)
|
||||
val bobListener = object : VerificationService.Listener {
|
||||
@ -75,7 +75,7 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
|
||||
bobSession.myUserId,
|
||||
bobSession.getMyDevice().deviceId,
|
||||
bobSession.cryptoService().getMyDevice().deviceId,
|
||||
null)
|
||||
assertNotNull("Alice should have a started transaction", txID)
|
||||
|
||||
@ -157,7 +157,7 @@ class SASTest : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
bobSession.getVerificationService().addListener(bobListener)
|
||||
bobSession.cryptoService().verificationService().addListener(bobListener)
|
||||
|
||||
// TODO bobSession!!.dataHandler.addListener(object : MXEventListener() {
|
||||
// TODO override fun onToDeviceEvent(event: Event?) {
|
||||
@ -172,7 +172,7 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceUserID = aliceSession.myUserId
|
||||
val aliceDevice = aliceSession.getMyDevice().deviceId
|
||||
val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
|
||||
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
@ -181,7 +181,7 @@ class SASTest : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
aliceSession.getVerificationService().addListener(aliceListener)
|
||||
aliceSession.cryptoService().verificationService().addListener(aliceListener)
|
||||
|
||||
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, protocols = protocols)
|
||||
|
||||
@ -218,7 +218,7 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceUserID = aliceSession.myUserId
|
||||
val aliceDevice = aliceSession.getMyDevice().deviceId
|
||||
val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
|
||||
|
||||
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, mac = mac)
|
||||
|
||||
@ -256,7 +256,7 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceUserID = aliceSession.myUserId
|
||||
val aliceDevice = aliceSession.getMyDevice().deviceId
|
||||
val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
|
||||
|
||||
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, codes = codes)
|
||||
|
||||
@ -277,7 +277,7 @@ class SASTest : InstrumentedTest {
|
||||
mac: List<String> = SASDefaultVerificationTransaction.KNOWN_MACS,
|
||||
codes: List<String> = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES) {
|
||||
val startMessage = KeyVerificationStart(
|
||||
fromDevice = bobSession.getMyDevice().deviceId,
|
||||
fromDevice = bobSession.cryptoService().getMyDevice().deviceId,
|
||||
method = VerificationMethod.SAS.toValue(),
|
||||
transactionID = tid,
|
||||
keyAgreementProtocols = protocols,
|
||||
@ -307,7 +307,7 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
|
||||
val aliceVerificationService = aliceSession.getVerificationService()
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
|
||||
val aliceCreatedLatch = CountDownLatch(2)
|
||||
val aliceCancelledLatch = CountDownLatch(2)
|
||||
@ -327,7 +327,7 @@ class SASTest : InstrumentedTest {
|
||||
aliceVerificationService.addListener(aliceListener)
|
||||
|
||||
val bobUserId = bobSession!!.myUserId
|
||||
val bobDeviceId = bobSession.getMyDevice().deviceId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
|
||||
@ -347,8 +347,8 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
|
||||
val aliceVerificationService = aliceSession.getVerificationService()
|
||||
val bobVerificationService = bobSession!!.getVerificationService()
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
|
||||
var accepted: KeyVerificationAccept? = null
|
||||
var startReq: KeyVerificationStart? = null
|
||||
@ -377,7 +377,7 @@ class SASTest : InstrumentedTest {
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = bobSession.getMyDevice().deviceId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
mTestHelper.await(aliceAcceptedLatch)
|
||||
|
||||
@ -403,8 +403,8 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
|
||||
val aliceVerificationService = aliceSession.getVerificationService()
|
||||
val bobVerificationService = bobSession!!.getVerificationService()
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
|
||||
val aliceSASLatch = CountDownLatch(1)
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
@ -438,7 +438,7 @@ class SASTest : InstrumentedTest {
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = bobSession.getMyDevice().deviceId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
mTestHelper.await(aliceSASLatch)
|
||||
mTestHelper.await(bobSASLatch)
|
||||
@ -459,8 +459,8 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
|
||||
val aliceVerificationService = aliceSession.getVerificationService()
|
||||
val bobVerificationService = bobSession!!.getVerificationService()
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
|
||||
val aliceSASLatch = CountDownLatch(1)
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
@ -500,14 +500,14 @@ class SASTest : InstrumentedTest {
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = bobSession.getMyDevice().deviceId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
mTestHelper.await(aliceSASLatch)
|
||||
mTestHelper.await(bobSASLatch)
|
||||
|
||||
// Assert that devices are verified
|
||||
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.getDeviceInfo(bobUserId, bobDeviceId)
|
||||
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.getDeviceInfo(aliceSession.myUserId, aliceSession.getMyDevice().deviceId)
|
||||
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
|
||||
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
|
||||
|
||||
// latch wait a bit again
|
||||
Thread.sleep(1000)
|
||||
|
@ -156,7 +156,7 @@ class VerificationTest : InstrumentedTest {
|
||||
val bobSession = cryptoTestData.secondSession!!
|
||||
|
||||
mTestHelper.doSync<Unit> { callback ->
|
||||
aliceSession.getCrossSigningService()
|
||||
aliceSession.cryptoService().crossSigningService()
|
||||
.initializeCrossSigning(UserPasswordAuth(
|
||||
user = aliceSession.myUserId,
|
||||
password = TestConstants.PASSWORD
|
||||
@ -164,15 +164,15 @@ class VerificationTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
mTestHelper.doSync<Unit> { callback ->
|
||||
bobSession.getCrossSigningService()
|
||||
bobSession.cryptoService().crossSigningService()
|
||||
.initializeCrossSigning(UserPasswordAuth(
|
||||
user = bobSession.myUserId,
|
||||
password = TestConstants.PASSWORD
|
||||
), callback)
|
||||
}
|
||||
|
||||
val aliceVerificationService = aliceSession.getVerificationService()
|
||||
val bobVerificationService = bobSession.getVerificationService()
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||
|
||||
var aliceReadyPendingVerificationRequest: PendingVerificationRequest? = null
|
||||
var bobReadyPendingVerificationRequest: PendingVerificationRequest? = null
|
||||
|
@ -49,7 +49,6 @@ interface Session :
|
||||
RoomDirectoryService,
|
||||
GroupService,
|
||||
UserService,
|
||||
CryptoService,
|
||||
CacheService,
|
||||
SignOutService,
|
||||
FilterService,
|
||||
@ -139,6 +138,11 @@ interface Session :
|
||||
*/
|
||||
fun contentUploadProgressTracker(): ContentUploadStateTracker
|
||||
|
||||
/**
|
||||
* Returns the cryptoService associated with the session
|
||||
*/
|
||||
fun cryptoService(): CryptoService
|
||||
|
||||
/**
|
||||
* Add a listener to the session.
|
||||
* @param listener the listener to add.
|
||||
|
@ -19,18 +19,35 @@ package im.vector.matrix.android.api.session.accountdata
|
||||
import androidx.lifecycle.LiveData
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.api.util.Optional
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
|
||||
|
||||
interface AccountDataService {
|
||||
|
||||
/**
|
||||
* Retrieve the account data with the provided type or null if not found
|
||||
*/
|
||||
fun getAccountDataEvent(type: String): UserAccountDataEvent?
|
||||
|
||||
/**
|
||||
* Observe the account data with the provided type
|
||||
*/
|
||||
fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>>
|
||||
|
||||
fun getAccountDataEvents(filterType: List<String>): List<UserAccountDataEvent>
|
||||
/**
|
||||
* Retrieve the account data with the provided types. The return list can have a different size that
|
||||
* the size of the types set, because some AccountData may not exist.
|
||||
* If an empty set is provided, all the AccountData are retrieved
|
||||
*/
|
||||
fun getAccountDataEvents(types: Set<String>): List<UserAccountDataEvent>
|
||||
|
||||
fun getLiveAccountDataEvents(filterType: List<String>): LiveData<List<UserAccountDataEvent>>
|
||||
/**
|
||||
* Observe the account data with the provided types. If an empty set is provided, all the AccountData are observed
|
||||
*/
|
||||
fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<UserAccountDataEvent>>
|
||||
|
||||
fun updateAccountData(type: String, content: Content, callback: MatrixCallback<Unit>? = null)
|
||||
/**
|
||||
* Update the account data with the provided type and the provided account data content
|
||||
*/
|
||||
fun updateAccountData(type: String, content: Content, callback: MatrixCallback<Unit>? = null): Cancelable
|
||||
}
|
||||
|
@ -40,6 +40,12 @@ import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
||||
|
||||
interface CryptoService {
|
||||
|
||||
fun verificationService(): VerificationService
|
||||
|
||||
fun crossSigningService(): CrossSigningService
|
||||
|
||||
fun keysBackupService(): KeysBackupService
|
||||
|
||||
fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>)
|
||||
|
||||
fun deleteDevice(deviceId: String, callback: MatrixCallback<Unit>)
|
||||
@ -50,12 +56,6 @@ interface CryptoService {
|
||||
|
||||
fun isCryptoEnabled(): Boolean
|
||||
|
||||
fun getVerificationService(): VerificationService
|
||||
|
||||
fun getCrossSigningService(): CrossSigningService
|
||||
|
||||
fun getKeysBackupService(): KeysBackupService
|
||||
|
||||
fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean
|
||||
|
||||
fun setWarnOnUnknownDevices(warn: Boolean)
|
||||
|
@ -19,6 +19,7 @@ package im.vector.matrix.android.api.session.securestorage
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.AccountDataContent
|
||||
|
||||
/**
|
||||
* The account_data will have an encrypted property that is a map from key ID to an object.
|
||||
@ -32,7 +33,7 @@ data class EncryptedSecretContent(
|
||||
@Json(name = "ciphertext") val ciphertext: String? = null,
|
||||
@Json(name = "mac") val mac: String? = null,
|
||||
@Json(name = "ephemeral") val ephemeral: String? = null
|
||||
) {
|
||||
) : AccountDataContent {
|
||||
companion object {
|
||||
/**
|
||||
* Facility method to convert from object which must be comprised of maps, lists,
|
||||
|
@ -54,25 +54,28 @@ data class SecretStorageKeyContent(
|
||||
/** Currently support m.secret_storage.v1.curve25519-aes-sha2 */
|
||||
@Json(name = "algorithm") val algorithm: String? = null,
|
||||
@Json(name = "name") val name: String? = null,
|
||||
@Json(name = "passphrase") val passphrase: SSSSPassphrase? = null,
|
||||
@Json(name = "passphrase") val passphrase: SsssPassphrase? = null,
|
||||
@Json(name = "pubkey") val publicKey: String? = null,
|
||||
@Json(name = "signatures")
|
||||
var signatures: Map<String, Map<String, String>>? = null
|
||||
@Json(name = "signatures") val signatures: Map<String, Map<String, String>>? = null
|
||||
) {
|
||||
|
||||
private fun signalableJSONDictionary(): Map<String, Any> {
|
||||
val map = HashMap<String, Any>()
|
||||
algorithm?.let { map["algorithm"] = it }
|
||||
name?.let { map["name"] = it }
|
||||
publicKey?.let { map["pubkey"] = it }
|
||||
passphrase?.let { ssspp ->
|
||||
map["passphrase"] = mapOf(
|
||||
"algorithm" to ssspp.algorithm,
|
||||
"iterations" to ssspp.salt,
|
||||
"salt" to ssspp.salt
|
||||
)
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
algorithm
|
||||
?.let { this["algorithm"] = it }
|
||||
name
|
||||
?.let { this["name"] = it }
|
||||
publicKey
|
||||
?.let { this["pubkey"] = it }
|
||||
passphrase
|
||||
?.let { ssssPassphrase ->
|
||||
this["passphrase"] = mapOf(
|
||||
"algorithm" to ssssPassphrase.algorithm,
|
||||
"iterations" to ssssPassphrase.iterations,
|
||||
"salt" to ssssPassphrase.salt
|
||||
)
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
fun canonicalSignable(): String {
|
||||
@ -93,7 +96,7 @@ data class SecretStorageKeyContent(
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class SSSSPassphrase(
|
||||
data class SsssPassphrase(
|
||||
@Json(name = "algorithm") val algorithm: String?,
|
||||
@Json(name = "iterations") val iterations: Int,
|
||||
@Json(name = "salt") val salt: String?
|
||||
|
@ -17,7 +17,6 @@
|
||||
package im.vector.matrix.android.api.session.securestorage
|
||||
|
||||
sealed class SharedSecretStorageError(message: String?) : Throwable(message) {
|
||||
|
||||
data class UnknownSecret(val secretName: String) : SharedSecretStorageError("Unknown Secret $secretName")
|
||||
data class UnknownKey(val keyId: String) : SharedSecretStorageError("Unknown key $keyId")
|
||||
data class UnknownAlgorithm(val keyId: String) : SharedSecretStorageError("Unknown algorithm $keyId")
|
||||
|
@ -108,5 +108,5 @@ interface SharedSecretStorageService {
|
||||
*
|
||||
*/
|
||||
@Throws
|
||||
fun getSecret(name: String, keyId: String?, secretKey: SSSSKeySpec, callback: MatrixCallback<String>)
|
||||
fun getSecret(name: String, keyId: String?, secretKey: SsssKeySpec, callback: MatrixCallback<String>)
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ import im.vector.matrix.android.internal.crypto.keysbackup.deriveKey
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
|
||||
|
||||
/** Tag class */
|
||||
interface SSSSKeySpec
|
||||
interface SsssKeySpec
|
||||
|
||||
data class Curve25519AesSha2KeySpec(
|
||||
val privateKey: ByteArray
|
||||
) : SSSSKeySpec {
|
||||
) : SsssKeySpec {
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -49,7 +49,7 @@ import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmEncryp
|
||||
import im.vector.matrix.android.internal.crypto.algorithms.olm.MXOlmEncryptionFactory
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.DefaultCrossSigningService
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
||||
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
|
||||
@ -122,7 +122,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
// Device list manager
|
||||
private val deviceListManager: DeviceListManager,
|
||||
// The key backup service.
|
||||
private val keysBackup: KeysBackup,
|
||||
private val keysBackupService: DefaultKeysBackupService,
|
||||
//
|
||||
private val objectSigner: ObjectSigner,
|
||||
//
|
||||
@ -301,7 +301,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
uploadDeviceKeys()
|
||||
oneTimeKeysUploader.maybeUploadOneTimeKeys()
|
||||
outgoingRoomKeyRequestManager.start()
|
||||
keysBackup.checkAndStartKeysBackup()
|
||||
keysBackupService.checkAndStartKeysBackup()
|
||||
if (isInitialSync) {
|
||||
// refresh the devices list for each known room members
|
||||
deviceListManager.invalidateAllDeviceLists()
|
||||
@ -340,14 +340,14 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
/**
|
||||
* @return the Keys backup Service
|
||||
*/
|
||||
override fun getKeysBackupService() = keysBackup
|
||||
override fun keysBackupService() = keysBackupService
|
||||
|
||||
/**
|
||||
* @return the VerificationService
|
||||
*/
|
||||
override fun getVerificationService() = verificationService
|
||||
override fun verificationService() = verificationService
|
||||
|
||||
override fun getCrossSigningService() = crossSigningService
|
||||
override fun crossSigningService() = crossSigningService
|
||||
|
||||
/**
|
||||
* A sync response has been received
|
||||
@ -721,7 +721,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
Timber.e("## onRoomKeyEvent() : Unable to handle keys for ${roomKeyContent.algorithm}")
|
||||
return
|
||||
}
|
||||
alg.onRoomKeyEvent(event, keysBackup)
|
||||
alg.onRoomKeyEvent(event, keysBackupService)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@
|
||||
package im.vector.matrix.android.internal.crypto.actions
|
||||
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import timber.log.Timber
|
||||
@ -26,7 +26,7 @@ import javax.inject.Inject
|
||||
internal class SetDeviceVerificationAction @Inject constructor(
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
@UserId private val userId: String,
|
||||
private val keysBackup: KeysBackup) {
|
||||
private val defaultKeysBackupService: DefaultKeysBackupService) {
|
||||
|
||||
fun handle(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) {
|
||||
val device = cryptoStore.getUserDevice(userId, deviceId)
|
||||
@ -42,7 +42,7 @@ internal class SetDeviceVerificationAction @Inject constructor(
|
||||
// If one of the user's own devices is being marked as verified / unverified,
|
||||
// check the key backup status, since whether or not we use this depends on
|
||||
// whether it has a signature from a verified device
|
||||
keysBackup.checkAndStartKeysBackup()
|
||||
defaultKeysBackupService.checkAndStartKeysBackup()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ package im.vector.matrix.android.internal.crypto.algorithms
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.crypto.IncomingRoomKeyRequest
|
||||
import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
|
||||
/**
|
||||
* An interface for decrypting data
|
||||
@ -41,7 +41,7 @@ internal interface IMXDecrypting {
|
||||
*
|
||||
* @param event the key event.
|
||||
*/
|
||||
fun onRoomKeyEvent(event: Event, keysBackup: KeysBackup) {}
|
||||
fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {}
|
||||
|
||||
/**
|
||||
* Check if the some messages can be decrypted with a new session
|
||||
|
@ -30,7 +30,7 @@ import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequestManager
|
||||
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
|
||||
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
|
||||
import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
|
||||
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
|
||||
import im.vector.matrix.android.internal.crypto.model.event.RoomKeyContent
|
||||
@ -198,7 +198,7 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
*
|
||||
* @param event the key event.
|
||||
*/
|
||||
override fun onRoomKeyEvent(event: Event, keysBackup: KeysBackup) {
|
||||
override fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {
|
||||
var exportFormat = false
|
||||
val roomKeyContent = event.getClearContent().toModel<RoomKeyContent>() ?: return
|
||||
|
||||
@ -262,7 +262,7 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
exportFormat)
|
||||
|
||||
if (added) {
|
||||
keysBackup.maybeBackupKeys()
|
||||
defaultKeysBackupService.maybeBackupKeys()
|
||||
|
||||
val content = RoomKeyRequestBody()
|
||||
|
||||
|
@ -28,7 +28,7 @@ import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
|
||||
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
|
||||
import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
|
||||
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
|
||||
@ -42,7 +42,7 @@ internal class MXMegolmEncryption(
|
||||
// The id of the room we will be sending to.
|
||||
private var roomId: String,
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val keysBackup: KeysBackup,
|
||||
private val defaultKeysBackupService: DefaultKeysBackupService,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
@ -85,7 +85,7 @@ internal class MXMegolmEncryption(
|
||||
olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, roomId, olmDevice.deviceCurve25519Key!!,
|
||||
emptyList(), keysClaimedMap, false)
|
||||
|
||||
keysBackup.maybeBackupKeys()
|
||||
defaultKeysBackupService.maybeBackupKeys()
|
||||
|
||||
return MXOutboundSessionInfo(sessionId)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import im.vector.matrix.android.internal.crypto.DeviceListManager
|
||||
import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
|
||||
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
||||
@ -29,7 +29,7 @@ import javax.inject.Inject
|
||||
|
||||
internal class MXMegolmEncryptionFactory @Inject constructor(
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val keysBackup: KeysBackup,
|
||||
private val defaultKeysBackupService: DefaultKeysBackupService,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
@ -42,7 +42,7 @@ internal class MXMegolmEncryptionFactory @Inject constructor(
|
||||
return MXMegolmEncryption(
|
||||
roomId,
|
||||
olmDevice,
|
||||
keysBackup,
|
||||
defaultKeysBackupService,
|
||||
cryptoStore,
|
||||
deviceListManager,
|
||||
ensureOlmSessionsForDevicesAction,
|
||||
|
@ -92,12 +92,11 @@ import javax.inject.Inject
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* A KeysBackup class instance manage incremental backup of e2e keys (megolm keys)
|
||||
* A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys)
|
||||
* to the user's homeserver.
|
||||
*/
|
||||
|
||||
@SessionScope
|
||||
internal class KeysBackup @Inject constructor(
|
||||
internal class DefaultKeysBackupService @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
private val credentials: Credentials,
|
||||
private val cryptoStore: IMXCryptoStore,
|
@ -25,24 +25,30 @@ import im.vector.matrix.android.api.session.securestorage.EncryptedSecretContent
|
||||
import im.vector.matrix.android.api.session.securestorage.KeyInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.KeyInfoResult
|
||||
import im.vector.matrix.android.api.session.securestorage.KeySigner
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.SSSSKeySpec
|
||||
import im.vector.matrix.android.api.session.securestorage.SSSSPassphrase
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssKeySpec
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssPassphrase
|
||||
import im.vector.matrix.android.api.session.securestorage.SecretStorageKeyContent
|
||||
import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageError
|
||||
import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
|
||||
import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.generatePrivateKeyWithPassword
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
|
||||
import im.vector.matrix.android.internal.crypto.tools.withOlmDecryption
|
||||
import im.vector.matrix.android.internal.crypto.tools.withOlmEncryption
|
||||
import im.vector.matrix.android.internal.extensions.foldToCallback
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.olm.OlmPkDecryption
|
||||
import org.matrix.olm.OlmPkEncryption
|
||||
import org.matrix.olm.OlmPkMessage
|
||||
import javax.inject.Inject
|
||||
|
||||
private data class Key(
|
||||
val publicKey: String,
|
||||
@Suppress("ArrayInDataClass")
|
||||
val privateKey: ByteArray
|
||||
)
|
||||
|
||||
internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
private val accountDataService: AccountDataService,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
@ -54,25 +60,22 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
keySigner: KeySigner,
|
||||
callback: MatrixCallback<SsssKeyCreationInfo>) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val pkDecryption = OlmPkDecryption()
|
||||
val pubKey: String
|
||||
val privateKey: ByteArray
|
||||
try {
|
||||
pubKey = pkDecryption.generateKey()
|
||||
privateKey = pkDecryption.privateKey()
|
||||
} catch (failure: Throwable) {
|
||||
return@launch Unit.also {
|
||||
callback.onFailure(failure)
|
||||
val key = try {
|
||||
withOlmDecryption { olmPkDecryption ->
|
||||
val pubKey = olmPkDecryption.generateKey()
|
||||
val privateKey = olmPkDecryption.privateKey()
|
||||
Key(pubKey, privateKey)
|
||||
}
|
||||
} finally {
|
||||
pkDecryption.releaseDecryption()
|
||||
} catch (failure: Throwable) {
|
||||
callback.onFailure(failure)
|
||||
return@launch
|
||||
}
|
||||
|
||||
val storageKeyContent = SecretStorageKeyContent(
|
||||
name = keyName,
|
||||
algorithm = SSSS_ALGORITHM_CURVE25519_AES_SHA2,
|
||||
passphrase = null,
|
||||
publicKey = pubKey
|
||||
publicKey = key.publicKey
|
||||
)
|
||||
|
||||
val signedContent = keySigner.sign(storageKeyContent.canonicalSignable())?.let {
|
||||
@ -93,7 +96,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
callback.onSuccess(SsssKeyCreationInfo(
|
||||
keyId = keyId,
|
||||
content = storageKeyContent,
|
||||
recoveryKey = computeRecoveryKey(privateKey)
|
||||
recoveryKey = computeRecoveryKey(key.privateKey)
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -110,21 +113,18 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val privatePart = generatePrivateKeyWithPassword(passphrase, progressListener)
|
||||
|
||||
val pkDecryption = OlmPkDecryption()
|
||||
val pubKey: String
|
||||
try {
|
||||
pubKey = pkDecryption.setPrivateKey(privatePart.privateKey)
|
||||
} catch (failure: Throwable) {
|
||||
return@launch Unit.also {
|
||||
callback.onFailure(failure)
|
||||
val pubKey = try {
|
||||
withOlmDecryption { olmPkDecryption ->
|
||||
olmPkDecryption.setPrivateKey(privatePart.privateKey)
|
||||
}
|
||||
} finally {
|
||||
pkDecryption.releaseDecryption()
|
||||
} catch (failure: Throwable) {
|
||||
callback.onFailure(failure)
|
||||
return@launch
|
||||
}
|
||||
|
||||
val storageKeyContent = SecretStorageKeyContent(
|
||||
algorithm = SSSS_ALGORITHM_CURVE25519_AES_SHA2,
|
||||
passphrase = SSSSPassphrase(algorithm = "m.pbkdf2", iterations = privatePart.iterations, salt = privatePart.salt),
|
||||
passphrase = SsssPassphrase(algorithm = "m.pbkdf2", iterations = privatePart.iterations, salt = privatePart.salt),
|
||||
publicKey = pubKey
|
||||
)
|
||||
|
||||
@ -192,21 +192,20 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val encryptedContents = HashMap<String, EncryptedSecretContent>()
|
||||
try {
|
||||
if (keys == null || keys.isEmpty()) {
|
||||
if (keys.isNullOrEmpty()) {
|
||||
// use default key
|
||||
val key = getDefaultKey()
|
||||
when (key) {
|
||||
when (val key = getDefaultKey()) {
|
||||
is KeyInfoResult.Success -> {
|
||||
if (key.keyInfo.content.algorithm == SSSS_ALGORITHM_CURVE25519_AES_SHA2) {
|
||||
withOlmEncryption { olmEncrypt ->
|
||||
val encryptedResult = withOlmEncryption { olmEncrypt ->
|
||||
olmEncrypt.setRecipientKey(key.keyInfo.content.publicKey)
|
||||
val encryptedResult = olmEncrypt.encrypt(secretBase64)
|
||||
encryptedContents[key.keyInfo.id] = EncryptedSecretContent(
|
||||
ciphertext = encryptedResult.mCipherText,
|
||||
ephemeral = encryptedResult.mEphemeralKey,
|
||||
mac = encryptedResult.mMac
|
||||
)
|
||||
olmEncrypt.encrypt(secretBase64)
|
||||
}
|
||||
encryptedContents[key.keyInfo.id] = EncryptedSecretContent(
|
||||
ciphertext = encryptedResult.mCipherText,
|
||||
ephemeral = encryptedResult.mEphemeralKey,
|
||||
mac = encryptedResult.mMac
|
||||
)
|
||||
} else {
|
||||
// Unknown algorithm
|
||||
callback.onFailure(SharedSecretStorageError.UnknownAlgorithm(key.keyInfo.content.algorithm ?: ""))
|
||||
@ -222,19 +221,18 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
keys.forEach {
|
||||
val keyId = it
|
||||
// encrypt the content
|
||||
val key = getKey(keyId)
|
||||
when (key) {
|
||||
when (val key = getKey(keyId)) {
|
||||
is KeyInfoResult.Success -> {
|
||||
if (key.keyInfo.content.algorithm == SSSS_ALGORITHM_CURVE25519_AES_SHA2) {
|
||||
withOlmEncryption { olmEncrypt ->
|
||||
val encryptedResult = withOlmEncryption { olmEncrypt ->
|
||||
olmEncrypt.setRecipientKey(key.keyInfo.content.publicKey)
|
||||
val encryptedResult = olmEncrypt.encrypt(secretBase64)
|
||||
encryptedContents[keyId] = EncryptedSecretContent(
|
||||
ciphertext = encryptedResult.mCipherText,
|
||||
ephemeral = encryptedResult.mEphemeralKey,
|
||||
mac = encryptedResult.mMac
|
||||
)
|
||||
olmEncrypt.encrypt(secretBase64)
|
||||
}
|
||||
encryptedContents[keyId] = EncryptedSecretContent(
|
||||
ciphertext = encryptedResult.mCipherText,
|
||||
ephemeral = encryptedResult.mEphemeralKey,
|
||||
mac = encryptedResult.mMac
|
||||
)
|
||||
} else {
|
||||
// Unknown algorithm
|
||||
callback.onFailure(SharedSecretStorageError.UnknownAlgorithm(key.keyInfo.content.algorithm ?: ""))
|
||||
@ -279,7 +277,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
return results
|
||||
}
|
||||
|
||||
override fun getSecret(name: String, keyId: String?, secretKey: SSSSKeySpec, callback: MatrixCallback<String>) {
|
||||
override fun getSecret(name: String, keyId: String?, secretKey: SsssKeySpec, callback: MatrixCallback<String>) {
|
||||
val accountData = accountDataService.getAccountDataEvent(name) ?: return Unit.also {
|
||||
callback.onFailure(SharedSecretStorageError.UnknownSecret(name))
|
||||
}
|
||||
@ -306,20 +304,16 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
}
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
kotlin.runCatching {
|
||||
// decryt from recovery key
|
||||
val keyBytes = keySpec.privateKey
|
||||
val decryption = OlmPkDecryption()
|
||||
try {
|
||||
decryption.setPrivateKey(keyBytes)
|
||||
decryption.decrypt(OlmPkMessage().apply {
|
||||
mCipherText = secretContent.ciphertext
|
||||
mEphemeralKey = secretContent.ephemeral
|
||||
mMac = secretContent.mac
|
||||
})
|
||||
} catch (failure: Throwable) {
|
||||
throw failure
|
||||
} finally {
|
||||
decryption.releaseDecryption()
|
||||
// decrypt from recovery key
|
||||
withOlmDecryption { olmPkDecryption ->
|
||||
olmPkDecryption.setPrivateKey(keySpec.privateKey)
|
||||
olmPkDecryption.decrypt(OlmPkMessage()
|
||||
.apply {
|
||||
mCipherText = secretContent.ciphertext
|
||||
mEphemeralKey = secretContent.ephemeral
|
||||
mMac = secretContent.mac
|
||||
}
|
||||
)
|
||||
}
|
||||
}.foldToCallback(callback)
|
||||
}
|
||||
@ -332,27 +326,5 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
const val KEY_ID_BASE = "m.secret_storage.key"
|
||||
const val ENCRYPTED = "encrypted"
|
||||
const val DEFAULT_KEY_ID = "m.secret_storage.default_key"
|
||||
|
||||
fun withOlmEncryption(block: (OlmPkEncryption) -> Unit) {
|
||||
val olmPkEncryption = OlmPkEncryption()
|
||||
try {
|
||||
block(olmPkEncryption)
|
||||
} catch (failure: Throwable) {
|
||||
throw failure
|
||||
} finally {
|
||||
olmPkEncryption.releaseEncryption()
|
||||
}
|
||||
}
|
||||
|
||||
fun withOlmDecryption(block: (OlmPkDecryption) -> Unit) {
|
||||
val olmPkDecryption = OlmPkDecryption()
|
||||
try {
|
||||
block(olmPkDecryption)
|
||||
} catch (failure: Throwable) {
|
||||
throw failure
|
||||
} finally {
|
||||
olmPkDecryption.releaseDecryption()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.crypto.tools
|
||||
|
||||
import org.matrix.olm.OlmPkDecryption
|
||||
import org.matrix.olm.OlmPkEncryption
|
||||
|
||||
fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
|
||||
val olmPkEncryption = OlmPkEncryption()
|
||||
try {
|
||||
return block(olmPkEncryption)
|
||||
} finally {
|
||||
olmPkEncryption.releaseEncryption()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
|
||||
val olmPkDecryption = OlmPkDecryption()
|
||||
try {
|
||||
return block(olmPkDecryption)
|
||||
} finally {
|
||||
olmPkDecryption.releaseDecryption()
|
||||
}
|
||||
}
|
@ -49,7 +49,6 @@ import im.vector.matrix.android.internal.crypto.crosssigning.ShieldTrustUpdater
|
||||
import im.vector.matrix.android.internal.database.LiveEntityObserver
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.session.sync.SyncTaskSequencer
|
||||
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
|
||||
import im.vector.matrix.android.internal.session.sync.job.SyncThread
|
||||
import im.vector.matrix.android.internal.session.sync.job.SyncWorker
|
||||
@ -88,7 +87,6 @@ internal class DefaultSession @Inject constructor(
|
||||
private val syncThreadProvider: Provider<SyncThread>,
|
||||
private val contentUrlResolver: ContentUrlResolver,
|
||||
private val syncTokenStore: SyncTokenStore,
|
||||
private val syncTaskSequencer: SyncTaskSequencer,
|
||||
private val sessionParamsStore: SessionParamsStore,
|
||||
private val contentUploadProgressTracker: ContentUploadStateTracker,
|
||||
private val initialSyncProgressService: Lazy<InitialSyncProgressService>,
|
||||
@ -101,7 +99,6 @@ internal class DefaultSession @Inject constructor(
|
||||
RoomDirectoryService by roomDirectoryService.get(),
|
||||
GroupService by groupService.get(),
|
||||
UserService by userService.get(),
|
||||
CryptoService by cryptoService.get(),
|
||||
SignOutService by signOutService.get(),
|
||||
FilterService by filterService.get(),
|
||||
PushRuleService by pushRuleService.get(),
|
||||
@ -170,7 +167,6 @@ internal class DefaultSession @Inject constructor(
|
||||
cryptoService.get().close()
|
||||
isOpen = false
|
||||
eventBus.unregister(this)
|
||||
syncTaskSequencer.close()
|
||||
shieldTrustUpdater.stop()
|
||||
}
|
||||
|
||||
@ -212,6 +208,8 @@ internal class DefaultSession @Inject constructor(
|
||||
|
||||
override fun contentUploadProgressTracker() = contentUploadProgressTracker
|
||||
|
||||
override fun cryptoService(): CryptoService = cryptoService.get()
|
||||
|
||||
override fun addListener(listener: Session.Listener) {
|
||||
sessionListeners.addListener(listener)
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ internal abstract class SessionModule {
|
||||
abstract fun bindHomeServerCapabilitiesService(homeServerCapabilitiesService: DefaultHomeServerCapabilitiesService): HomeServerCapabilitiesService
|
||||
|
||||
@Binds
|
||||
abstract fun bindAccountDataService(accountDataService: DefaultAccountDataService): AccountDataService
|
||||
abstract fun bindAccountDataService(service: DefaultAccountDataService): AccountDataService
|
||||
|
||||
@Binds
|
||||
abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService
|
||||
|
@ -17,8 +17,8 @@
|
||||
package im.vector.matrix.android.internal.session.sync
|
||||
|
||||
import im.vector.matrix.android.internal.session.SessionScope
|
||||
import im.vector.matrix.android.internal.task.ChannelCoroutineSequencer
|
||||
import im.vector.matrix.android.internal.task.SemaphoreCoroutineSequencer
|
||||
import javax.inject.Inject
|
||||
|
||||
@SessionScope
|
||||
internal class SyncTaskSequencer @Inject constructor() : ChannelCoroutineSequencer<Unit>()
|
||||
internal class SyncTaskSequencer @Inject constructor() : SemaphoreCoroutineSequencer()
|
||||
|
@ -17,8 +17,9 @@
|
||||
package im.vector.matrix.android.internal.session.sync.model.accountdata
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import im.vector.matrix.android.internal.session.user.accountdata.AccountDataContent
|
||||
|
||||
abstract class UserAccountData {
|
||||
abstract class UserAccountData : AccountDataContent {
|
||||
|
||||
@Json(name = "type") abstract val type: String
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.user.accountdata
|
||||
|
||||
/**
|
||||
* Tag class to identify every account data content
|
||||
*/
|
||||
internal interface AccountDataContent
|
@ -22,13 +22,13 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.accountdata.AccountDataService
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE
|
||||
import im.vector.matrix.android.api.util.Optional
|
||||
import im.vector.matrix.android.api.util.toOptional
|
||||
import im.vector.matrix.android.internal.database.model.UserAccountDataEntity
|
||||
import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFields
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
import im.vector.matrix.android.internal.session.sync.UserAccountDataSyncHandler
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
@ -37,7 +37,6 @@ import javax.inject.Inject
|
||||
|
||||
internal class DefaultAccountDataService @Inject constructor(
|
||||
private val monarchy: Monarchy,
|
||||
@SessionId private val sessionId: String,
|
||||
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
|
||||
private val userAccountDataSyncHandler: UserAccountDataSyncHandler,
|
||||
private val taskExecutor: TaskExecutor
|
||||
@ -47,39 +46,39 @@ internal class DefaultAccountDataService @Inject constructor(
|
||||
private val adapter = moshi.adapter<Map<String, Any>>(JSON_DICT_PARAMETERIZED_TYPE)
|
||||
|
||||
override fun getAccountDataEvent(type: String): UserAccountDataEvent? {
|
||||
return getAccountDataEvents(listOf(type)).firstOrNull()
|
||||
return getAccountDataEvents(setOf(type)).firstOrNull()
|
||||
}
|
||||
|
||||
override fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>> {
|
||||
return Transformations.map(getLiveAccountDataEvents(listOf(type))) {
|
||||
return Transformations.map(getLiveAccountDataEvents(setOf(type))) {
|
||||
it.firstOrNull()?.toOptional()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAccountDataEvents(filterType: List<String>): List<UserAccountDataEvent> {
|
||||
override fun getAccountDataEvents(types: Set<String>): List<UserAccountDataEvent> {
|
||||
return monarchy.fetchAllCopiedSync { realm ->
|
||||
realm.where(UserAccountDataEntity::class.java)
|
||||
.apply {
|
||||
if (filterType.isNotEmpty()) {
|
||||
`in`(UserAccountDataEntityFields.TYPE, filterType.toTypedArray())
|
||||
if (types.isNotEmpty()) {
|
||||
`in`(UserAccountDataEntityFields.TYPE, types.toTypedArray())
|
||||
}
|
||||
}
|
||||
}?.mapNotNull { entity ->
|
||||
}.mapNotNull { entity ->
|
||||
entity.type?.let { type ->
|
||||
UserAccountDataEvent(
|
||||
type = type,
|
||||
content = entity.contentStr?.let { adapter.fromJson(it) } ?: emptyMap()
|
||||
)
|
||||
}
|
||||
} ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLiveAccountDataEvents(filterType: List<String>): LiveData<List<UserAccountDataEvent>> {
|
||||
override fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<UserAccountDataEvent>> {
|
||||
return monarchy.findAllMappedWithChanges({ realm ->
|
||||
realm.where(UserAccountDataEntity::class.java)
|
||||
.apply {
|
||||
if (filterType.isNotEmpty()) {
|
||||
`in`(UserAccountDataEntityFields.TYPE, filterType.toTypedArray())
|
||||
if (types.isNotEmpty()) {
|
||||
`in`(UserAccountDataEntityFields.TYPE, types.toTypedArray())
|
||||
}
|
||||
}
|
||||
}, { entity ->
|
||||
@ -90,14 +89,15 @@ internal class DefaultAccountDataService @Inject constructor(
|
||||
})
|
||||
}
|
||||
|
||||
override fun updateAccountData(type: String, content: Content, callback: MatrixCallback<Unit>?) {
|
||||
updateUserAccountDataTask.configureWith(UpdateUserAccountDataTask.AnyParams(
|
||||
override fun updateAccountData(type: String, content: Content, callback: MatrixCallback<Unit>?): Cancelable {
|
||||
return updateUserAccountDataTask.configureWith(UpdateUserAccountDataTask.AnyParams(
|
||||
type = type,
|
||||
any = content
|
||||
)) {
|
||||
this.retryCount = 5
|
||||
this.callback = object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
// TODO Move that to the task (but it created a circular dependencies...)
|
||||
monarchy.runTransactionSync { realm ->
|
||||
userAccountDataSyncHandler.handleGenericAccountData(realm, type, content)
|
||||
}
|
||||
|
@ -16,72 +16,28 @@
|
||||
|
||||
package im.vector.matrix.android.internal.task
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import java.util.concurrent.Executors
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
|
||||
/**
|
||||
* This class intends to be used for ensure suspendable methods are played sequentially all the way long.
|
||||
* This class intends to be used to ensure suspendable methods are played sequentially all the way long.
|
||||
*/
|
||||
internal interface CoroutineSequencer<T> {
|
||||
internal interface CoroutineSequencer {
|
||||
/**
|
||||
* @param block the suspendable block to execute
|
||||
* @return the result of the block
|
||||
*/
|
||||
suspend fun post(block: suspend () -> T): T
|
||||
|
||||
/**
|
||||
* Cancel all and close, so you won't be able to post anything else after
|
||||
*/
|
||||
fun close()
|
||||
suspend fun <T> post(block: suspend () -> T): T
|
||||
}
|
||||
|
||||
internal open class ChannelCoroutineSequencer<T> : CoroutineSequencer<T> {
|
||||
internal open class SemaphoreCoroutineSequencer : CoroutineSequencer {
|
||||
|
||||
private data class Message<T>(
|
||||
val block: suspend () -> T,
|
||||
val deferred: CompletableDeferred<T>
|
||||
)
|
||||
// Permits 1 suspend function at a time.
|
||||
private val semaphore = Semaphore(1)
|
||||
|
||||
private var messageChannel: Channel<Message<T>> = Channel()
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob())
|
||||
// This will ensure
|
||||
private val singleDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
|
||||
init {
|
||||
launchCoroutine()
|
||||
}
|
||||
|
||||
private fun launchCoroutine() {
|
||||
coroutineScope.launch(singleDispatcher) {
|
||||
for (message in messageChannel) {
|
||||
try {
|
||||
val result = message.block()
|
||||
message.deferred.complete(result)
|
||||
} catch (exception: Throwable) {
|
||||
message.deferred.completeExceptionally(exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
coroutineScope.coroutineContext.cancelChildren()
|
||||
messageChannel.close()
|
||||
}
|
||||
|
||||
override suspend fun post(block: suspend () -> T): T {
|
||||
val deferred = CompletableDeferred<T>()
|
||||
val message = Message(block, deferred)
|
||||
messageChannel.send(message)
|
||||
return try {
|
||||
deferred.await()
|
||||
} catch (cancellation: CancellationException) {
|
||||
// In case of cancellation, we stop the current coroutine context
|
||||
// and relaunch one to consume next messages
|
||||
coroutineScope.coroutineContext.cancelChildren()
|
||||
launchCoroutine()
|
||||
throw cancellation
|
||||
override suspend fun <T> post(block: suspend () -> T): T {
|
||||
return semaphore.withPermit {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class CoroutineSequencersTest {
|
||||
|
||||
@Test
|
||||
fun sequencer_should_run_sequential() {
|
||||
val sequencer = ChannelCoroutineSequencer<String>()
|
||||
val sequencer = SemaphoreCoroutineSequencer()
|
||||
val results = ArrayList<String>()
|
||||
|
||||
val jobs = listOf(
|
||||
@ -63,9 +63,9 @@ class CoroutineSequencersTest {
|
||||
|
||||
@Test
|
||||
fun sequencer_should_run_parallel() {
|
||||
val sequencer1 = ChannelCoroutineSequencer<String>()
|
||||
val sequencer2 = ChannelCoroutineSequencer<String>()
|
||||
val sequencer3 = ChannelCoroutineSequencer<String>()
|
||||
val sequencer1 = SemaphoreCoroutineSequencer()
|
||||
val sequencer2 = SemaphoreCoroutineSequencer()
|
||||
val sequencer3 = SemaphoreCoroutineSequencer()
|
||||
val results = ArrayList<String>()
|
||||
val jobs = listOf(
|
||||
GlobalScope.launch(dispatcher) {
|
||||
@ -92,7 +92,7 @@ class CoroutineSequencersTest {
|
||||
|
||||
@Test
|
||||
fun sequencer_should_jump_to_next_when_current_job_canceled() {
|
||||
val sequencer = ChannelCoroutineSequencer<String>()
|
||||
val sequencer = SemaphoreCoroutineSequencer()
|
||||
val results = ArrayList<String>()
|
||||
val jobs = listOf(
|
||||
GlobalScope.launch(dispatcher) {
|
||||
|
@ -66,6 +66,6 @@ fun Session.startSyncing(context: Context) {
|
||||
* Tell is the session has unsaved e2e keys in the backup
|
||||
*/
|
||||
fun Session.hasUnsavedKeys(): Boolean {
|
||||
return inboundGroupSessionsCount(false) > 0
|
||||
&& getKeysBackupService().state != KeysBackupState.ReadyToBackUp
|
||||
return cryptoService().inboundGroupSessionsCount(false) > 0
|
||||
&& cryptoService().keysBackupService().state != KeysBackupState.ReadyToBackUp
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class KeysExporter(private val session: Session) {
|
||||
fun export(context: Context, password: String, callback: MatrixCallback<String>) {
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
runCatching {
|
||||
val data = awaitCallback<ByteArray> { session.exportRoomKeys(password, it) }
|
||||
val data = awaitCallback<ByteArray> { session.cryptoService().exportRoomKeys(password, it) }
|
||||
withContext(Dispatchers.IO) {
|
||||
val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
val file = File(parentDir, "riotx-keys-" + System.currentTimeMillis() + ".txt")
|
||||
|
@ -59,7 +59,7 @@ class KeysImporter(private val session: Session) {
|
||||
}
|
||||
|
||||
awaitCallback<ImportRoomKeysResult> {
|
||||
session.importRoomKeys(data, password, null, it)
|
||||
session.cryptoService().importRoomKeys(data, password, null, it)
|
||||
}
|
||||
}
|
||||
}.foldToCallback(callback)
|
||||
|
@ -47,7 +47,7 @@ class KeysBackupRestoreFromKeyViewModel @Inject constructor() : ViewModel() {
|
||||
|
||||
fun recoverKeys(context: Context, sharedViewModel: KeysBackupRestoreSharedViewModel) {
|
||||
val session = sharedViewModel.session
|
||||
val keysBackup = session.getKeysBackupService()
|
||||
val keysBackup = session.cryptoService().keysBackupService()
|
||||
|
||||
recoveryCodeErrorText.value = null
|
||||
val recoveryKey = recoveryCode.value!!
|
||||
|
@ -49,7 +49,7 @@ class KeysBackupRestoreFromPassphraseViewModel @Inject constructor() : ViewModel
|
||||
}
|
||||
|
||||
fun recoverKeys(context: Context, sharedViewModel: KeysBackupRestoreSharedViewModel) {
|
||||
val keysBackup = sharedViewModel.session.getKeysBackupService()
|
||||
val keysBackup = sharedViewModel.session.cryptoService().keysBackupService()
|
||||
|
||||
passphraseErrorText.value = null
|
||||
|
||||
|
@ -63,7 +63,7 @@ class KeysBackupRestoreSharedViewModel @Inject constructor() : ViewModel() {
|
||||
}
|
||||
|
||||
fun getLatestVersion(context: Context) {
|
||||
val keysBackup = session.getKeysBackupService()
|
||||
val keysBackup = session.cryptoService().keysBackupService()
|
||||
|
||||
loadingEvent.value = WaitingViewData(context.getString(R.string.keys_backup_restore_is_getting_backup_version))
|
||||
|
||||
|
@ -119,8 +119,8 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
|
||||
style(GenericItem.STYLE.BIG_TEXT)
|
||||
hasIndeterminateProcess(true)
|
||||
|
||||
val totalKeys = session.inboundGroupSessionsCount(false)
|
||||
val backedUpKeys = session.inboundGroupSessionsCount(true)
|
||||
val totalKeys = session.cryptoService().inboundGroupSessionsCount(false)
|
||||
val backedUpKeys = session.cryptoService().inboundGroupSessionsCount(true)
|
||||
|
||||
val remainingKeysToBackup = totalKeys - backedUpKeys
|
||||
|
||||
|
@ -47,13 +47,13 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS
|
||||
}
|
||||
}
|
||||
|
||||
private var keysBackupService: KeysBackupService = session.getKeysBackupService()
|
||||
private val keysBackupService: KeysBackupService = session.cryptoService().keysBackupService()
|
||||
|
||||
init {
|
||||
setState {
|
||||
this.copy(
|
||||
keysBackupState = session.getKeysBackupService().state,
|
||||
keysBackupVersion = session.getKeysBackupService().keysBackupVersion
|
||||
keysBackupState = keysBackupService.state,
|
||||
keysBackupVersion = keysBackupService.keysBackupVersion
|
||||
)
|
||||
}
|
||||
keysBackupService.addListener(this)
|
||||
|
@ -102,7 +102,7 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() {
|
||||
session.let { mxSession ->
|
||||
val requestedId = currentRequestId.value!!
|
||||
|
||||
mxSession.getKeysBackupService().prepareKeysBackupVersion(withPassphrase,
|
||||
mxSession.cryptoService().keysBackupService().prepareKeysBackupVersion(withPassphrase,
|
||||
object : ProgressListener {
|
||||
override fun onProgress(progress: Int, total: Int) {
|
||||
if (requestedId != currentRequestId.value) {
|
||||
@ -125,7 +125,7 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() {
|
||||
megolmBackupCreationInfo = data
|
||||
copyHasBeenMade = false
|
||||
|
||||
val keyBackup = session.getKeysBackupService()
|
||||
val keyBackup = session.cryptoService().keysBackupService()
|
||||
createKeysBackup(context, keyBackup)
|
||||
}
|
||||
|
||||
@ -145,14 +145,14 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() {
|
||||
}
|
||||
|
||||
fun forceCreateKeyBackup(context: Context) {
|
||||
val keyBackup = session.getKeysBackupService()
|
||||
val keyBackup = session.cryptoService().keysBackupService()
|
||||
createKeysBackup(context, keyBackup, true)
|
||||
}
|
||||
|
||||
fun stopAndKeepAfterDetectingExistingOnServer() {
|
||||
loadingStatus.value = null
|
||||
navigateEvent.value = LiveEvent(NAVIGATE_FINISH)
|
||||
session.getKeysBackupService().checkAndStartKeysBackup()
|
||||
session.cryptoService().keysBackupService().checkAndStartKeysBackup()
|
||||
}
|
||||
|
||||
private fun createKeysBackup(context: Context, keysBackup: KeysBackupService, forceOverride: Boolean = false) {
|
||||
|
@ -64,13 +64,13 @@ class KeyRequestHandler @Inject constructor(private val context: Context)
|
||||
|
||||
fun start(session: Session) {
|
||||
this.session = session
|
||||
session.getVerificationService().addListener(this)
|
||||
session.addRoomKeysRequestListener(this)
|
||||
session.cryptoService().verificationService().addListener(this)
|
||||
session.cryptoService().addRoomKeysRequestListener(this)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
session?.getVerificationService()?.removeListener(this)
|
||||
session?.removeRoomKeysRequestListener(this)
|
||||
session?.cryptoService()?.verificationService()?.removeListener(this)
|
||||
session?.cryptoService()?.removeRoomKeysRequestListener(this)
|
||||
session = null
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ class KeyRequestHandler @Inject constructor(private val context: Context)
|
||||
alertsToRequests[mappingKey] = ArrayList<IncomingRoomKeyRequest>().apply { this.add(request) }
|
||||
|
||||
// Add a notification for every incoming request
|
||||
session?.downloadKeys(listOf(userId), false, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
session?.cryptoService()?.downloadKeys(listOf(userId), false, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<CryptoDeviceInfo>) {
|
||||
val deviceInfo = data.getObject(userId, deviceId)
|
||||
|
||||
@ -111,12 +111,12 @@ class KeyRequestHandler @Inject constructor(private val context: Context)
|
||||
}
|
||||
|
||||
if (deviceInfo.isUnknown) {
|
||||
session?.setDeviceVerification(DeviceTrustLevel(false, false), userId, deviceId)
|
||||
session?.cryptoService()?.setDeviceVerification(DeviceTrustLevel(false, false), userId, deviceId)
|
||||
|
||||
deviceInfo.trustLevel = DeviceTrustLevel(false, false)
|
||||
|
||||
// can we get more info on this device?
|
||||
session?.getDevicesList(object : MatrixCallback<DevicesListResponse> {
|
||||
session?.cryptoService()?.getDevicesList(object : MatrixCallback<DevicesListResponse> {
|
||||
override fun onSuccess(data: DevicesListResponse) {
|
||||
data.devices?.find { it.deviceId == deviceId }?.let {
|
||||
postAlert(context, userId, deviceId, true, deviceInfo, it)
|
||||
|
@ -40,11 +40,11 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context
|
||||
|
||||
fun start(session: Session) {
|
||||
this.session = session
|
||||
session.getVerificationService().addListener(this)
|
||||
session.cryptoService().verificationService().addListener(this)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
session?.getVerificationService()?.removeListener(this)
|
||||
session?.cryptoService()?.verificationService()?.removeListener(this)
|
||||
this.session = null
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context
|
||||
}
|
||||
}
|
||||
dismissedAction = Runnable {
|
||||
session?.getVerificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
|
||||
session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
|
||||
pr.transactionId ?: "",
|
||||
pr.roomId ?: ""
|
||||
)
|
||||
|
@ -63,7 +63,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
VerificationService.Listener {
|
||||
|
||||
init {
|
||||
session.getVerificationService().addListener(this)
|
||||
session.cryptoService().verificationService().addListener(this)
|
||||
|
||||
val userItem = session.getUser(args.otherUserId)
|
||||
|
||||
@ -73,7 +73,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
val pr = if (isWaitingForOtherMode) {
|
||||
// See if active tx for this user and take it
|
||||
|
||||
session.getVerificationService().getExistingVerificationRequest(args.otherUserId)
|
||||
session.cryptoService().verificationService().getExistingVerificationRequest(args.otherUserId)
|
||||
?.lastOrNull { !it.isFinished }
|
||||
?.also { verificationRequest ->
|
||||
if (verificationRequest.isIncoming && !verificationRequest.isReady) {
|
||||
@ -82,15 +82,15 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
}
|
||||
}
|
||||
} else {
|
||||
session.getVerificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
|
||||
session.cryptoService().verificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
|
||||
}
|
||||
|
||||
val sasTx = (pr?.transactionId ?: args.verificationId)?.let {
|
||||
session.getVerificationService().getExistingTransaction(args.otherUserId, it) as? SasVerificationTransaction
|
||||
session.cryptoService().verificationService().getExistingTransaction(args.otherUserId, it) as? SasVerificationTransaction
|
||||
}
|
||||
|
||||
val qrTx = (pr?.transactionId ?: args.verificationId)?.let {
|
||||
session.getVerificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
|
||||
session.cryptoService().verificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
|
||||
}
|
||||
|
||||
setState {
|
||||
@ -108,7 +108,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
|
||||
if (autoReady) {
|
||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||
session.getVerificationService()
|
||||
session.cryptoService().verificationService()
|
||||
.readyPendingVerification(supportedVerificationMethods,
|
||||
pr!!.otherUserId,
|
||||
pr.transactionId ?: "")
|
||||
@ -116,7 +116,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
session.getVerificationService().removeListener(this)
|
||||
session.cryptoService().verificationService().removeListener(this)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
@ -164,7 +164,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
roomId = data,
|
||||
pendingRequest = Success(
|
||||
session
|
||||
.getVerificationService()
|
||||
.cryptoService()
|
||||
.verificationService()
|
||||
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, data, pendingLocalId)
|
||||
)
|
||||
)
|
||||
@ -181,7 +182,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
setState {
|
||||
copy(
|
||||
pendingRequest = Success(session
|
||||
.getVerificationService()
|
||||
.cryptoService()
|
||||
.verificationService()
|
||||
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, roomId)
|
||||
)
|
||||
)
|
||||
@ -190,18 +192,18 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
Unit
|
||||
}
|
||||
is VerificationAction.StartSASVerification -> {
|
||||
val request = session.getVerificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
||||
val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
||||
?: return@withState
|
||||
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
||||
if (roomId == null) {
|
||||
session.getVerificationService().beginKeyVerification(
|
||||
session.cryptoService().verificationService().beginKeyVerification(
|
||||
VerificationMethod.SAS,
|
||||
otherUserId = request.otherUserId,
|
||||
otherDeviceId = otherDevice ?: "",
|
||||
transactionId = action.pendingRequestTransactionId
|
||||
)
|
||||
} else {
|
||||
session.getVerificationService().beginKeyVerificationInDMs(
|
||||
session.cryptoService().verificationService().beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
transactionId = action.pendingRequestTransactionId,
|
||||
roomId = roomId,
|
||||
@ -213,7 +215,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
Unit
|
||||
}
|
||||
is VerificationAction.RemoteQrCodeScanned -> {
|
||||
val existingTransaction = session.getVerificationService()
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.userHasScannedOtherQrCode(action.scannedData)
|
||||
@ -221,7 +223,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
is VerificationAction.OtherUserScannedSuccessfully -> {
|
||||
val transactionId = state.transactionId ?: return@withState
|
||||
|
||||
val existingTransaction = session.getVerificationService()
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.otherUserScannedMyQrCode()
|
||||
@ -229,18 +231,18 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
is VerificationAction.OtherUserDidNotScanned -> {
|
||||
val transactionId = state.transactionId ?: return@withState
|
||||
|
||||
val existingTransaction = session.getVerificationService()
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.otherUserDidNotScannedMyQrCode()
|
||||
}
|
||||
is VerificationAction.SASMatchAction -> {
|
||||
(session.getVerificationService()
|
||||
(session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.sasTransactionId)
|
||||
as? SasVerificationTransaction)?.userHasVerifiedShortCode()
|
||||
}
|
||||
is VerificationAction.SASDoNotMatchAction -> {
|
||||
(session.getVerificationService()
|
||||
(session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.sasTransactionId)
|
||||
as? SasVerificationTransaction)
|
||||
?.shortCodeDoesNotMatch()
|
||||
@ -312,7 +314,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
if (!pr.isReady) {
|
||||
// auto ready in this case, as we are waiting
|
||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||
session.getVerificationService()
|
||||
session.cryptoService().verificationService()
|
||||
.readyPendingVerification(supportedVerificationMethods,
|
||||
pr.otherUserId,
|
||||
pr.transactionId ?: "")
|
||||
|
@ -62,7 +62,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) = withState { state ->
|
||||
val pvr = session.getVerificationService().getExistingVerificationRequest(state.otherUserId, state.transactionId)
|
||||
val pvr = session.cryptoService().verificationService().getExistingVerificationRequest(state.otherUserId, state.transactionId)
|
||||
|
||||
setState {
|
||||
copy(
|
||||
@ -79,12 +79,12 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
init {
|
||||
session.getVerificationService().addListener(this)
|
||||
session.cryptoService().verificationService().addListener(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
session.getVerificationService().removeListener(this)
|
||||
session.cryptoService().verificationService().removeListener(this)
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<VerificationChooseMethodViewModel, VerificationChooseMethodViewState> {
|
||||
@ -96,10 +96,11 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
||||
override fun initialState(viewModelContext: ViewModelContext): VerificationChooseMethodViewState? {
|
||||
val args: VerificationBottomSheet.VerificationArgs = viewModelContext.args()
|
||||
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
|
||||
val pvr = session.getVerificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
|
||||
val verificationService = session.cryptoService().verificationService()
|
||||
val pvr = verificationService.getExistingVerificationRequest(args.otherUserId, args.verificationId)
|
||||
|
||||
// Get the QR code now, because transaction is already created, so transactionCreated() will not be called
|
||||
val qrCodeVerificationTransaction = session.getVerificationService().getExistingTransaction(args.otherUserId, args.verificationId ?: "")
|
||||
val qrCodeVerificationTransaction = verificationService.getExistingTransaction(args.otherUserId, args.verificationId ?: "")
|
||||
|
||||
return VerificationChooseMethodViewState(otherUserId = args.otherUserId,
|
||||
transactionId = args.verificationId ?: "",
|
||||
|
@ -56,16 +56,16 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor(
|
||||
|
||||
init {
|
||||
withState { state ->
|
||||
refreshStateFromTx(session.getVerificationService()
|
||||
refreshStateFromTx(session.cryptoService().verificationService()
|
||||
.getExistingTransaction(state.otherUser?.id ?: "", state.transactionId
|
||||
?: "") as? SasVerificationTransaction)
|
||||
}
|
||||
|
||||
session.getVerificationService().addListener(this)
|
||||
session.cryptoService().verificationService().addListener(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
session.getVerificationService().removeListener(this)
|
||||
session.cryptoService().verificationService().removeListener(this)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
if (sharedActionViewModel.hasDisplayedCompleteSecurityPrompt) return
|
||||
|
||||
// ensure keys are downloaded
|
||||
session.downloadKeys(listOf(session.myUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
session.cryptoService().downloadKeys(listOf(session.myUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<CryptoDeviceInfo>) {
|
||||
runOnUiThread {
|
||||
alertCompleteSecurity(session)
|
||||
@ -140,7 +140,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
}
|
||||
|
||||
private fun alertCompleteSecurity(session: Session) {
|
||||
val myCrossSigningKeys = session.getCrossSigningService()
|
||||
val myCrossSigningKeys = session.cryptoService().crossSigningService()
|
||||
.getMyCrossSigningKeys()
|
||||
val crossSigningEnabledOnAccount = myCrossSigningKeys != null
|
||||
|
||||
|
@ -422,7 +422,10 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
||||
popDraft()
|
||||
}
|
||||
is ParsedCommand.VerifyUser -> {
|
||||
session.getVerificationService().requestKeyVerificationInDMs(supportedVerificationMethods, slashCommandResult.userId, room.roomId)
|
||||
session
|
||||
.cryptoService()
|
||||
.verificationService()
|
||||
.requestKeyVerificationInDMs(supportedVerificationMethods, slashCommandResult.userId, room.roomId)
|
||||
_viewEvents.post(RoomDetailViewEvents.SlashCommandHandled())
|
||||
popDraft()
|
||||
}
|
||||
@ -828,7 +831,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
||||
|
||||
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
|
||||
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
|
||||
if (session.getVerificationService().readyPendingVerificationInDMs(
|
||||
if (session.cryptoService().verificationService().readyPendingVerificationInDMs(
|
||||
supportedVerificationMethods,
|
||||
action.otherUserId,
|
||||
room.roomId,
|
||||
@ -840,7 +843,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
||||
}
|
||||
|
||||
private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) {
|
||||
session.getVerificationService().declineVerificationRequestInDMs(
|
||||
session.cryptoService().verificationService().declineVerificationRequestInDMs(
|
||||
action.otherUserId,
|
||||
action.transactionId,
|
||||
room.roomId)
|
||||
@ -853,7 +856,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
||||
|
||||
private fun handleResumeRequestVerification(action: RoomDetailAction.ResumeVerification) {
|
||||
// Check if this request is still active and handled by me
|
||||
session.getVerificationService().getExistingVerificationRequestInRoom(room.roomId, action.transactionId)?.let {
|
||||
session.cryptoService().verificationService().getExistingVerificationRequestInRoom(room.roomId, action.transactionId)?.let {
|
||||
if (it.handledByOtherSession) return
|
||||
if (!it.isFinished) {
|
||||
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action.copy(
|
||||
|
@ -100,7 +100,7 @@ class ViewEditHistoryViewModel @AssistedInject constructor(@Assisted
|
||||
if (it.isEncrypted() && it.mxDecryptionResult == null) {
|
||||
// for now decrypt sync
|
||||
try {
|
||||
val result = session.decryptEvent(it, timelineID)
|
||||
val result = session.cryptoService().decryptEvent(it, timelineID)
|
||||
it.mxDecryptionResult = OlmDecryptionResult(
|
||||
payload = result.clearEvent,
|
||||
senderKey = result.senderCurve25519Key,
|
||||
|
@ -66,7 +66,7 @@ class DefaultNavigator @Inject constructor(
|
||||
|
||||
override fun performDeviceVerification(context: Context, otherUserId: String, sasTransactionId: String) {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return
|
||||
val tx = session.getVerificationService().getExistingTransaction(otherUserId, sasTransactionId) ?: return
|
||||
val tx = session.cryptoService().verificationService().getExistingTransaction(otherUserId, sasTransationId) ?: return
|
||||
(tx as? IncomingSasVerificationTransaction)?.performAccept()
|
||||
if (context is VectorBaseActivity) {
|
||||
VerificationBottomSheet.withArgs(
|
||||
@ -79,10 +79,10 @@ class DefaultNavigator @Inject constructor(
|
||||
|
||||
override fun requestSessionVerification(context: Context) {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return
|
||||
val pr = session.getVerificationService().requestKeyVerification(
|
||||
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
session.myUserId,
|
||||
session.getUserDevices(session.myUserId).map { it.deviceId })
|
||||
session.cryptoService().getUserDevices(session.myUserId).map { it.deviceId })
|
||||
if (context is VectorBaseActivity) {
|
||||
VerificationBottomSheet.withArgs(
|
||||
roomId = null,
|
||||
|
@ -114,7 +114,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
|
||||
// TODO use a global event decryptor? attache to session and that listen to new sessionId?
|
||||
// for now decrypt sync
|
||||
try {
|
||||
val result = session.decryptEvent(event.root, event.root.roomId + UUID.randomUUID().toString())
|
||||
val result = session.cryptoService().decryptEvent(event.root, event.root.roomId + UUID.randomUUID().toString())
|
||||
event.root.mxDecryptionResult = OlmDecryptionResult(
|
||||
payload = result.clearEvent,
|
||||
senderKey = result.senderCurve25519Key,
|
||||
|
@ -211,7 +211,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes
|
||||
activeSessionHolder.getSafeActiveSession()?.let { session ->
|
||||
userId = session.myUserId
|
||||
deviceId = session.sessionParams.credentials.deviceId ?: "undefined"
|
||||
olmVersion = session.getCryptoVersion(context, true)
|
||||
olmVersion = session.cryptoService().getCryptoVersion(context, true)
|
||||
}
|
||||
|
||||
if (!mIsCancelled) {
|
||||
|
@ -148,7 +148,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
|
||||
// ok, let's find or create the DM room
|
||||
_viewEvents.post(RoomMemberProfileViewEvents.StartVerification(
|
||||
userId = state.userId,
|
||||
canCrossSign = session.getCrossSigningService().canCrossSign()
|
||||
canCrossSign = session.cryptoService().crossSigningService().canCrossSign()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
|
||||
}
|
||||
|
||||
private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) {
|
||||
session.getVerificationService().beginKeyVerification(VerificationMethod.SAS, userId, action.deviceId, null)?.let { txID ->
|
||||
session.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, userId, action.deviceId, null)?.let { txID ->
|
||||
_viewEvents.post(DeviceListBottomSheetViewEvents.Verify(userId, txID))
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||
room.rx().liveRoomMembers(roomMemberQueryParams)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.switchMap { membersSummary ->
|
||||
session.getLiveCryptoDeviceInfo(membersSummary.map { it.userId })
|
||||
session.cryptoService().getLiveCryptoDeviceInfo(membersSummary.map { it.userId })
|
||||
.asObservable()
|
||||
.doOnError { Timber.e(it) }
|
||||
.map { deviceList ->
|
||||
@ -104,7 +104,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||
val allDeviceTrusted = it.value.fold(it.value.isNotEmpty()) { prev, next ->
|
||||
prev && next.trustLevel?.isCrossSigningVerified().orFalse()
|
||||
}
|
||||
if (session.getCrossSigningService().getUserCrossSigningKeys(it.key)?.isTrusted().orFalse()) {
|
||||
if (session.cryptoService().crossSigningService().getUserCrossSigningKeys(it.key)?.isTrusted().orFalse()) {
|
||||
if (allDeviceTrusted) RoomEncryptionTrustLevel.Trusted else RoomEncryptionTrustLevel.Warning
|
||||
} else {
|
||||
RoomEncryptionTrustLevel.Default
|
||||
|
@ -77,7 +77,7 @@ class VectorSettingsHelpAboutFragment @Inject constructor(
|
||||
|
||||
// olm version
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_OLM_VERSION_PREFERENCE_KEY)!!
|
||||
.summary = session.getCryptoVersion(requireContext(), false)
|
||||
.summary = session.cryptoService().getCryptoVersion(requireContext(), false)
|
||||
|
||||
// copyright
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_COPYRIGHT_PREFERENCE_KEY)!!
|
||||
|
@ -37,7 +37,7 @@ class VectorSettingsLabsFragment @Inject constructor(
|
||||
// val useCryptoPref = findPreference(VectorPreferences.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY) as SwitchPreference
|
||||
// val cryptoIsEnabledPref = findPreference(VectorPreferences.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY)
|
||||
|
||||
if (session.isCryptoEnabled()) {
|
||||
if (session.cryptoService().isCryptoEnabled()) {
|
||||
// mLabsCategory.removePreference(useCryptoPref)
|
||||
//
|
||||
// cryptoIsEnabledPref.isEnabled = false
|
||||
|
@ -134,10 +134,10 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
||||
|
||||
private fun refreshXSigningStatus() {
|
||||
if (vectorPreferences.developerMode()) {
|
||||
val crossSigningKeys = session.getCrossSigningService().getMyCrossSigningKeys()
|
||||
val crossSigningKeys = session.cryptoService().crossSigningService().getMyCrossSigningKeys()
|
||||
val xSigningIsEnableInAccount = crossSigningKeys != null
|
||||
val xSigningKeysAreTrusted = session.getCrossSigningService().checkUserTrust(session.myUserId).isVerified()
|
||||
val xSigningKeyCanSign = session.getCrossSigningService().canCrossSign()
|
||||
val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified()
|
||||
val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign()
|
||||
|
||||
if (xSigningKeyCanSign) {
|
||||
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_trusted)
|
||||
@ -412,10 +412,10 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
||||
|
||||
sendToUnverifiedDevicesPref.isChecked = false
|
||||
|
||||
sendToUnverifiedDevicesPref.isChecked = session.getGlobalBlacklistUnverifiedDevices()
|
||||
sendToUnverifiedDevicesPref.isChecked = session.cryptoService().getGlobalBlacklistUnverifiedDevices()
|
||||
|
||||
sendToUnverifiedDevicesPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
session.setGlobalBlacklistUnverifiedDevices(sendToUnverifiedDevicesPref.isChecked)
|
||||
session.cryptoService().setGlobalBlacklistUnverifiedDevices(sendToUnverifiedDevicesPref.isChecked)
|
||||
|
||||
true
|
||||
}
|
||||
@ -426,7 +426,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
||||
// ==============================================================================================================
|
||||
|
||||
private fun refreshMyDevice() {
|
||||
session.getUserDevices(session.myUserId).map {
|
||||
session.cryptoService().getUserDevices(session.myUserId).map {
|
||||
DeviceInfo(
|
||||
user_id = session.myUserId,
|
||||
deviceId = it.deviceId,
|
||||
@ -436,7 +436,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
||||
refreshCryptographyPreference(it)
|
||||
}
|
||||
// TODO Move to a ViewModel...
|
||||
session.getDevicesList(object : MatrixCallback<DevicesListResponse> {
|
||||
session.cryptoService().getDevicesList(object : MatrixCallback<DevicesListResponse> {
|
||||
override fun onSuccess(data: DevicesListResponse) {
|
||||
if (isAdded) {
|
||||
refreshCryptographyPreference(data.devices ?: emptyList())
|
||||
|
@ -57,8 +57,8 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted privat
|
||||
.execute {
|
||||
val crossSigningKeys = it.invoke()?.getOrNull()
|
||||
val xSigningIsEnableInAccount = crossSigningKeys != null
|
||||
val xSigningKeysAreTrusted = session.getCrossSigningService().checkUserTrust(session.myUserId).isVerified()
|
||||
val xSigningKeyCanSign = session.getCrossSigningService().canCrossSign()
|
||||
val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified()
|
||||
val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign()
|
||||
copy(
|
||||
crossSigningInfo = crossSigningKeys,
|
||||
xSigningIsEnableInAccount = xSigningIsEnableInAccount,
|
||||
@ -97,7 +97,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted privat
|
||||
setState {
|
||||
copy(isUploadingKeys = true)
|
||||
}
|
||||
session.getCrossSigningService().initializeCrossSigning(auth, object : MatrixCallback<Unit> {
|
||||
session.cryptoService().crossSigningService().initializeCrossSigning(auth, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
_pendingSession = null
|
||||
|
||||
|
@ -63,7 +63,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
|
||||
setState {
|
||||
copy(deviceInfo = Loading())
|
||||
}
|
||||
session.getDeviceInfo(deviceId, object : MatrixCallback<DeviceInfo> {
|
||||
session.cryptoService().getDeviceInfo(deviceId, object : MatrixCallback<DeviceInfo> {
|
||||
override fun onSuccess(data: DeviceInfo) {
|
||||
setState {
|
||||
copy(deviceInfo = Success(data))
|
||||
|
@ -74,7 +74,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
|
||||
init {
|
||||
refreshDevicesList()
|
||||
session.getVerificationService().addListener(this)
|
||||
session.cryptoService().verificationService().addListener(this)
|
||||
|
||||
session.rx().liveUserCryptoDevices(session.myUserId)
|
||||
.execute {
|
||||
@ -85,7 +85,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
session.getVerificationService().removeListener(this)
|
||||
session.cryptoService().verificationService().removeListener(this)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
private fun refreshDevicesList() {
|
||||
if (!session.sessionParams.credentials.deviceId.isNullOrEmpty()) {
|
||||
// display something asap
|
||||
val localKnown = session.getUserDevices(session.myUserId).map {
|
||||
val localKnown = session.cryptoService().getUserDevices(session.myUserId).map {
|
||||
DeviceInfo(
|
||||
user_id = session.myUserId,
|
||||
deviceId = it.deviceId,
|
||||
@ -118,7 +118,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
)
|
||||
}
|
||||
|
||||
session.getDevicesList(object : MatrixCallback<DevicesListResponse> {
|
||||
session.cryptoService().getDevicesList(object : MatrixCallback<DevicesListResponse> {
|
||||
override fun onSuccess(data: DevicesListResponse) {
|
||||
setState {
|
||||
copy(
|
||||
@ -141,16 +141,16 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
setState {
|
||||
copy(
|
||||
myDeviceId = session.sessionParams.credentials.deviceId ?: "",
|
||||
cryptoDevices = Success(session.getUserDevices(session.myUserId))
|
||||
cryptoDevices = Success(session.cryptoService().getUserDevices(session.myUserId))
|
||||
)
|
||||
}
|
||||
|
||||
// then force download
|
||||
session.downloadKeys(listOf(session.myUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
session.cryptoService().downloadKeys(listOf(session.myUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<CryptoDeviceInfo>) {
|
||||
setState {
|
||||
copy(
|
||||
cryptoDevices = Success(session.getUserDevices(session.myUserId))
|
||||
cryptoDevices = Success(session.cryptoService().getUserDevices(session.myUserId))
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -172,7 +172,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
}
|
||||
|
||||
private fun handleVerify(action: DevicesAction.VerifyMyDevice) {
|
||||
val txID = session.getVerificationService().requestKeyVerification(supportedVerificationMethods, session.myUserId, listOf(action.deviceId))
|
||||
val txID = session.cryptoService().verificationService().requestKeyVerification(supportedVerificationMethods, session.myUserId, listOf(action.deviceId))
|
||||
_viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
|
||||
session.myUserId,
|
||||
txID.transactionId
|
||||
@ -187,7 +187,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
}
|
||||
|
||||
private fun handleRename(action: DevicesAction.Rename) {
|
||||
session.setDeviceName(action.deviceId, action.newName, object : MatrixCallback<Unit> {
|
||||
session.cryptoService().setDeviceName(action.deviceId, action.newName, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
setState {
|
||||
copy(
|
||||
@ -222,7 +222,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
)
|
||||
}
|
||||
|
||||
session.deleteDevice(deviceId, object : MatrixCallback<Unit> {
|
||||
session.cryptoService().deleteDevice(deviceId, object : MatrixCallback<Unit> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
var isPasswordRequestFound = false
|
||||
|
||||
@ -284,7 +284,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||
)
|
||||
}
|
||||
|
||||
session.deleteDeviceWithUserPassword(currentDeviceId, _currentSession, action.password, object : MatrixCallback<Unit> {
|
||||
session.cryptoService().deleteDeviceWithUserPassword(currentDeviceId, _currentSession, action.password, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
_currentDeviceId = null
|
||||
_currentSession = null
|
||||
|
@ -40,7 +40,7 @@ class AccountDataViewModel @AssistedInject constructor(@Assisted initialState: A
|
||||
: VectorViewModel<AccountDataViewState, EmptyAction, EmptyViewEvents>(initialState) {
|
||||
|
||||
init {
|
||||
session.rx().liveAccountData(emptyList())
|
||||
session.rx().liveAccountData(emptySet())
|
||||
.execute {
|
||||
copy(accountData = it)
|
||||
}
|
||||
|
@ -30,36 +30,36 @@ class SignOutViewModel @Inject constructor(private val session: Session) : ViewM
|
||||
var keysBackupState = MutableLiveData<KeysBackupState>()
|
||||
|
||||
init {
|
||||
session.getKeysBackupService().addListener(this)
|
||||
session.cryptoService().keysBackupService().addListener(this)
|
||||
|
||||
keysBackupState.value = session.getKeysBackupService().state
|
||||
keysBackupState.value = session.cryptoService().keysBackupService().state
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe way to get the current KeysBackup version
|
||||
*/
|
||||
fun getCurrentBackupVersion(): String {
|
||||
return session.getKeysBackupService().currentBackupVersion ?: ""
|
||||
return session.cryptoService().keysBackupService().currentBackupVersion ?: ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe way to get the number of keys to backup
|
||||
*/
|
||||
fun getNumberOfKeysToBackup(): Int {
|
||||
return session.inboundGroupSessionsCount(false)
|
||||
return session.cryptoService().inboundGroupSessionsCount(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe way to tell if there are more keys on the server
|
||||
*/
|
||||
fun canRestoreKeys(): Boolean {
|
||||
return session.getKeysBackupService().canRestoreKeys()
|
||||
return session.cryptoService().keysBackupService().canRestoreKeys()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
|
||||
session.getKeysBackupService().removeListener(this)
|
||||
session.cryptoService().keysBackupService().removeListener(this)
|
||||
}
|
||||
|
||||
override fun onStateChange(newState: KeysBackupState) {
|
||||
@ -68,7 +68,7 @@ class SignOutViewModel @Inject constructor(private val session: Session) : ViewM
|
||||
|
||||
fun refreshRemoteStateIfNeeded() {
|
||||
if (keysBackupState.value == KeysBackupState.Disabled) {
|
||||
session.getKeysBackupService().checkAndStartKeysBackup()
|
||||
session.cryptoService().keysBackupService().checkAndStartKeysBackup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user