Do some cleanup on verification APIs
This commit is contained in:
parent
309a290cb8
commit
8bd094fa66
@ -30,8 +30,7 @@ import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
|||||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction
|
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
@ -311,16 +310,16 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we should reach SHOW SAS on both
|
// we should reach SHOW SAS on both
|
||||||
var alicePovTx: OutgoingSasVerificationTransaction? = null
|
var alicePovTx: SasVerificationTransaction? = null
|
||||||
var bobPovTx: IncomingSasVerificationTransaction? = null
|
var bobPovTx: SasVerificationTransaction? = null
|
||||||
|
|
||||||
// wait for alice to get the ready
|
// wait for alice to get the ready
|
||||||
testHelper.waitWithLatch {
|
testHelper.waitWithLatch {
|
||||||
testHelper.retryPeriodicallyWithLatch(it) {
|
testHelper.retryPeriodicallyWithLatch(it) {
|
||||||
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? IncomingSasVerificationTransaction
|
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? SasVerificationTransaction
|
||||||
Log.v("TEST", "== bobPovTx is ${alicePovTx?.uxState}")
|
Log.v("TEST", "== bobPovTx is ${bobPovTx?.state}")
|
||||||
if (bobPovTx?.state == VerificationTxState.OnStarted) {
|
if (bobPovTx?.state == VerificationTxState.OnStarted) {
|
||||||
bobPovTx?.performAccept()
|
bobPovTx?.acceptVerification()
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -330,18 +329,18 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
|||||||
|
|
||||||
testHelper.waitWithLatch {
|
testHelper.waitWithLatch {
|
||||||
testHelper.retryPeriodicallyWithLatch(it) {
|
testHelper.retryPeriodicallyWithLatch(it) {
|
||||||
alicePovTx = aliceVerificationService.getExistingTransaction(bob.myUserId, requestID) as? OutgoingSasVerificationTransaction
|
alicePovTx = aliceVerificationService.getExistingTransaction(bob.myUserId, requestID) as? SasVerificationTransaction
|
||||||
Log.v("TEST", "== alicePovTx is ${alicePovTx?.uxState}")
|
Log.v("TEST", "== alicePovTx is ${alicePovTx?.state}")
|
||||||
alicePovTx?.state == VerificationTxState.ShortCodeReady
|
alicePovTx?.state == VerificationTxState.ShortCodeReady
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// wait for alice to get the ready
|
// wait for alice to get the ready
|
||||||
testHelper.waitWithLatch {
|
testHelper.waitWithLatch {
|
||||||
testHelper.retryPeriodicallyWithLatch(it) {
|
testHelper.retryPeriodicallyWithLatch(it) {
|
||||||
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? IncomingSasVerificationTransaction
|
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? SasVerificationTransaction
|
||||||
Log.v("TEST", "== bobPovTx is ${alicePovTx?.uxState}")
|
Log.v("TEST", "== bobPovTx is ${bobPovTx?.state}")
|
||||||
if (bobPovTx?.state == VerificationTxState.OnStarted) {
|
if (bobPovTx?.state == VerificationTxState.OnStarted) {
|
||||||
bobPovTx?.performAccept()
|
bobPovTx?.acceptVerification()
|
||||||
}
|
}
|
||||||
bobPovTx?.state == VerificationTxState.ShortCodeReady
|
bobPovTx?.state == VerificationTxState.ShortCodeReady
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.crosssigning
|
|||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertNotNull
|
import org.junit.Assert.assertNotNull
|
||||||
@ -53,7 +54,7 @@ class XSigningTest : InstrumentedTest {
|
|||||||
fun test_InitializeAndStoreKeys() {
|
fun test_InitializeAndStoreKeys() {
|
||||||
val aliceSession = testHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
|
val aliceSession = testHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
|
||||||
|
|
||||||
testHelper.doSync<Unit> {
|
testHelper.runBlockingTest {
|
||||||
aliceSession.cryptoService().crossSigningService()
|
aliceSession.cryptoService().crossSigningService()
|
||||||
.initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
.initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
@ -65,10 +66,12 @@ class XSigningTest : InstrumentedTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, it)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val myCrossSigningKeys = aliceSession.cryptoService().crossSigningService().getMyCrossSigningKeys()
|
val myCrossSigningKeys = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().crossSigningService().getMyCrossSigningKeys()
|
||||||
|
}
|
||||||
val masterPubKey = myCrossSigningKeys?.masterKey()
|
val masterPubKey = myCrossSigningKeys?.masterKey()
|
||||||
assertNotNull("Master key should be stored", masterPubKey?.unpaddedBase64PublicKey)
|
assertNotNull("Master key should be stored", masterPubKey?.unpaddedBase64PublicKey)
|
||||||
val selfSigningKey = myCrossSigningKeys?.selfSigningKey()
|
val selfSigningKey = myCrossSigningKeys?.selfSigningKey()
|
||||||
@ -78,7 +81,10 @@ class XSigningTest : InstrumentedTest {
|
|||||||
|
|
||||||
assertTrue("Signing Keys should be trusted", myCrossSigningKeys?.isTrusted() == true)
|
assertTrue("Signing Keys should be trusted", myCrossSigningKeys?.isTrusted() == true)
|
||||||
|
|
||||||
assertTrue("Signing Keys should be trusted", aliceSession.cryptoService().crossSigningService().checkUserTrust(aliceSession.myUserId).isVerified())
|
val userTrustResult = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().crossSigningService().checkUserTrust(aliceSession.myUserId)
|
||||||
|
}
|
||||||
|
assertTrue("Signing Keys should be trusted", userTrustResult.isVerified())
|
||||||
|
|
||||||
testHelper.signOutAndClose(aliceSession)
|
testHelper.signOutAndClose(aliceSession)
|
||||||
}
|
}
|
||||||
@ -99,29 +105,37 @@ class XSigningTest : InstrumentedTest {
|
|||||||
password = TestConstants.PASSWORD
|
password = TestConstants.PASSWORD
|
||||||
)
|
)
|
||||||
|
|
||||||
testHelper.doSync<Unit> {
|
testHelper.runBlockingTest {
|
||||||
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
promise.resume(aliceAuthParams)
|
promise.resume(aliceAuthParams)
|
||||||
}
|
}
|
||||||
}, it)
|
})
|
||||||
}
|
}
|
||||||
testHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
testHelper.runBlockingTest {
|
||||||
|
bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
promise.resume(bobAuthParams)
|
promise.resume(bobAuthParams)
|
||||||
}
|
}
|
||||||
}, it) }
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Check that alice can see bob keys
|
// Check that alice can see bob keys
|
||||||
testHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true) }
|
testHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true) }
|
||||||
|
|
||||||
val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
|
val bobKeysFromAlicePOV = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
|
||||||
|
}
|
||||||
assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey())
|
assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey())
|
||||||
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
|
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
|
||||||
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
|
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
|
||||||
|
|
||||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
|
val myKeys = testHelper.runBlockingTest {
|
||||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
|
bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, myKeys?.masterKey()?.unpaddedBase64PublicKey)
|
||||||
|
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, myKeys?.selfSigningKey()?.unpaddedBase64PublicKey)
|
||||||
|
|
||||||
assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())
|
assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())
|
||||||
|
|
||||||
@ -145,25 +159,33 @@ class XSigningTest : InstrumentedTest {
|
|||||||
password = TestConstants.PASSWORD
|
password = TestConstants.PASSWORD
|
||||||
)
|
)
|
||||||
|
|
||||||
testHelper.doSync<Unit> { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
promise.resume(aliceAuthParams)
|
promise.resume(aliceAuthParams)
|
||||||
}
|
}
|
||||||
}, it) }
|
})
|
||||||
testHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
}
|
||||||
|
testHelper.runBlockingTest {
|
||||||
|
bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
promise.resume(bobAuthParams)
|
promise.resume(bobAuthParams)
|
||||||
}
|
}
|
||||||
}, it) }
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Check that alice can see bob keys
|
// Check that alice can see bob keys
|
||||||
val bobUserId = bobSession.myUserId
|
val bobUserId = bobSession.myUserId
|
||||||
testHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true) }
|
testHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true) }
|
||||||
|
|
||||||
val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobUserId)
|
val bobKeysFromAlicePOV = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobUserId)
|
||||||
|
}
|
||||||
assertTrue("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV?.isTrusted() == false)
|
assertTrue("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV?.isTrusted() == false)
|
||||||
|
|
||||||
testHelper.doSync<Unit> { aliceSession.cryptoService().crossSigningService().trustUser(bobUserId, it) }
|
testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().crossSigningService().trustUser(bobUserId)
|
||||||
|
}
|
||||||
|
|
||||||
// Now bobs logs in on a new device and verifies it
|
// Now bobs logs in on a new device and verifies it
|
||||||
// We will want to test that in alice POV, this new device would be trusted by cross signing
|
// We will want to test that in alice POV, this new device would be trusted by cross signing
|
||||||
@ -180,7 +202,9 @@ class XSigningTest : InstrumentedTest {
|
|||||||
fail("Bob should see the new device")
|
fail("Bob should see the new device")
|
||||||
}
|
}
|
||||||
|
|
||||||
val bobSecondDevicePOVFirstDevice = bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId)
|
val bobSecondDevicePOVFirstDevice = runBlocking {
|
||||||
|
bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId)
|
||||||
|
}
|
||||||
assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice)
|
assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice)
|
||||||
|
|
||||||
// Manually mark it as trusted from first session
|
// Manually mark it as trusted from first session
|
||||||
@ -198,7 +222,9 @@ class XSigningTest : InstrumentedTest {
|
|||||||
fail("Alice should see the new device")
|
fail("Alice should see the new device")
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = aliceSession.cryptoService().crossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null)
|
val result = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().crossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null)
|
||||||
|
}
|
||||||
assertTrue("Bob second device should be trusted from alice POV", result.isCrossSignedVerified())
|
assertTrue("Bob second device should be trusted from alice POV", result.isCrossSignedVerified())
|
||||||
|
|
||||||
testHelper.signOutAndClose(aliceSession)
|
testHelper.signOutAndClose(aliceSession)
|
||||||
|
@ -24,7 +24,6 @@ import junit.framework.TestCase.assertNotNull
|
|||||||
import junit.framework.TestCase.assertTrue
|
import junit.framework.TestCase.assertTrue
|
||||||
import junit.framework.TestCase.fail
|
import junit.framework.TestCase.fail
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.FixMethodOrder
|
import org.junit.FixMethodOrder
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
@ -37,7 +36,6 @@ import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
|||||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||||
@ -250,35 +248,34 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
|
|
||||||
aliceVerificationService1.addListener(object : VerificationService.Listener {
|
aliceVerificationService1.addListener(object : VerificationService.Listener {
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
|
if (tx !is SasVerificationTransaction) return
|
||||||
Log.d("#TEST", "AA: tx incoming?:${tx.isIncoming} state ${tx.state}")
|
Log.d("#TEST", "AA: tx incoming?:${tx.isIncoming} state ${tx.state}")
|
||||||
if (tx is SasVerificationTransaction) {
|
when (tx.state) {
|
||||||
if (tx.state == VerificationTxState.OnStarted) {
|
VerificationTxState.OnStarted -> commonTestHelper.runBlockingTest {
|
||||||
(tx as IncomingSasVerificationTransaction).performAccept()
|
tx.acceptVerification()
|
||||||
}
|
}
|
||||||
if (tx.state == VerificationTxState.ShortCodeReady) {
|
VerificationTxState.ShortCodeReady -> commonTestHelper.runBlockingTest {
|
||||||
session1ShortCode = tx.getDecimalCodeRepresentation()
|
session1ShortCode = tx.getDecimalCodeRepresentation()
|
||||||
commonTestHelper.runBlockingTest {
|
|
||||||
delay(500)
|
delay(500)
|
||||||
tx.userHasVerifiedShortCode()
|
tx.userHasVerifiedShortCode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
aliceVerificationService2.addListener(object : VerificationService.Listener {
|
aliceVerificationService2.addListener(object : VerificationService.Listener {
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
|
if (tx !is SasVerificationTransaction) return
|
||||||
Log.d("#TEST", "BB: tx incoming?:${tx.isIncoming} state ${tx.state}")
|
Log.d("#TEST", "BB: tx incoming?:${tx.isIncoming} state ${tx.state}")
|
||||||
if (tx is SasVerificationTransaction) {
|
when (tx.state) {
|
||||||
if (tx.state == VerificationTxState.ShortCodeReady) {
|
VerificationTxState.ShortCodeReady -> commonTestHelper.runBlockingTest {
|
||||||
session2ShortCode = tx.getDecimalCodeRepresentation()
|
session2ShortCode = tx.getDecimalCodeRepresentation()
|
||||||
commonTestHelper.runBlockingTest {
|
|
||||||
delay(500)
|
delay(500)
|
||||||
tx.userHasVerifiedShortCode()
|
tx.userHasVerifiedShortCode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
val txId = "m.testVerif12"
|
val txId = "m.testVerif12"
|
||||||
@ -301,7 +298,8 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
|
|
||||||
// SSK and USK private keys should have been shared
|
// SSK and USK private keys should have been shared
|
||||||
|
|
||||||
commonTestHelper.waitWithLatch(60_000) { latch ->
|
commonTestHelper.waitWithLatch(60_000)
|
||||||
|
{ latch ->
|
||||||
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
||||||
Log.d("#TEST", "CAN XS :${aliceSession2.cryptoService().crossSigningService().getMyCrossSigningKeys()}")
|
Log.d("#TEST", "CAN XS :${aliceSession2.cryptoService().crossSigningService().getMyCrossSigningKeys()}")
|
||||||
aliceSession2.cryptoService().crossSigningService().canCrossSign()
|
aliceSession2.cryptoService().crossSigningService().canCrossSign()
|
||||||
@ -309,7 +307,8 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test that key backup key has been shared to
|
// Test that key backup key has been shared to
|
||||||
commonTestHelper.waitWithLatch(60_000) { latch ->
|
commonTestHelper.waitWithLatch(60_000)
|
||||||
|
{ latch ->
|
||||||
val keysBackupService = aliceSession2.cryptoService().keysBackupService()
|
val keysBackupService = aliceSession2.cryptoService().keysBackupService()
|
||||||
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
||||||
Log.d("#TEST", "Recovery :${keysBackupService.getKeyBackupRecoveryKeyInfo()?.recoveryKey}")
|
Log.d("#TEST", "Recovery :${keysBackupService.getKeyBackupRecoveryKeyInfo()?.recoveryKey}")
|
||||||
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.verification
|
|||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertNotNull
|
import org.junit.Assert.assertNotNull
|
||||||
@ -32,9 +33,7 @@ import org.junit.runners.MethodSorters
|
|||||||
import org.matrix.android.sdk.InstrumentedTest
|
import org.matrix.android.sdk.InstrumentedTest
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction
|
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.SasMode
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||||
@ -49,6 +48,8 @@ import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
|
|||||||
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel
|
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart
|
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
|
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.UUID
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@ -75,10 +76,15 @@ class SASTest : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
bobVerificationService.addListener(bobListener)
|
bobVerificationService.addListener(bobListener)
|
||||||
|
|
||||||
val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
|
val myDevice = testHelper.runBlockingTest {
|
||||||
|
bobSession.cryptoService().getMyDevice()
|
||||||
|
}
|
||||||
|
val txID = testHelper.runBlockingTest {
|
||||||
|
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
|
||||||
bobSession.myUserId,
|
bobSession.myUserId,
|
||||||
bobSession.cryptoService().getMyDevice().deviceId,
|
myDevice.deviceId,
|
||||||
null)
|
null)
|
||||||
|
}
|
||||||
assertNotNull("Alice should have a started transaction", txID)
|
assertNotNull("Alice should have a started transaction", txID)
|
||||||
|
|
||||||
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
|
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
|
||||||
@ -90,16 +96,14 @@ class SASTest : InstrumentedTest {
|
|||||||
val bobKeyTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID)
|
val bobKeyTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID)
|
||||||
|
|
||||||
assertNotNull("Bob should have started verif transaction", bobKeyTx)
|
assertNotNull("Bob should have started verif transaction", bobKeyTx)
|
||||||
assertTrue(bobKeyTx is SASDefaultVerificationTransaction)
|
assertTrue(bobKeyTx is SasVerificationTransaction)
|
||||||
assertNotNull("Bob should have starting a SAS transaction", bobKeyTx)
|
assertNotNull("Bob should have starting a SAS transaction", bobKeyTx)
|
||||||
assertTrue(aliceKeyTx is SASDefaultVerificationTransaction)
|
assertTrue(aliceKeyTx is SasVerificationTransaction)
|
||||||
assertEquals("Alice and Bob have same transaction id", aliceKeyTx!!.transactionId, bobKeyTx!!.transactionId)
|
assertEquals("Alice and Bob have same transaction id", aliceKeyTx!!.transactionId, bobKeyTx!!.transactionId)
|
||||||
|
|
||||||
val aliceSasTx = aliceKeyTx as SASDefaultVerificationTransaction?
|
|
||||||
val bobSasTx = bobKeyTx as SASDefaultVerificationTransaction?
|
|
||||||
|
|
||||||
assertEquals("Alice state should be started", VerificationTxState.Started, aliceSasTx!!.state)
|
assertEquals("Alice state should be started", VerificationTxState.Started, aliceKeyTx.state)
|
||||||
assertEquals("Bob state should be started by alice", VerificationTxState.OnStarted, bobSasTx!!.state)
|
assertEquals("Bob state should be started by alice", VerificationTxState.OnStarted, bobKeyTx.state)
|
||||||
|
|
||||||
// Let's cancel from alice side
|
// Let's cancel from alice side
|
||||||
val cancelLatch = CountDownLatch(1)
|
val cancelLatch = CountDownLatch(1)
|
||||||
@ -107,7 +111,7 @@ class SASTest : InstrumentedTest {
|
|||||||
val bobListener2 = object : VerificationService.Listener {
|
val bobListener2 = object : VerificationService.Listener {
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
if (tx.transactionId == txID) {
|
if (tx.transactionId == txID) {
|
||||||
val immutableState = (tx as SASDefaultVerificationTransaction).state
|
val immutableState = (tx as SasVerificationTransaction).state
|
||||||
if (immutableState is VerificationTxState.Cancelled && !immutableState.byMe) {
|
if (immutableState is VerificationTxState.Cancelled && !immutableState.byMe) {
|
||||||
cancelLatch.countDown()
|
cancelLatch.countDown()
|
||||||
}
|
}
|
||||||
@ -116,14 +120,16 @@ class SASTest : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
bobVerificationService.addListener(bobListener2)
|
bobVerificationService.addListener(bobListener2)
|
||||||
|
|
||||||
aliceSasTx.cancel(CancelCode.User)
|
testHelper.runBlockingTest {
|
||||||
|
aliceKeyTx.cancel(CancelCode.User)
|
||||||
|
}
|
||||||
testHelper.await(cancelLatch)
|
testHelper.await(cancelLatch)
|
||||||
|
|
||||||
assertTrue("Should be cancelled on alice side", aliceSasTx.state is VerificationTxState.Cancelled)
|
assertTrue("Should be cancelled on alice side", aliceKeyTx.state is VerificationTxState.Cancelled)
|
||||||
assertTrue("Should be cancelled on bob side", bobSasTx.state is VerificationTxState.Cancelled)
|
assertTrue("Should be cancelled on bob side", bobKeyTx.state is VerificationTxState.Cancelled)
|
||||||
|
|
||||||
val aliceCancelState = aliceSasTx.state as VerificationTxState.Cancelled
|
val aliceCancelState = aliceKeyTx.state as VerificationTxState.Cancelled
|
||||||
val bobCancelState = bobSasTx.state as VerificationTxState.Cancelled
|
val bobCancelState = bobKeyTx.state as VerificationTxState.Cancelled
|
||||||
|
|
||||||
assertTrue("Should be cancelled by me on alice side", aliceCancelState.byMe)
|
assertTrue("Should be cancelled by me on alice side", aliceCancelState.byMe)
|
||||||
assertFalse("Should be cancelled by other on bob side", bobCancelState.byMe)
|
assertFalse("Should be cancelled by other on bob side", bobCancelState.byMe)
|
||||||
@ -177,12 +183,16 @@ class SASTest : InstrumentedTest {
|
|||||||
|
|
||||||
val aliceSession = cryptoTestData.firstSession
|
val aliceSession = cryptoTestData.firstSession
|
||||||
val aliceUserID = aliceSession.myUserId
|
val aliceUserID = aliceSession.myUserId
|
||||||
val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
|
val aliceDevice = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().getMyDevice().deviceId
|
||||||
|
}
|
||||||
|
|
||||||
val aliceListener = object : VerificationService.Listener {
|
val aliceListener = object : VerificationService.Listener {
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
|
if (tx.state is VerificationTxState.OnStarted && tx is SasVerificationTransaction) {
|
||||||
(tx as IncomingSasVerificationTransaction).performAccept()
|
testHelper.runBlockingTest {
|
||||||
|
tx.acceptVerification()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,7 +236,9 @@ class SASTest : InstrumentedTest {
|
|||||||
|
|
||||||
val aliceSession = cryptoTestData.firstSession
|
val aliceSession = cryptoTestData.firstSession
|
||||||
val aliceUserID = aliceSession.myUserId
|
val aliceUserID = aliceSession.myUserId
|
||||||
val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
|
val aliceDevice = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().getMyDevice().deviceId
|
||||||
|
}
|
||||||
|
|
||||||
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, mac = mac)
|
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, mac = mac)
|
||||||
|
|
||||||
@ -267,7 +279,9 @@ class SASTest : InstrumentedTest {
|
|||||||
|
|
||||||
val aliceSession = cryptoTestData.firstSession
|
val aliceSession = cryptoTestData.firstSession
|
||||||
val aliceUserID = aliceSession.myUserId
|
val aliceUserID = aliceSession.myUserId
|
||||||
val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
|
val aliceDevice = testHelper.runBlockingTest {
|
||||||
|
aliceSession.cryptoService().getMyDevice().deviceId
|
||||||
|
}
|
||||||
|
|
||||||
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, codes = codes)
|
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, codes = codes)
|
||||||
|
|
||||||
@ -283,12 +297,15 @@ class SASTest : InstrumentedTest {
|
|||||||
aliceUserID: String?,
|
aliceUserID: String?,
|
||||||
aliceDevice: String?,
|
aliceDevice: String?,
|
||||||
tid: String,
|
tid: String,
|
||||||
protocols: List<String> = SASDefaultVerificationTransaction.KNOWN_AGREEMENT_PROTOCOLS,
|
protocols: List<String> = emptyList(),
|
||||||
hashes: List<String> = SASDefaultVerificationTransaction.KNOWN_HASHES,
|
hashes: List<String> = emptyList(),
|
||||||
mac: List<String> = SASDefaultVerificationTransaction.KNOWN_MACS,
|
mac: List<String> = emptyList(),
|
||||||
codes: List<String> = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES) {
|
codes: List<String> = emptyList()) {
|
||||||
|
val deviceId = runBlocking {
|
||||||
|
bobSession.cryptoService().getMyDevice().deviceId
|
||||||
|
}
|
||||||
val startMessage = KeyVerificationStart(
|
val startMessage = KeyVerificationStart(
|
||||||
fromDevice = bobSession.cryptoService().getMyDevice().deviceId,
|
fromDevice = deviceId,
|
||||||
method = VerificationMethod.SAS.toValue(),
|
method = VerificationMethod.SAS.toValue(),
|
||||||
transactionId = tid,
|
transactionId = tid,
|
||||||
keyAgreementProtocols = protocols,
|
keyAgreementProtocols = protocols,
|
||||||
@ -324,15 +341,15 @@ class SASTest : InstrumentedTest {
|
|||||||
|
|
||||||
val aliceCreatedLatch = CountDownLatch(2)
|
val aliceCreatedLatch = CountDownLatch(2)
|
||||||
val aliceCancelledLatch = CountDownLatch(2)
|
val aliceCancelledLatch = CountDownLatch(2)
|
||||||
val createdTx = mutableListOf<SASDefaultVerificationTransaction>()
|
val createdTx = mutableListOf<VerificationTransaction>()
|
||||||
val aliceListener = object : VerificationService.Listener {
|
val aliceListener = object : VerificationService.Listener {
|
||||||
override fun transactionCreated(tx: VerificationTransaction) {
|
override fun transactionCreated(tx: VerificationTransaction) {
|
||||||
createdTx.add(tx as SASDefaultVerificationTransaction)
|
createdTx.add(tx)
|
||||||
aliceCreatedLatch.countDown()
|
aliceCreatedLatch.countDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
if ((tx as SASDefaultVerificationTransaction).state is VerificationTxState.Cancelled && !(tx.state as VerificationTxState.Cancelled).byMe) {
|
if (tx.state is VerificationTxState.Cancelled && !(tx.state as VerificationTxState.Cancelled).byMe) {
|
||||||
aliceCancelledLatch.countDown()
|
aliceCancelledLatch.countDown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,10 +357,13 @@ class SASTest : InstrumentedTest {
|
|||||||
aliceVerificationService.addListener(aliceListener)
|
aliceVerificationService.addListener(aliceListener)
|
||||||
|
|
||||||
val bobUserId = bobSession!!.myUserId
|
val bobUserId = bobSession!!.myUserId
|
||||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
val bobDeviceId = testHelper.runBlockingTest {
|
||||||
|
bobSession.cryptoService().getMyDevice().deviceId
|
||||||
|
}
|
||||||
|
testHelper.runBlockingTest {
|
||||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||||
|
}
|
||||||
testHelper.await(aliceCreatedLatch)
|
testHelper.await(aliceCreatedLatch)
|
||||||
testHelper.await(aliceCancelledLatch)
|
testHelper.await(aliceCancelledLatch)
|
||||||
|
|
||||||
@ -366,17 +386,10 @@ class SASTest : InstrumentedTest {
|
|||||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||||
|
|
||||||
var accepted: ValidVerificationInfoAccept? = null
|
|
||||||
var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null
|
|
||||||
|
|
||||||
val aliceAcceptedLatch = CountDownLatch(1)
|
val aliceAcceptedLatch = CountDownLatch(1)
|
||||||
val aliceListener = object : VerificationService.Listener {
|
val aliceListener = object : VerificationService.Listener {
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
Log.v("TEST", "== aliceTx state ${tx.state} => ${(tx as? OutgoingSasVerificationTransaction)?.uxState}")
|
if (tx.state is VerificationTxState.OnAccepted) {
|
||||||
if ((tx as SASDefaultVerificationTransaction).state === VerificationTxState.OnAccepted) {
|
|
||||||
val at = tx as SASDefaultVerificationTransaction
|
|
||||||
accepted = at.accepted
|
|
||||||
startReq = at.startReq
|
|
||||||
aliceAcceptedLatch.countDown()
|
aliceAcceptedLatch.countDown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,32 +398,24 @@ class SASTest : InstrumentedTest {
|
|||||||
|
|
||||||
val bobListener = object : VerificationService.Listener {
|
val bobListener = object : VerificationService.Listener {
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
Log.v("TEST", "== bobTx state ${tx.state} => ${(tx as? IncomingSasVerificationTransaction)?.uxState}")
|
if (tx.state is VerificationTxState.OnStarted && tx is SasVerificationTransaction) {
|
||||||
if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
|
|
||||||
bobVerificationService.removeListener(this)
|
bobVerificationService.removeListener(this)
|
||||||
val at = tx as IncomingSasVerificationTransaction
|
testHelper.runBlockingTest {
|
||||||
at.performAccept()
|
tx.acceptVerification()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bobVerificationService.addListener(bobListener)
|
bobVerificationService.addListener(bobListener)
|
||||||
|
|
||||||
val bobUserId = bobSession.myUserId
|
val bobUserId = bobSession.myUserId
|
||||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
val bobDeviceId = runBlocking {
|
||||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
bobSession.cryptoService().getMyDevice().deviceId
|
||||||
testHelper.await(aliceAcceptedLatch)
|
|
||||||
|
|
||||||
assertTrue("Should have receive a commitment", accepted!!.commitment?.trim()?.isEmpty() == false)
|
|
||||||
|
|
||||||
// check that agreement is valid
|
|
||||||
assertTrue("Agreed Protocol should be Valid", accepted != null)
|
|
||||||
assertTrue("Agreed Protocol should be known by alice", startReq!!.keyAgreementProtocols.contains(accepted!!.keyAgreementProtocol))
|
|
||||||
assertTrue("Hash should be known by alice", startReq!!.hashes.contains(accepted!!.hash))
|
|
||||||
assertTrue("Hash should be known by alice", startReq!!.messageAuthenticationCodes.contains(accepted!!.messageAuthenticationCode))
|
|
||||||
|
|
||||||
accepted!!.shortAuthenticationStrings.forEach {
|
|
||||||
assertTrue("all agreed Short Code should be known by alice", startReq!!.shortAuthenticationStrings.contains(it))
|
|
||||||
}
|
}
|
||||||
|
testHelper.runBlockingTest {
|
||||||
|
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||||
|
}
|
||||||
|
testHelper.await(aliceAcceptedLatch)
|
||||||
|
|
||||||
cryptoTestData.cleanUp(testHelper)
|
cryptoTestData.cleanUp(testHelper)
|
||||||
}
|
}
|
||||||
@ -422,17 +427,19 @@ class SASTest : InstrumentedTest {
|
|||||||
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
||||||
|
|
||||||
val aliceSession = cryptoTestData.firstSession
|
val aliceSession = cryptoTestData.firstSession
|
||||||
val bobSession = cryptoTestData.secondSession
|
val bobSession = cryptoTestData.secondSession!!
|
||||||
|
|
||||||
|
cryptoTestHelper.initializeCrossSigning(aliceSession)
|
||||||
|
cryptoTestHelper.initializeCrossSigning(bobSession)
|
||||||
|
|
||||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||||
|
|
||||||
val aliceSASLatch = CountDownLatch(1)
|
val aliceSASLatch = CountDownLatch(1)
|
||||||
val aliceListener = object : VerificationService.Listener {
|
val aliceListener = object : VerificationService.Listener {
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
val uxState = (tx as OutgoingSasVerificationTransaction).uxState
|
when (tx.state) {
|
||||||
when (uxState) {
|
VerificationTxState.ShortCodeReady -> {
|
||||||
OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
|
||||||
aliceSASLatch.countDown()
|
aliceSASLatch.countDown()
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
@ -443,32 +450,42 @@ class SASTest : InstrumentedTest {
|
|||||||
|
|
||||||
val bobSASLatch = CountDownLatch(1)
|
val bobSASLatch = CountDownLatch(1)
|
||||||
val bobListener = object : VerificationService.Listener {
|
val bobListener = object : VerificationService.Listener {
|
||||||
|
|
||||||
|
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
val uxState = (tx as IncomingSasVerificationTransaction).uxState
|
val sasVerification = tx as SasVerificationTransaction
|
||||||
when (uxState) {
|
when (tx.state) {
|
||||||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> {
|
VerificationTxState.OnStarted -> testHelper.runBlockingTest {
|
||||||
tx.performAccept()
|
sasVerification.acceptVerification()
|
||||||
|
}
|
||||||
|
VerificationTxState.ShortCodeReady -> {
|
||||||
|
bobSASLatch.countDown()
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
if (uxState === IncomingSasVerificationTransaction.UxState.SHOW_SAS) {
|
|
||||||
bobSASLatch.countDown()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bobVerificationService.addListener(bobListener)
|
bobVerificationService.addListener(bobListener)
|
||||||
|
|
||||||
val bobUserId = bobSession.myUserId
|
val bobUserId = bobSession.myUserId
|
||||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
testHelper.runBlockingTest {
|
||||||
val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
aliceSession.cryptoService().downloadKeys(listOf(bobUserId), forceDownload = true)
|
||||||
|
aliceVerificationService.requestKeyVerificationInDMs(listOf(VerificationMethod.SAS),bobUserId, cryptoTestData.roomId)
|
||||||
|
}
|
||||||
testHelper.await(aliceSASLatch)
|
testHelper.await(aliceSASLatch)
|
||||||
testHelper.await(bobSASLatch)
|
testHelper.await(bobSASLatch)
|
||||||
|
|
||||||
val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SASDefaultVerificationTransaction
|
/*
|
||||||
val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SASDefaultVerificationTransaction
|
val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SasVerificationTransaction
|
||||||
|
val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SasVerificationTransaction
|
||||||
|
|
||||||
assertEquals("Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL),
|
|
||||||
bobTx.getShortCodeRepresentation(SasMode.DECIMAL))
|
assertEquals("Should have same SAS", aliceTx.getDecimalCodeRepresentation(), bobTx.getDecimalCodeRepresentation())
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
cryptoTestData.cleanUp(testHelper)
|
cryptoTestData.cleanUp(testHelper)
|
||||||
}
|
}
|
||||||
@ -489,13 +506,12 @@ class SASTest : InstrumentedTest {
|
|||||||
val aliceListener = object : VerificationService.Listener {
|
val aliceListener = object : VerificationService.Listener {
|
||||||
var matchOnce = true
|
var matchOnce = true
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
val uxState = (tx as OutgoingSasVerificationTransaction).uxState
|
if (tx !is SasVerificationTransaction) return
|
||||||
Log.v("TEST", "== aliceState ${uxState.name}")
|
when (tx.state) {
|
||||||
when (uxState) {
|
VerificationTxState.ShortCodeReady -> testHelper.runBlockingTest {
|
||||||
OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
|
||||||
tx.userHasVerifiedShortCode()
|
tx.userHasVerifiedShortCode()
|
||||||
}
|
}
|
||||||
OutgoingSasVerificationTransaction.UxState.VERIFIED -> {
|
VerificationTxState.Verified -> {
|
||||||
if (matchOnce) {
|
if (matchOnce) {
|
||||||
matchOnce = false
|
matchOnce = false
|
||||||
aliceSASLatch.countDown()
|
aliceSASLatch.countDown()
|
||||||
@ -512,22 +528,21 @@ class SASTest : InstrumentedTest {
|
|||||||
var acceptOnce = true
|
var acceptOnce = true
|
||||||
var matchOnce = true
|
var matchOnce = true
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
val uxState = (tx as IncomingSasVerificationTransaction).uxState
|
if (tx !is SasVerificationTransaction) return
|
||||||
Log.v("TEST", "== bobState ${uxState.name}")
|
when (tx.state) {
|
||||||
when (uxState) {
|
VerificationTxState.OnStarted -> testHelper.runBlockingTest {
|
||||||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> {
|
|
||||||
if (acceptOnce) {
|
if (acceptOnce) {
|
||||||
acceptOnce = false
|
acceptOnce = false
|
||||||
tx.performAccept()
|
tx.acceptVerification()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IncomingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
VerificationTxState.ShortCodeReady -> testHelper.runBlockingTest {
|
||||||
if (matchOnce) {
|
if (matchOnce) {
|
||||||
matchOnce = false
|
matchOnce = false
|
||||||
tx.userHasVerifiedShortCode()
|
tx.userHasVerifiedShortCode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IncomingSasVerificationTransaction.UxState.VERIFIED -> {
|
VerificationTxState.Verified -> {
|
||||||
bobSASLatch.countDown()
|
bobSASLatch.countDown()
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
@ -537,15 +552,22 @@ class SASTest : InstrumentedTest {
|
|||||||
bobVerificationService.addListener(bobListener)
|
bobVerificationService.addListener(bobListener)
|
||||||
|
|
||||||
val bobUserId = bobSession.myUserId
|
val bobUserId = bobSession.myUserId
|
||||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
val bobDeviceId = runBlocking {
|
||||||
|
bobSession.cryptoService().getMyDevice().deviceId
|
||||||
|
}
|
||||||
|
testHelper.runBlockingTest {
|
||||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||||
|
}
|
||||||
testHelper.await(aliceSASLatch)
|
testHelper.await(aliceSASLatch)
|
||||||
testHelper.await(bobSASLatch)
|
testHelper.await(bobSASLatch)
|
||||||
|
|
||||||
// Assert that devices are verified
|
// Assert that devices are verified
|
||||||
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
|
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = testHelper.runBlockingTest {
|
||||||
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
|
aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
|
||||||
|
}
|
||||||
|
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = testHelper.runBlockingTest {
|
||||||
|
bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
|
||||||
|
}
|
||||||
assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
|
assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
|
||||||
assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
|
assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
|
||||||
cryptoTestData.cleanUp(testHelper)
|
cryptoTestData.cleanUp(testHelper)
|
||||||
@ -563,11 +585,13 @@ class SASTest : InstrumentedTest {
|
|||||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||||
|
|
||||||
val req = aliceVerificationService.requestKeyVerificationInDMs(
|
val req = testHelper.runBlockingTest {
|
||||||
|
aliceVerificationService.requestKeyVerificationInDMs(
|
||||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||||
bobSession.myUserId,
|
bobSession.myUserId,
|
||||||
cryptoTestData.roomId
|
cryptoTestData.roomId
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var requestID: String? = null
|
var requestID: String? = null
|
||||||
|
|
||||||
@ -590,11 +614,13 @@ class SASTest : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testHelper.runBlockingTest {
|
||||||
bobVerificationService.readyPendingVerification(
|
bobVerificationService.readyPendingVerification(
|
||||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||||
aliceSession.myUserId,
|
aliceSession.myUserId,
|
||||||
requestID!!
|
requestID!!
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// wait for alice to get the ready
|
// wait for alice to get the ready
|
||||||
testHelper.waitWithLatch {
|
testHelper.waitWithLatch {
|
||||||
@ -606,6 +632,7 @@ class SASTest : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start concurrent!
|
// Start concurrent!
|
||||||
|
testHelper.runBlockingTest {
|
||||||
aliceVerificationService.beginKeyVerificationInDMs(
|
aliceVerificationService.beginKeyVerificationInDMs(
|
||||||
VerificationMethod.SAS,
|
VerificationMethod.SAS,
|
||||||
requestID!!,
|
requestID!!,
|
||||||
@ -620,6 +647,8 @@ class SASTest : InstrumentedTest {
|
|||||||
aliceSession.myUserId,
|
aliceSession.myUserId,
|
||||||
aliceSession.sessionParams.deviceId!!)
|
aliceSession.sessionParams.deviceId!!)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// we should reach SHOW SAS on both
|
// we should reach SHOW SAS on both
|
||||||
var alicePovTx: SasVerificationTransaction?
|
var alicePovTx: SasVerificationTransaction?
|
||||||
var bobPovTx: SasVerificationTransaction?
|
var bobPovTx: SasVerificationTransaction?
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.crypto.verification.qrcode
|
package org.matrix.android.sdk.internal.crypto.verification
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import org.amshove.kluent.shouldBe
|
import org.amshove.kluent.shouldBe
|
||||||
@ -23,19 +23,13 @@ import org.junit.Test
|
|||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.MethodSorters
|
import org.junit.runners.MethodSorters
|
||||||
import org.matrix.android.sdk.InstrumentedTest
|
import org.matrix.android.sdk.InstrumentedTest
|
||||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
|
||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
|
||||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
|
||||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||||
import org.matrix.android.sdk.common.CommonTestHelper
|
import org.matrix.android.sdk.common.CommonTestHelper
|
||||||
import org.matrix.android.sdk.common.CryptoTestHelper
|
import org.matrix.android.sdk.common.CryptoTestHelper
|
||||||
import org.matrix.android.sdk.common.TestConstants
|
import timber.log.Timber
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import kotlin.coroutines.Continuation
|
|
||||||
import kotlin.coroutines.resume
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@FixMethodOrder(MethodSorters.JVM)
|
@FixMethodOrder(MethodSorters.JVM)
|
||||||
@ -147,8 +141,6 @@ class VerificationTest : InstrumentedTest {
|
|||||||
ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true)
|
ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO Add tests without SAS
|
|
||||||
|
|
||||||
private fun doTest(aliceSupportedMethods: List<VerificationMethod>,
|
private fun doTest(aliceSupportedMethods: List<VerificationMethod>,
|
||||||
bobSupportedMethods: List<VerificationMethod>,
|
bobSupportedMethods: List<VerificationMethod>,
|
||||||
expectedResultForAlice: ExpectedResult,
|
expectedResultForAlice: ExpectedResult,
|
||||||
@ -160,37 +152,8 @@ class VerificationTest : InstrumentedTest {
|
|||||||
val aliceSession = cryptoTestData.firstSession
|
val aliceSession = cryptoTestData.firstSession
|
||||||
val bobSession = cryptoTestData.secondSession!!
|
val bobSession = cryptoTestData.secondSession!!
|
||||||
|
|
||||||
testHelper.doSync<Unit> { callback ->
|
cryptoTestHelper.initializeCrossSigning(aliceSession)
|
||||||
aliceSession.cryptoService().crossSigningService()
|
cryptoTestHelper.initializeCrossSigning(bobSession)
|
||||||
.initializeCrossSigning(
|
|
||||||
object : UserInteractiveAuthInterceptor {
|
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
|
||||||
promise.resume(
|
|
||||||
UserPasswordAuth(
|
|
||||||
user = aliceSession.myUserId,
|
|
||||||
password = TestConstants.PASSWORD,
|
|
||||||
session = flowResponse.session
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
testHelper.doSync<Unit> { callback ->
|
|
||||||
bobSession.cryptoService().crossSigningService()
|
|
||||||
.initializeCrossSigning(
|
|
||||||
object : UserInteractiveAuthInterceptor {
|
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
|
||||||
promise.resume(
|
|
||||||
UserPasswordAuth(
|
|
||||||
user = bobSession.myUserId,
|
|
||||||
password = TestConstants.PASSWORD,
|
|
||||||
session = flowResponse.session
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||||
val bobVerificationService = bobSession.cryptoService().verificationService()
|
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||||
@ -202,6 +165,7 @@ class VerificationTest : InstrumentedTest {
|
|||||||
val aliceListener = object : VerificationService.Listener {
|
val aliceListener = object : VerificationService.Listener {
|
||||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
||||||
// Step 4: Alice receive the ready request
|
// Step 4: Alice receive the ready request
|
||||||
|
Timber.v("Alice is ready: ${pr.isReady}")
|
||||||
if (pr.isReady) {
|
if (pr.isReady) {
|
||||||
aliceReadyPendingVerificationRequest = pr
|
aliceReadyPendingVerificationRequest = pr
|
||||||
latch.countDown()
|
latch.countDown()
|
||||||
@ -213,16 +177,19 @@ class VerificationTest : InstrumentedTest {
|
|||||||
val bobListener = object : VerificationService.Listener {
|
val bobListener = object : VerificationService.Listener {
|
||||||
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
||||||
// Step 2: Bob accepts the verification request
|
// Step 2: Bob accepts the verification request
|
||||||
bobVerificationService.readyPendingVerificationInDMs(
|
Timber.v("Bob accepts the verification request")
|
||||||
|
testHelper.runBlockingTest {
|
||||||
|
bobVerificationService.readyPendingVerification(
|
||||||
bobSupportedMethods,
|
bobSupportedMethods,
|
||||||
aliceSession.myUserId,
|
aliceSession.myUserId,
|
||||||
cryptoTestData.roomId,
|
|
||||||
pr.transactionId!!
|
pr.transactionId!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
||||||
// Step 3: Bob is ready
|
// Step 3: Bob is ready
|
||||||
|
Timber.v("Bob is ready: ${pr.isReady}")
|
||||||
if (pr.isReady) {
|
if (pr.isReady) {
|
||||||
bobReadyPendingVerificationRequest = pr
|
bobReadyPendingVerificationRequest = pr
|
||||||
latch.countDown()
|
latch.countDown()
|
||||||
@ -233,7 +200,9 @@ class VerificationTest : InstrumentedTest {
|
|||||||
|
|
||||||
val bobUserId = bobSession.myUserId
|
val bobUserId = bobSession.myUserId
|
||||||
// Step 1: Alice starts a verification request
|
// Step 1: Alice starts a verification request
|
||||||
|
testHelper.runBlockingTest {
|
||||||
aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId)
|
aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId)
|
||||||
|
}
|
||||||
testHelper.await(latch)
|
testHelper.await(latch)
|
||||||
|
|
||||||
aliceReadyPendingVerificationRequest!!.let { pr ->
|
aliceReadyPendingVerificationRequest!!.let { pr ->
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
*
|
|
||||||
* 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 org.matrix.android.sdk.internal.crypto.verification.qrcode
|
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
import org.amshove.kluent.shouldBe
|
|
||||||
import org.amshove.kluent.shouldNotBeEqualTo
|
|
||||||
import org.junit.FixMethodOrder
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import org.junit.runners.MethodSorters
|
|
||||||
import org.matrix.android.sdk.InstrumentedTest
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
@FixMethodOrder(MethodSorters.JVM)
|
|
||||||
class SharedSecretTest : InstrumentedTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testSharedSecretLengthCase() {
|
|
||||||
repeat(100) {
|
|
||||||
generateSharedSecretV2().length shouldBe 11
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testSharedDiffCase() {
|
|
||||||
val sharedSecret1 = generateSharedSecretV2()
|
|
||||||
val sharedSecret2 = generateSharedSecretV2()
|
|
||||||
|
|
||||||
sharedSecret1 shouldNotBeEqualTo sharedSecret2
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
*
|
|
||||||
* 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 org.matrix.android.sdk.api.session.crypto.verification
|
|
||||||
|
|
||||||
interface IncomingSasVerificationTransaction : SasVerificationTransaction {
|
|
||||||
val uxState: UxState
|
|
||||||
|
|
||||||
fun performAccept()
|
|
||||||
|
|
||||||
enum class UxState {
|
|
||||||
UNKNOWN,
|
|
||||||
SHOW_ACCEPT,
|
|
||||||
WAIT_FOR_KEY_AGREEMENT,
|
|
||||||
SHOW_SAS,
|
|
||||||
WAIT_FOR_VERIFICATION,
|
|
||||||
VERIFIED,
|
|
||||||
CANCELLED_BY_ME,
|
|
||||||
CANCELLED_BY_OTHER
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
*
|
|
||||||
* 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 org.matrix.android.sdk.api.session.crypto.verification
|
|
||||||
|
|
||||||
interface OutgoingSasVerificationTransaction : SasVerificationTransaction {
|
|
||||||
val uxState: UxState
|
|
||||||
|
|
||||||
enum class UxState {
|
|
||||||
UNKNOWN,
|
|
||||||
WAIT_FOR_START,
|
|
||||||
WAIT_FOR_KEY_AGREEMENT,
|
|
||||||
SHOW_SAS,
|
|
||||||
WAIT_FOR_VERIFICATION,
|
|
||||||
VERIFIED,
|
|
||||||
CANCELLED_BY_ME,
|
|
||||||
CANCELLED_BY_OTHER
|
|
||||||
}
|
|
||||||
}
|
|
@ -46,55 +46,38 @@ interface VerificationService {
|
|||||||
|
|
||||||
fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest?
|
fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest?
|
||||||
|
|
||||||
suspend fun beginKeyVerification(method: VerificationMethod,
|
|
||||||
otherUserId: String,
|
|
||||||
otherDeviceId: String,
|
|
||||||
transactionId: String?): String?
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request key verification with another user via room events (instead of the to-device API)
|
* Request key verification with another user via room events (instead of the to-device API).
|
||||||
*/
|
*/
|
||||||
suspend fun requestKeyVerificationInDMs(methods: List<VerificationMethod>,
|
suspend fun requestKeyVerificationInDMs(methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
|
localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
|
||||||
|
|
||||||
suspend fun cancelVerificationRequest(request: PendingVerificationRequest)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a key verification from another user using toDevice events.
|
* Request a self key verification using to-device API (instead of room events).
|
||||||
*/
|
*/
|
||||||
suspend fun requestKeyVerification(methods: List<VerificationMethod>,
|
suspend fun requestSelfKeyVerification(methods: List<VerificationMethod>): PendingVerificationRequest
|
||||||
otherUserId: String,
|
|
||||||
otherDevices: List<String>?): PendingVerificationRequest
|
|
||||||
|
|
||||||
suspend fun declineVerificationRequestInDMs(otherUserId: String,
|
|
||||||
transactionId: String,
|
|
||||||
roomId: String)
|
|
||||||
|
|
||||||
// Only SAS method is supported for the moment
|
|
||||||
// TODO Parameter otherDeviceId should be removed in this case
|
|
||||||
suspend fun beginKeyVerificationInDMs(method: VerificationMethod,
|
|
||||||
transactionId: String,
|
|
||||||
roomId: String,
|
|
||||||
otherUserId: String,
|
|
||||||
otherDeviceId: String): String
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns false if the request is unknown
|
* You should call this method after receiving a verification request.
|
||||||
*/
|
* Accept the verification request advertising the given methods as supported
|
||||||
suspend fun readyPendingVerificationInDMs(methods: List<VerificationMethod>,
|
* Returns false if the request is unknown or transaction is not ready.
|
||||||
otherUserId: String,
|
|
||||||
roomId: String,
|
|
||||||
transactionId: String): Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns false if the request is unknown
|
|
||||||
*/
|
*/
|
||||||
suspend fun readyPendingVerification(methods: List<VerificationMethod>,
|
suspend fun readyPendingVerification(methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
transactionId: String): Boolean
|
transactionId: String): Boolean
|
||||||
|
|
||||||
|
suspend fun cancelVerificationRequest(request: PendingVerificationRequest)
|
||||||
|
|
||||||
|
suspend fun cancelVerificationRequest(otherUserId: String, transactionId: String)
|
||||||
|
|
||||||
|
suspend fun beginKeyVerification(method: VerificationMethod,
|
||||||
|
otherUserId: String,
|
||||||
|
transactionId: String): String?
|
||||||
|
|
||||||
|
suspend fun beginDeviceVerification(otherUserId: String, otherDeviceId: String): String?
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
/**
|
/**
|
||||||
* Called when a verification request is created either by the user, or by the other user.
|
* Called when a verification request is created either by the user, or by the other user.
|
||||||
|
@ -775,7 +775,7 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
Timber.tag(loggerTag.value).e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error")
|
Timber.tag(loggerTag.value).e(throwable, "## CRYPTO doKeyDownloadForUsers(): error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,17 +229,12 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun requestKeyVerification(
|
override suspend fun requestSelfKeyVerification(methods: List<VerificationMethod>): PendingVerificationRequest {
|
||||||
methods: List<VerificationMethod>,
|
val verification = when (val identity = olmMachine.getIdentity(olmMachine.userId())) {
|
||||||
otherUserId: String,
|
|
||||||
otherDevices: List<String>?
|
|
||||||
): PendingVerificationRequest {
|
|
||||||
val verification = when (val identity = olmMachine.getIdentity(otherUserId)) {
|
|
||||||
is OwnUserIdentity -> identity.requestVerification(methods)
|
is OwnUserIdentity -> identity.requestVerification(methods)
|
||||||
is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices")
|
is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices")
|
||||||
null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user")
|
null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user")
|
||||||
}
|
}
|
||||||
|
|
||||||
return verification.toPendingVerificationRequest()
|
return verification.toPendingVerificationRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +244,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
|||||||
roomId: String,
|
roomId: String,
|
||||||
localId: String?
|
localId: String?
|
||||||
): PendingVerificationRequest {
|
): PendingVerificationRequest {
|
||||||
Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId")
|
olmMachine.ensureUsersKeys(listOf(otherUserId))
|
||||||
val verification = when (val identity = olmMachine.getIdentity(otherUserId)) {
|
val verification = when (val identity = olmMachine.getIdentity(otherUserId)) {
|
||||||
is UserIdentity -> identity.requestVerification(methods, roomId, localId!!)
|
is UserIdentity -> identity.requestVerification(methods, roomId, localId!!)
|
||||||
is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user")
|
is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user")
|
||||||
@ -284,23 +279,12 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun readyPendingVerificationInDMs(
|
|
||||||
methods: List<VerificationMethod>,
|
|
||||||
otherUserId: String,
|
|
||||||
roomId: String,
|
|
||||||
transactionId: String
|
|
||||||
): Boolean {
|
|
||||||
return readyPendingVerification(methods, otherUserId, transactionId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun beginKeyVerification(
|
override suspend fun beginKeyVerification(
|
||||||
method: VerificationMethod,
|
method: VerificationMethod,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
otherDeviceId: String,
|
transactionId: String
|
||||||
transactionId: String?
|
|
||||||
): String? {
|
): String? {
|
||||||
return if (method == VerificationMethod.SAS) {
|
return if (method == VerificationMethod.SAS) {
|
||||||
if (transactionId != null) {
|
|
||||||
val request = olmMachine.getVerificationRequest(otherUserId, transactionId)
|
val request = olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||||
|
|
||||||
val sas = request?.startSasVerification()
|
val sas = request?.startSasVerification()
|
||||||
@ -312,6 +296,11 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
throw IllegalArgumentException("Unknown verification method")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun beginDeviceVerification(otherUserId: String, otherDeviceId: String): String? {
|
||||||
// This starts the short SAS flow, the one that doesn't start with
|
// This starts the short SAS flow, the one that doesn't start with
|
||||||
// a `m.key.verification.request`, Element web stopped doing this, might
|
// a `m.key.verification.request`, Element web stopped doing this, might
|
||||||
// be wise do do so as well
|
// be wise do do so as well
|
||||||
@ -319,43 +308,20 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
|||||||
// triggers this is called `manuallyVerify()`
|
// triggers this is called `manuallyVerify()`
|
||||||
val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId)
|
val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId)
|
||||||
val verification = otherDevice?.startVerification()
|
val verification = otherDevice?.startVerification()
|
||||||
if (verification != null) {
|
return if (verification != null) {
|
||||||
dispatcher.dispatchTxAdded(verification)
|
dispatcher.dispatchTxAdded(verification)
|
||||||
verification.transactionId
|
verification.transactionId
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw IllegalArgumentException("Unknown verification method")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun beginKeyVerificationInDMs(
|
|
||||||
method: VerificationMethod,
|
|
||||||
transactionId: String,
|
|
||||||
roomId: String,
|
|
||||||
otherUserId: String,
|
|
||||||
otherDeviceId: String
|
|
||||||
): String {
|
|
||||||
beginKeyVerification(method, otherUserId, otherDeviceId, transactionId)
|
|
||||||
// TODO what's the point of returning the same ID we got as an argument?
|
|
||||||
// We do this because the old verification service did so
|
|
||||||
return transactionId
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun cancelVerificationRequest(request: PendingVerificationRequest) {
|
override suspend fun cancelVerificationRequest(request: PendingVerificationRequest) {
|
||||||
val verificationRequest = request.transactionId?.let {
|
request.transactionId ?: return
|
||||||
olmMachine.getVerificationRequest(request.otherUserId, it)
|
cancelVerificationRequest(request.otherUserId, request.transactionId)
|
||||||
}
|
|
||||||
verificationRequest?.cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun declineVerificationRequestInDMs(
|
override suspend fun cancelVerificationRequest(otherUserId: String, transactionId: String) {
|
||||||
otherUserId: String,
|
|
||||||
transactionId: String,
|
|
||||||
roomId: String
|
|
||||||
) {
|
|
||||||
val verificationRequest = olmMachine.getVerificationRequest(otherUserId, transactionId)
|
val verificationRequest = olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||||
verificationRequest?.cancel()
|
verificationRequest?.cancel()
|
||||||
}
|
}
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
*
|
|
||||||
* 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 org.matrix.android.sdk.internal.crypto.verification.qrcode
|
|
||||||
|
|
||||||
import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding
|
|
||||||
import java.security.SecureRandom
|
|
||||||
|
|
||||||
fun generateSharedSecretV2(): String {
|
|
||||||
val secureRandom = SecureRandom()
|
|
||||||
|
|
||||||
// 8 bytes long
|
|
||||||
val secretBytes = ByteArray(8)
|
|
||||||
secureRandom.nextBytes(secretBytes)
|
|
||||||
return secretBytes.toBase64NoPadding()
|
|
||||||
}
|
|
@ -51,6 +51,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
|||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||||
|
import org.matrix.android.sdk.common.CommonTestHelper
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
@ -134,10 +135,8 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
|||||||
onView(withId(R.id.bottomSheetFragmentContainer))
|
onView(withId(R.id.bottomSheetFragmentContainer))
|
||||||
.check(matches(not(hasDescendant(withText(R.string.verification_cannot_access_other_session)))))
|
.check(matches(not(hasDescendant(withText(R.string.verification_cannot_access_other_session)))))
|
||||||
|
|
||||||
val request = existingSession!!.cryptoService().verificationService().requestKeyVerification(
|
val request = existingSession!!.cryptoService().verificationService().requestSelfKeyVerification(
|
||||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW)
|
||||||
existingSession!!.myUserId,
|
|
||||||
listOf(uiSession.sessionParams.deviceId!!)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val transactionId = request.transactionId!!
|
val transactionId = request.transactionId!!
|
||||||
|
@ -166,9 +166,8 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dismissedAction = LaunchCoroutineRunnable(coroutineScope) {
|
dismissedAction = LaunchCoroutineRunnable(coroutineScope) {
|
||||||
session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
|
session?.cryptoService()?.verificationService()?.cancelVerificationRequest(pr.otherUserId,
|
||||||
pr.transactionId ?: "",
|
pr.transactionId ?: ""
|
||||||
pr.roomId ?: ""
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
colorAttribute = R.attr.vctr_notice_secondary
|
colorAttribute = R.attr.vctr_notice_secondary
|
||||||
|
@ -238,7 +238,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||||||
handleRequestVerificationByDM(roomId, otherUserId)
|
handleRequestVerificationByDM(roomId, otherUserId)
|
||||||
}
|
}
|
||||||
is VerificationAction.StartSASVerification -> {
|
is VerificationAction.StartSASVerification -> {
|
||||||
handleStartSASVerification(roomId, otherUserId, action)
|
handleStartSASVerification(otherUserId, action)
|
||||||
}
|
}
|
||||||
is VerificationAction.RemoteQrCodeScanned -> {
|
is VerificationAction.RemoteQrCodeScanned -> {
|
||||||
handleRemoteQrCodeScanned(action)
|
handleRemoteQrCodeScanned(action)
|
||||||
@ -284,27 +284,15 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleStartSASVerification(roomId: String?, otherUserId: String, action: VerificationAction.StartSASVerification) {
|
private fun handleStartSASVerification(otherUserId: String, action: VerificationAction.StartSASVerification) {
|
||||||
val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
||||||
?: return
|
?: return
|
||||||
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if (roomId == null) {
|
|
||||||
session.cryptoService().verificationService().beginKeyVerification(
|
session.cryptoService().verificationService().beginKeyVerification(
|
||||||
VerificationMethod.SAS,
|
VerificationMethod.SAS,
|
||||||
otherUserId = request.otherUserId,
|
otherUserId = request.otherUserId,
|
||||||
otherDeviceId = otherDevice ?: "",
|
|
||||||
transactionId = action.pendingRequestTransactionId
|
transactionId = action.pendingRequestTransactionId
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
session.cryptoService().verificationService().beginKeyVerificationInDMs(
|
|
||||||
VerificationMethod.SAS,
|
|
||||||
transactionId = action.pendingRequestTransactionId,
|
|
||||||
roomId = roomId,
|
|
||||||
otherUserId = request.otherUserId,
|
|
||||||
otherDeviceId = otherDevice ?: ""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,10 +995,9 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
|
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
|
||||||
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
|
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if (session.cryptoService().verificationService().readyPendingVerificationInDMs(
|
if (session.cryptoService().verificationService().readyPendingVerification(
|
||||||
supportedVerificationMethodsProvider.provide(),
|
supportedVerificationMethodsProvider.provide(),
|
||||||
action.otherUserId,
|
action.otherUserId,
|
||||||
room.roomId,
|
|
||||||
action.transactionId)) {
|
action.transactionId)) {
|
||||||
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action))
|
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action))
|
||||||
} else {
|
} else {
|
||||||
@ -1009,10 +1008,9 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) {
|
private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
session.cryptoService().verificationService().declineVerificationRequestInDMs(
|
session.cryptoService().verificationService().cancelVerificationRequest(
|
||||||
action.otherUserId,
|
action.otherUserId,
|
||||||
action.transactionId,
|
action.transactionId)
|
||||||
room.roomId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,10 +217,8 @@ class DefaultNavigator @Inject constructor(
|
|||||||
override fun requestSessionVerification(context: Context, otherSessionId: String) {
|
override fun requestSessionVerification(context: Context, otherSessionId: String) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
val session = sessionHolder.getSafeActiveSession() ?: return@launch
|
val session = sessionHolder.getSafeActiveSession() ?: return@launch
|
||||||
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
val pr = session.cryptoService().verificationService().requestSelfKeyVerification(
|
||||||
supportedVerificationMethodsProvider.provide(),
|
supportedVerificationMethodsProvider.provide()
|
||||||
session.myUserId,
|
|
||||||
listOf(otherSessionId)
|
|
||||||
)
|
)
|
||||||
if (context is AppCompatActivity) {
|
if (context is AppCompatActivity) {
|
||||||
VerificationBottomSheet.withArgs(
|
VerificationBottomSheet.withArgs(
|
||||||
@ -241,10 +239,8 @@ class DefaultNavigator @Inject constructor(
|
|||||||
.map { it.deviceId }
|
.map { it.deviceId }
|
||||||
if (context is AppCompatActivity) {
|
if (context is AppCompatActivity) {
|
||||||
if (otherSessions.isNotEmpty()) {
|
if (otherSessions.isNotEmpty()) {
|
||||||
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
val pr = session.cryptoService().verificationService().requestSelfKeyVerification(
|
||||||
supportedVerificationMethodsProvider.provide(),
|
supportedVerificationMethodsProvider.provide())
|
||||||
session.myUserId,
|
|
||||||
otherSessions)
|
|
||||||
VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId)
|
VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId)
|
||||||
.show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
.show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,11 +126,10 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
|
|||||||
private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) {
|
private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) {
|
||||||
if (!initialState.allowDeviceAction) return
|
if (!initialState.allowDeviceAction) return
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
session.cryptoService().verificationService().beginKeyVerification(
|
session.cryptoService().verificationService().beginDeviceVerification(
|
||||||
method = VerificationMethod.SAS,
|
|
||||||
otherUserId = initialState.userId,
|
otherUserId = initialState.userId,
|
||||||
otherDeviceId = action.deviceId,
|
otherDeviceId = action.deviceId,
|
||||||
transactionId = null)?.let { txID ->
|
)?.let { txID ->
|
||||||
_viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID))
|
_viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ class DevicesViewModel @AssistedInject constructor(
|
|||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val txID = session.cryptoService()
|
val txID = session.cryptoService()
|
||||||
.verificationService()
|
.verificationService()
|
||||||
.beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null)
|
.beginDeviceVerification(session.myUserId, action.deviceId)
|
||||||
_viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
|
_viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
|
||||||
session.myUserId,
|
session.myUserId,
|
||||||
txID
|
txID
|
||||||
|
Loading…
Reference in New Issue
Block a user