mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
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.extensions.orFalse
|
||||
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.OutgoingSasVerificationTransaction
|
||||
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.VerificationTxState
|
||||
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
|
||||
var alicePovTx: OutgoingSasVerificationTransaction? = null
|
||||
var bobPovTx: IncomingSasVerificationTransaction? = null
|
||||
var alicePovTx: SasVerificationTransaction? = null
|
||||
var bobPovTx: SasVerificationTransaction? = null
|
||||
|
||||
// wait for alice to get the ready
|
||||
testHelper.waitWithLatch {
|
||||
testHelper.retryPeriodicallyWithLatch(it) {
|
||||
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? IncomingSasVerificationTransaction
|
||||
Log.v("TEST", "== bobPovTx is ${alicePovTx?.uxState}")
|
||||
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? SasVerificationTransaction
|
||||
Log.v("TEST", "== bobPovTx is ${bobPovTx?.state}")
|
||||
if (bobPovTx?.state == VerificationTxState.OnStarted) {
|
||||
bobPovTx?.performAccept()
|
||||
bobPovTx?.acceptVerification()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@ -330,18 +329,18 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||
|
||||
testHelper.waitWithLatch {
|
||||
testHelper.retryPeriodicallyWithLatch(it) {
|
||||
alicePovTx = aliceVerificationService.getExistingTransaction(bob.myUserId, requestID) as? OutgoingSasVerificationTransaction
|
||||
Log.v("TEST", "== alicePovTx is ${alicePovTx?.uxState}")
|
||||
alicePovTx = aliceVerificationService.getExistingTransaction(bob.myUserId, requestID) as? SasVerificationTransaction
|
||||
Log.v("TEST", "== alicePovTx is ${alicePovTx?.state}")
|
||||
alicePovTx?.state == VerificationTxState.ShortCodeReady
|
||||
}
|
||||
}
|
||||
// wait for alice to get the ready
|
||||
testHelper.waitWithLatch {
|
||||
testHelper.retryPeriodicallyWithLatch(it) {
|
||||
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? IncomingSasVerificationTransaction
|
||||
Log.v("TEST", "== bobPovTx is ${alicePovTx?.uxState}")
|
||||
bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? SasVerificationTransaction
|
||||
Log.v("TEST", "== bobPovTx is ${bobPovTx?.state}")
|
||||
if (bobPovTx?.state == VerificationTxState.OnStarted) {
|
||||
bobPovTx?.performAccept()
|
||||
bobPovTx?.acceptVerification()
|
||||
}
|
||||
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.filters.LargeTest
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNotNull
|
||||
@ -53,7 +54,7 @@ class XSigningTest : InstrumentedTest {
|
||||
fun test_InitializeAndStoreKeys() {
|
||||
val aliceSession = testHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
|
||||
|
||||
testHelper.doSync<Unit> {
|
||||
testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().crossSigningService()
|
||||
.initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
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()
|
||||
assertNotNull("Master key should be stored", masterPubKey?.unpaddedBase64PublicKey)
|
||||
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", 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)
|
||||
}
|
||||
@ -99,29 +105,37 @@ class XSigningTest : InstrumentedTest {
|
||||
password = TestConstants.PASSWORD
|
||||
)
|
||||
|
||||
testHelper.doSync<Unit> {
|
||||
testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
promise.resume(aliceAuthParams)
|
||||
}
|
||||
}, it)
|
||||
})
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
promise.resume(bobAuthParams)
|
||||
}
|
||||
})
|
||||
}
|
||||
testHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
promise.resume(bobAuthParams)
|
||||
}
|
||||
}, it) }
|
||||
|
||||
// Check that alice can see bob keys
|
||||
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())
|
||||
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.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
|
||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
|
||||
val myKeys = testHelper.runBlockingTest {
|
||||
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())
|
||||
|
||||
@ -145,25 +159,33 @@ class XSigningTest : InstrumentedTest {
|
||||
password = TestConstants.PASSWORD
|
||||
)
|
||||
|
||||
testHelper.doSync<Unit> { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
promise.resume(aliceAuthParams)
|
||||
}
|
||||
}, it) }
|
||||
testHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
promise.resume(bobAuthParams)
|
||||
}
|
||||
}, it) }
|
||||
testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
promise.resume(aliceAuthParams)
|
||||
}
|
||||
})
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
promise.resume(bobAuthParams)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Check that alice can see bob keys
|
||||
val bobUserId = bobSession.myUserId
|
||||
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)
|
||||
|
||||
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
|
||||
// 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")
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
// Manually mark it as trusted from first session
|
||||
@ -198,7 +222,9 @@ class XSigningTest : InstrumentedTest {
|
||||
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())
|
||||
|
||||
testHelper.signOutAndClose(aliceSession)
|
||||
|
@ -24,7 +24,6 @@ import junit.framework.TestCase.assertNotNull
|
||||
import junit.framework.TestCase.assertTrue
|
||||
import junit.framework.TestCase.fail
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.FixMethodOrder
|
||||
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.registration.RegistrationFlowResponse
|
||||
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.VerificationMethod
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
@ -250,32 +248,31 @@ class KeyShareTests : InstrumentedTest {
|
||||
|
||||
aliceVerificationService1.addListener(object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
if (tx !is SasVerificationTransaction) return
|
||||
Log.d("#TEST", "AA: tx incoming?:${tx.isIncoming} state ${tx.state}")
|
||||
if (tx is SasVerificationTransaction) {
|
||||
if (tx.state == VerificationTxState.OnStarted) {
|
||||
(tx as IncomingSasVerificationTransaction).performAccept()
|
||||
when (tx.state) {
|
||||
VerificationTxState.OnStarted -> commonTestHelper.runBlockingTest {
|
||||
tx.acceptVerification()
|
||||
}
|
||||
if (tx.state == VerificationTxState.ShortCodeReady) {
|
||||
VerificationTxState.ShortCodeReady -> commonTestHelper.runBlockingTest {
|
||||
session1ShortCode = tx.getDecimalCodeRepresentation()
|
||||
commonTestHelper.runBlockingTest {
|
||||
delay(500)
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
delay(500)
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
aliceVerificationService2.addListener(object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
if (tx !is SasVerificationTransaction) return
|
||||
Log.d("#TEST", "BB: tx incoming?:${tx.isIncoming} state ${tx.state}")
|
||||
if (tx is SasVerificationTransaction) {
|
||||
if (tx.state == VerificationTxState.ShortCodeReady) {
|
||||
when (tx.state) {
|
||||
VerificationTxState.ShortCodeReady -> commonTestHelper.runBlockingTest {
|
||||
session2ShortCode = tx.getDecimalCodeRepresentation()
|
||||
commonTestHelper.runBlockingTest {
|
||||
delay(500)
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
delay(500)
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -301,7 +298,8 @@ class KeyShareTests : InstrumentedTest {
|
||||
|
||||
// SSK and USK private keys should have been shared
|
||||
|
||||
commonTestHelper.waitWithLatch(60_000) { latch ->
|
||||
commonTestHelper.waitWithLatch(60_000)
|
||||
{ latch ->
|
||||
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
||||
Log.d("#TEST", "CAN XS :${aliceSession2.cryptoService().crossSigningService().getMyCrossSigningKeys()}")
|
||||
aliceSession2.cryptoService().crossSigningService().canCrossSign()
|
||||
@ -309,7 +307,8 @@ class KeyShareTests : InstrumentedTest {
|
||||
}
|
||||
|
||||
// Test that key backup key has been shared to
|
||||
commonTestHelper.waitWithLatch(60_000) { latch ->
|
||||
commonTestHelper.waitWithLatch(60_000)
|
||||
{ latch ->
|
||||
val keysBackupService = aliceSession2.cryptoService().keysBackupService()
|
||||
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
||||
Log.d("#TEST", "Recovery :${keysBackupService.getKeyBackupRecoveryKeyInfo()?.recoveryKey}")
|
||||
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.verification
|
||||
|
||||
import android.util.Log
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
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.api.session.Session
|
||||
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.OutgoingSasVerificationTransaction
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.SasMode
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||
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.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.KeyVerificationStart
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@ -75,10 +76,15 @@ class SASTest : InstrumentedTest {
|
||||
}
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
|
||||
bobSession.myUserId,
|
||||
bobSession.cryptoService().getMyDevice().deviceId,
|
||||
null)
|
||||
val myDevice = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getMyDevice()
|
||||
}
|
||||
val txID = testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
|
||||
bobSession.myUserId,
|
||||
myDevice.deviceId,
|
||||
null)
|
||||
}
|
||||
assertNotNull("Alice should have a started transaction", txID)
|
||||
|
||||
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
|
||||
@ -90,16 +96,14 @@ class SASTest : InstrumentedTest {
|
||||
val bobKeyTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID)
|
||||
|
||||
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)
|
||||
assertTrue(aliceKeyTx is SASDefaultVerificationTransaction)
|
||||
assertTrue(aliceKeyTx is SasVerificationTransaction)
|
||||
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("Bob state should be started by alice", VerificationTxState.OnStarted, bobSasTx!!.state)
|
||||
assertEquals("Alice state should be started", VerificationTxState.Started, aliceKeyTx.state)
|
||||
assertEquals("Bob state should be started by alice", VerificationTxState.OnStarted, bobKeyTx.state)
|
||||
|
||||
// Let's cancel from alice side
|
||||
val cancelLatch = CountDownLatch(1)
|
||||
@ -107,7 +111,7 @@ class SASTest : InstrumentedTest {
|
||||
val bobListener2 = object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
if (tx.transactionId == txID) {
|
||||
val immutableState = (tx as SASDefaultVerificationTransaction).state
|
||||
val immutableState = (tx as SasVerificationTransaction).state
|
||||
if (immutableState is VerificationTxState.Cancelled && !immutableState.byMe) {
|
||||
cancelLatch.countDown()
|
||||
}
|
||||
@ -116,14 +120,16 @@ class SASTest : InstrumentedTest {
|
||||
}
|
||||
bobVerificationService.addListener(bobListener2)
|
||||
|
||||
aliceSasTx.cancel(CancelCode.User)
|
||||
testHelper.runBlockingTest {
|
||||
aliceKeyTx.cancel(CancelCode.User)
|
||||
}
|
||||
testHelper.await(cancelLatch)
|
||||
|
||||
assertTrue("Should be cancelled on alice side", aliceSasTx.state is VerificationTxState.Cancelled)
|
||||
assertTrue("Should be cancelled on bob side", bobSasTx.state is VerificationTxState.Cancelled)
|
||||
assertTrue("Should be cancelled on alice side", aliceKeyTx.state is VerificationTxState.Cancelled)
|
||||
assertTrue("Should be cancelled on bob side", bobKeyTx.state is VerificationTxState.Cancelled)
|
||||
|
||||
val aliceCancelState = aliceSasTx.state as VerificationTxState.Cancelled
|
||||
val bobCancelState = bobSasTx.state as VerificationTxState.Cancelled
|
||||
val aliceCancelState = aliceKeyTx.state as VerificationTxState.Cancelled
|
||||
val bobCancelState = bobKeyTx.state as VerificationTxState.Cancelled
|
||||
|
||||
assertTrue("Should be cancelled by me on alice side", aliceCancelState.byMe)
|
||||
assertFalse("Should be cancelled by other on bob side", bobCancelState.byMe)
|
||||
@ -177,12 +183,16 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceUserID = aliceSession.myUserId
|
||||
val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
|
||||
val aliceDevice = testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().getMyDevice().deviceId
|
||||
}
|
||||
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
|
||||
(tx as IncomingSasVerificationTransaction).performAccept()
|
||||
if (tx.state is VerificationTxState.OnStarted && tx is SasVerificationTransaction) {
|
||||
testHelper.runBlockingTest {
|
||||
tx.acceptVerification()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,7 +236,9 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
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)
|
||||
|
||||
@ -267,7 +279,9 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
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)
|
||||
|
||||
@ -283,12 +297,15 @@ class SASTest : InstrumentedTest {
|
||||
aliceUserID: String?,
|
||||
aliceDevice: String?,
|
||||
tid: String,
|
||||
protocols: List<String> = SASDefaultVerificationTransaction.KNOWN_AGREEMENT_PROTOCOLS,
|
||||
hashes: List<String> = SASDefaultVerificationTransaction.KNOWN_HASHES,
|
||||
mac: List<String> = SASDefaultVerificationTransaction.KNOWN_MACS,
|
||||
codes: List<String> = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES) {
|
||||
protocols: List<String> = emptyList(),
|
||||
hashes: List<String> = emptyList(),
|
||||
mac: List<String> = emptyList(),
|
||||
codes: List<String> = emptyList()) {
|
||||
val deviceId = runBlocking {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
}
|
||||
val startMessage = KeyVerificationStart(
|
||||
fromDevice = bobSession.cryptoService().getMyDevice().deviceId,
|
||||
fromDevice = deviceId,
|
||||
method = VerificationMethod.SAS.toValue(),
|
||||
transactionId = tid,
|
||||
keyAgreementProtocols = protocols,
|
||||
@ -324,15 +341,15 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceCreatedLatch = CountDownLatch(2)
|
||||
val aliceCancelledLatch = CountDownLatch(2)
|
||||
val createdTx = mutableListOf<SASDefaultVerificationTransaction>()
|
||||
val createdTx = mutableListOf<VerificationTransaction>()
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun transactionCreated(tx: VerificationTransaction) {
|
||||
createdTx.add(tx as SASDefaultVerificationTransaction)
|
||||
createdTx.add(tx)
|
||||
aliceCreatedLatch.countDown()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
@ -340,10 +357,13 @@ class SASTest : InstrumentedTest {
|
||||
aliceVerificationService.addListener(aliceListener)
|
||||
|
||||
val bobUserId = bobSession!!.myUserId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
|
||||
val bobDeviceId = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
}
|
||||
testHelper.await(aliceCreatedLatch)
|
||||
testHelper.await(aliceCancelledLatch)
|
||||
|
||||
@ -366,17 +386,10 @@ class SASTest : InstrumentedTest {
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
|
||||
var accepted: ValidVerificationInfoAccept? = null
|
||||
var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null
|
||||
|
||||
val aliceAcceptedLatch = CountDownLatch(1)
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
Log.v("TEST", "== aliceTx state ${tx.state} => ${(tx as? OutgoingSasVerificationTransaction)?.uxState}")
|
||||
if ((tx as SASDefaultVerificationTransaction).state === VerificationTxState.OnAccepted) {
|
||||
val at = tx as SASDefaultVerificationTransaction
|
||||
accepted = at.accepted
|
||||
startReq = at.startReq
|
||||
if (tx.state is VerificationTxState.OnAccepted) {
|
||||
aliceAcceptedLatch.countDown()
|
||||
}
|
||||
}
|
||||
@ -385,32 +398,24 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val bobListener = object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
Log.v("TEST", "== bobTx state ${tx.state} => ${(tx as? IncomingSasVerificationTransaction)?.uxState}")
|
||||
if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
|
||||
if (tx.state is VerificationTxState.OnStarted && tx is SasVerificationTransaction) {
|
||||
bobVerificationService.removeListener(this)
|
||||
val at = tx as IncomingSasVerificationTransaction
|
||||
at.performAccept()
|
||||
testHelper.runBlockingTest {
|
||||
tx.acceptVerification()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
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))
|
||||
val bobDeviceId = runBlocking {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
}
|
||||
testHelper.await(aliceAcceptedLatch)
|
||||
|
||||
cryptoTestData.cleanUp(testHelper)
|
||||
}
|
||||
@ -422,20 +427,22 @@ class SASTest : InstrumentedTest {
|
||||
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
val bobSession = cryptoTestData.secondSession!!
|
||||
|
||||
cryptoTestHelper.initializeCrossSigning(aliceSession)
|
||||
cryptoTestHelper.initializeCrossSigning(bobSession)
|
||||
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||
|
||||
val aliceSASLatch = CountDownLatch(1)
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
val uxState = (tx as OutgoingSasVerificationTransaction).uxState
|
||||
when (uxState) {
|
||||
OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
when (tx.state) {
|
||||
VerificationTxState.ShortCodeReady -> {
|
||||
aliceSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -443,32 +450,42 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val bobSASLatch = CountDownLatch(1)
|
||||
val bobListener = object : VerificationService.Listener {
|
||||
|
||||
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
||||
|
||||
}
|
||||
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
val uxState = (tx as IncomingSasVerificationTransaction).uxState
|
||||
when (uxState) {
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> {
|
||||
tx.performAccept()
|
||||
val sasVerification = tx as SasVerificationTransaction
|
||||
when (tx.state) {
|
||||
VerificationTxState.OnStarted -> testHelper.runBlockingTest {
|
||||
sasVerification.acceptVerification()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
if (uxState === IncomingSasVerificationTransaction.UxState.SHOW_SAS) {
|
||||
bobSASLatch.countDown()
|
||||
VerificationTxState.ShortCodeReady -> {
|
||||
bobSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().downloadKeys(listOf(bobUserId), forceDownload = true)
|
||||
aliceVerificationService.requestKeyVerificationInDMs(listOf(VerificationMethod.SAS),bobUserId, cryptoTestData.roomId)
|
||||
}
|
||||
testHelper.await(aliceSASLatch)
|
||||
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)
|
||||
}
|
||||
@ -489,19 +506,18 @@ class SASTest : InstrumentedTest {
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
var matchOnce = true
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
val uxState = (tx as OutgoingSasVerificationTransaction).uxState
|
||||
Log.v("TEST", "== aliceState ${uxState.name}")
|
||||
when (uxState) {
|
||||
OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
if (tx !is SasVerificationTransaction) return
|
||||
when (tx.state) {
|
||||
VerificationTxState.ShortCodeReady -> testHelper.runBlockingTest {
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
OutgoingSasVerificationTransaction.UxState.VERIFIED -> {
|
||||
VerificationTxState.Verified -> {
|
||||
if (matchOnce) {
|
||||
matchOnce = false
|
||||
aliceSASLatch.countDown()
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -512,40 +528,46 @@ class SASTest : InstrumentedTest {
|
||||
var acceptOnce = true
|
||||
var matchOnce = true
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
val uxState = (tx as IncomingSasVerificationTransaction).uxState
|
||||
Log.v("TEST", "== bobState ${uxState.name}")
|
||||
when (uxState) {
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> {
|
||||
if (tx !is SasVerificationTransaction) return
|
||||
when (tx.state) {
|
||||
VerificationTxState.OnStarted -> testHelper.runBlockingTest {
|
||||
if (acceptOnce) {
|
||||
acceptOnce = false
|
||||
tx.performAccept()
|
||||
tx.acceptVerification()
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
VerificationTxState.ShortCodeReady -> testHelper.runBlockingTest {
|
||||
if (matchOnce) {
|
||||
matchOnce = false
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.VERIFIED -> {
|
||||
VerificationTxState.Verified -> {
|
||||
bobSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
val bobDeviceId = runBlocking {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
}
|
||||
testHelper.await(aliceSASLatch)
|
||||
testHelper.await(bobSASLatch)
|
||||
|
||||
// Assert that devices are verified
|
||||
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
|
||||
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
|
||||
|
||||
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = testHelper.runBlockingTest {
|
||||
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("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
|
||||
cryptoTestData.cleanUp(testHelper)
|
||||
@ -563,11 +585,13 @@ class SASTest : InstrumentedTest {
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
|
||||
val req = aliceVerificationService.requestKeyVerificationInDMs(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
bobSession.myUserId,
|
||||
cryptoTestData.roomId
|
||||
)
|
||||
val req = testHelper.runBlockingTest {
|
||||
aliceVerificationService.requestKeyVerificationInDMs(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
bobSession.myUserId,
|
||||
cryptoTestData.roomId
|
||||
)
|
||||
}
|
||||
|
||||
var requestID: String? = null
|
||||
|
||||
@ -590,11 +614,13 @@ class SASTest : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
|
||||
bobVerificationService.readyPendingVerification(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
aliceSession.myUserId,
|
||||
requestID!!
|
||||
)
|
||||
testHelper.runBlockingTest {
|
||||
bobVerificationService.readyPendingVerification(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
aliceSession.myUserId,
|
||||
requestID!!
|
||||
)
|
||||
}
|
||||
|
||||
// wait for alice to get the ready
|
||||
testHelper.waitWithLatch {
|
||||
@ -606,19 +632,22 @@ class SASTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
// Start concurrent!
|
||||
aliceVerificationService.beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
requestID!!,
|
||||
cryptoTestData.roomId,
|
||||
bobSession.myUserId,
|
||||
bobSession.sessionParams.deviceId!!)
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
requestID!!,
|
||||
cryptoTestData.roomId,
|
||||
bobSession.myUserId,
|
||||
bobSession.sessionParams.deviceId!!)
|
||||
|
||||
bobVerificationService.beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
requestID!!,
|
||||
cryptoTestData.roomId,
|
||||
aliceSession.myUserId,
|
||||
aliceSession.sessionParams.deviceId!!)
|
||||
bobVerificationService.beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
requestID!!,
|
||||
cryptoTestData.roomId,
|
||||
aliceSession.myUserId,
|
||||
aliceSession.sessionParams.deviceId!!)
|
||||
|
||||
}
|
||||
|
||||
// we should reach SHOW SAS on both
|
||||
var alicePovTx: 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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,7 +14,7 @@
|
||||
* 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 org.amshove.kluent.shouldBe
|
||||
@ -23,19 +23,13 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
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.VerificationMethod
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import org.matrix.android.sdk.common.CommonTestHelper
|
||||
import org.matrix.android.sdk.common.CryptoTestHelper
|
||||
import org.matrix.android.sdk.common.TestConstants
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@ -147,50 +141,19 @@ class VerificationTest : InstrumentedTest {
|
||||
ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true)
|
||||
)
|
||||
|
||||
// TODO Add tests without SAS
|
||||
|
||||
private fun doTest(aliceSupportedMethods: List<VerificationMethod>,
|
||||
bobSupportedMethods: List<VerificationMethod>,
|
||||
expectedResultForAlice: ExpectedResult,
|
||||
expectedResultForBob: ExpectedResult) {
|
||||
val testHelper = CommonTestHelper(context())
|
||||
val cryptoTestHelper = CryptoTestHelper(testHelper)
|
||||
val testHelper = CommonTestHelper(context())
|
||||
val cryptoTestHelper = CryptoTestHelper(testHelper)
|
||||
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession!!
|
||||
|
||||
testHelper.doSync<Unit> { callback ->
|
||||
aliceSession.cryptoService().crossSigningService()
|
||||
.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)
|
||||
}
|
||||
cryptoTestHelper.initializeCrossSigning(aliceSession)
|
||||
cryptoTestHelper.initializeCrossSigning(bobSession)
|
||||
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||
@ -202,6 +165,7 @@ class VerificationTest : InstrumentedTest {
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
||||
// Step 4: Alice receive the ready request
|
||||
Timber.v("Alice is ready: ${pr.isReady}")
|
||||
if (pr.isReady) {
|
||||
aliceReadyPendingVerificationRequest = pr
|
||||
latch.countDown()
|
||||
@ -213,16 +177,19 @@ class VerificationTest : InstrumentedTest {
|
||||
val bobListener = object : VerificationService.Listener {
|
||||
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
||||
// Step 2: Bob accepts the verification request
|
||||
bobVerificationService.readyPendingVerificationInDMs(
|
||||
bobSupportedMethods,
|
||||
aliceSession.myUserId,
|
||||
cryptoTestData.roomId,
|
||||
pr.transactionId!!
|
||||
)
|
||||
Timber.v("Bob accepts the verification request")
|
||||
testHelper.runBlockingTest {
|
||||
bobVerificationService.readyPendingVerification(
|
||||
bobSupportedMethods,
|
||||
aliceSession.myUserId,
|
||||
pr.transactionId!!
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
||||
// Step 3: Bob is ready
|
||||
Timber.v("Bob is ready: ${pr.isReady}")
|
||||
if (pr.isReady) {
|
||||
bobReadyPendingVerificationRequest = pr
|
||||
latch.countDown()
|
||||
@ -233,7 +200,9 @@ class VerificationTest : InstrumentedTest {
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
// Step 1: Alice starts a verification request
|
||||
aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId)
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId)
|
||||
}
|
||||
testHelper.await(latch)
|
||||
|
||||
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,54 +46,37 @@ interface VerificationService {
|
||||
|
||||
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>,
|
||||
otherUserId: String,
|
||||
roomId: String,
|
||||
localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
|
||||
otherUserId: String,
|
||||
roomId: String,
|
||||
localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
|
||||
|
||||
/**
|
||||
* Request a self key verification using to-device API (instead of room events).
|
||||
*/
|
||||
suspend fun requestSelfKeyVerification(methods: List<VerificationMethod>): PendingVerificationRequest
|
||||
|
||||
/**
|
||||
* You should call this method after receiving a verification request.
|
||||
* Accept the verification request advertising the given methods as supported
|
||||
* Returns false if the request is unknown or transaction is not ready.
|
||||
*/
|
||||
suspend fun readyPendingVerification(methods: List<VerificationMethod>,
|
||||
otherUserId: String,
|
||||
transactionId: String): Boolean
|
||||
|
||||
suspend fun cancelVerificationRequest(request: PendingVerificationRequest)
|
||||
|
||||
/**
|
||||
* Request a key verification from another user using toDevice events.
|
||||
*/
|
||||
suspend fun requestKeyVerification(methods: List<VerificationMethod>,
|
||||
otherUserId: String,
|
||||
otherDevices: List<String>?): PendingVerificationRequest
|
||||
suspend fun cancelVerificationRequest(otherUserId: String, transactionId: String)
|
||||
|
||||
suspend fun declineVerificationRequestInDMs(otherUserId: String,
|
||||
transactionId: String,
|
||||
roomId: String)
|
||||
suspend fun beginKeyVerification(method: VerificationMethod,
|
||||
otherUserId: String,
|
||||
transactionId: String): 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
|
||||
*/
|
||||
suspend fun readyPendingVerificationInDMs(methods: List<VerificationMethod>,
|
||||
otherUserId: String,
|
||||
roomId: String,
|
||||
transactionId: String): Boolean
|
||||
|
||||
/**
|
||||
* Returns false if the request is unknown
|
||||
*/
|
||||
suspend fun readyPendingVerification(methods: List<VerificationMethod>,
|
||||
otherUserId: String,
|
||||
transactionId: String): Boolean
|
||||
suspend fun beginDeviceVerification(otherUserId: String, otherDeviceId: String): String?
|
||||
|
||||
interface Listener {
|
||||
/**
|
||||
|
@ -775,7 +775,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
}
|
||||
}
|
||||
} 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
|
||||
}
|
||||
|
||||
override suspend fun requestKeyVerification(
|
||||
methods: List<VerificationMethod>,
|
||||
otherUserId: String,
|
||||
otherDevices: List<String>?
|
||||
): PendingVerificationRequest {
|
||||
val verification = when (val identity = olmMachine.getIdentity(otherUserId)) {
|
||||
override suspend fun requestSelfKeyVerification(methods: List<VerificationMethod>): PendingVerificationRequest {
|
||||
val verification = when (val identity = olmMachine.getIdentity(olmMachine.userId())) {
|
||||
is OwnUserIdentity -> identity.requestVerification(methods)
|
||||
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")
|
||||
}
|
||||
|
||||
return verification.toPendingVerificationRequest()
|
||||
}
|
||||
|
||||
@ -249,7 +244,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||
roomId: String,
|
||||
localId: String?
|
||||
): PendingVerificationRequest {
|
||||
Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId")
|
||||
olmMachine.ensureUsersKeys(listOf(otherUserId))
|
||||
val verification = when (val identity = olmMachine.getIdentity(otherUserId)) {
|
||||
is UserIdentity -> identity.requestVerification(methods, roomId, localId!!)
|
||||
is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user")
|
||||
@ -284,78 +279,49 @@ 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(
|
||||
method: VerificationMethod,
|
||||
otherUserId: String,
|
||||
otherDeviceId: String,
|
||||
transactionId: String?
|
||||
transactionId: String
|
||||
): String? {
|
||||
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()
|
||||
|
||||
if (sas != null) {
|
||||
dispatcher.dispatchTxAdded(sas)
|
||||
sas.transactionId
|
||||
} else {
|
||||
null
|
||||
}
|
||||
if (sas != null) {
|
||||
dispatcher.dispatchTxAdded(sas)
|
||||
sas.transactionId
|
||||
} else {
|
||||
// This starts the short SAS flow, the one that doesn't start with
|
||||
// a `m.key.verification.request`, Element web stopped doing this, might
|
||||
// be wise do do so as well
|
||||
// DeviceListBottomSheetViewModel triggers this, interestingly the method that
|
||||
// triggers this is called `manuallyVerify()`
|
||||
val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId)
|
||||
val verification = otherDevice?.startVerification()
|
||||
if (verification != null) {
|
||||
dispatcher.dispatchTxAdded(verification)
|
||||
verification.transactionId
|
||||
} 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 beginDeviceVerification(otherUserId: String, otherDeviceId: String): String? {
|
||||
// This starts the short SAS flow, the one that doesn't start with
|
||||
// a `m.key.verification.request`, Element web stopped doing this, might
|
||||
// be wise do do so as well
|
||||
// DeviceListBottomSheetViewModel triggers this, interestingly the method that
|
||||
// triggers this is called `manuallyVerify()`
|
||||
val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId)
|
||||
val verification = otherDevice?.startVerification()
|
||||
return if (verification != null) {
|
||||
dispatcher.dispatchTxAdded(verification)
|
||||
verification.transactionId
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun cancelVerificationRequest(request: PendingVerificationRequest) {
|
||||
val verificationRequest = request.transactionId?.let {
|
||||
olmMachine.getVerificationRequest(request.otherUserId, it)
|
||||
}
|
||||
verificationRequest?.cancel()
|
||||
request.transactionId ?: return
|
||||
cancelVerificationRequest(request.otherUserId, request.transactionId)
|
||||
}
|
||||
|
||||
override suspend fun declineVerificationRequestInDMs(
|
||||
otherUserId: String,
|
||||
transactionId: String,
|
||||
roomId: String
|
||||
) {
|
||||
override suspend fun cancelVerificationRequest(otherUserId: String, transactionId: String) {
|
||||
val verificationRequest = olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||
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.VerificationTransaction
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||
import org.matrix.android.sdk.common.CommonTestHelper
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
@ -134,10 +135,8 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||
onView(withId(R.id.bottomSheetFragmentContainer))
|
||||
.check(matches(not(hasDescendant(withText(R.string.verification_cannot_access_other_session)))))
|
||||
|
||||
val request = existingSession!!.cryptoService().verificationService().requestKeyVerification(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
existingSession!!.myUserId,
|
||||
listOf(uiSession.sessionParams.deviceId!!)
|
||||
val request = existingSession!!.cryptoService().verificationService().requestSelfKeyVerification(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW)
|
||||
)
|
||||
|
||||
val transactionId = request.transactionId!!
|
||||
|
@ -166,9 +166,8 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
||||
}
|
||||
}
|
||||
dismissedAction = LaunchCoroutineRunnable(coroutineScope) {
|
||||
session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
|
||||
pr.transactionId ?: "",
|
||||
pr.roomId ?: ""
|
||||
session?.cryptoService()?.verificationService()?.cancelVerificationRequest(pr.otherUserId,
|
||||
pr.transactionId ?: ""
|
||||
)
|
||||
}
|
||||
colorAttribute = R.attr.vctr_notice_secondary
|
||||
|
@ -238,7 +238,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||
handleRequestVerificationByDM(roomId, otherUserId)
|
||||
}
|
||||
is VerificationAction.StartSASVerification -> {
|
||||
handleStartSASVerification(roomId, otherUserId, action)
|
||||
handleStartSASVerification(otherUserId, action)
|
||||
}
|
||||
is VerificationAction.RemoteQrCodeScanned -> {
|
||||
handleRemoteQrCodeScanned(action)
|
||||
@ -284,28 +284,16 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||
}.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)
|
||||
?: return
|
||||
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
||||
viewModelScope.launch {
|
||||
if (roomId == null) {
|
||||
session.cryptoService().verificationService().beginKeyVerification(
|
||||
VerificationMethod.SAS,
|
||||
otherUserId = request.otherUserId,
|
||||
otherDeviceId = otherDevice ?: "",
|
||||
transactionId = action.pendingRequestTransactionId
|
||||
)
|
||||
} else {
|
||||
session.cryptoService().verificationService().beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
transactionId = action.pendingRequestTransactionId,
|
||||
roomId = roomId,
|
||||
otherUserId = request.otherUserId,
|
||||
otherDeviceId = otherDevice ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSASDoNotMatchAction(action: VerificationAction.SASDoNotMatchAction) {
|
||||
|
@ -995,10 +995,9 @@ class TimelineViewModel @AssistedInject constructor(
|
||||
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
|
||||
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
|
||||
viewModelScope.launch {
|
||||
if (session.cryptoService().verificationService().readyPendingVerificationInDMs(
|
||||
if (session.cryptoService().verificationService().readyPendingVerification(
|
||||
supportedVerificationMethodsProvider.provide(),
|
||||
action.otherUserId,
|
||||
room.roomId,
|
||||
action.transactionId)) {
|
||||
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action))
|
||||
} else {
|
||||
@ -1009,10 +1008,9 @@ class TimelineViewModel @AssistedInject constructor(
|
||||
|
||||
private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) {
|
||||
viewModelScope.launch {
|
||||
session.cryptoService().verificationService().declineVerificationRequestInDMs(
|
||||
session.cryptoService().verificationService().cancelVerificationRequest(
|
||||
action.otherUserId,
|
||||
action.transactionId,
|
||||
room.roomId)
|
||||
action.transactionId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,10 +217,8 @@ class DefaultNavigator @Inject constructor(
|
||||
override fun requestSessionVerification(context: Context, otherSessionId: String) {
|
||||
coroutineScope.launch {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return@launch
|
||||
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
||||
supportedVerificationMethodsProvider.provide(),
|
||||
session.myUserId,
|
||||
listOf(otherSessionId)
|
||||
val pr = session.cryptoService().verificationService().requestSelfKeyVerification(
|
||||
supportedVerificationMethodsProvider.provide()
|
||||
)
|
||||
if (context is AppCompatActivity) {
|
||||
VerificationBottomSheet.withArgs(
|
||||
@ -241,10 +239,8 @@ class DefaultNavigator @Inject constructor(
|
||||
.map { it.deviceId }
|
||||
if (context is AppCompatActivity) {
|
||||
if (otherSessions.isNotEmpty()) {
|
||||
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
||||
supportedVerificationMethodsProvider.provide(),
|
||||
session.myUserId,
|
||||
otherSessions)
|
||||
val pr = session.cryptoService().verificationService().requestSelfKeyVerification(
|
||||
supportedVerificationMethodsProvider.provide())
|
||||
VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId)
|
||||
.show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
||||
} else {
|
||||
|
@ -126,11 +126,10 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
|
||||
private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) {
|
||||
if (!initialState.allowDeviceAction) return
|
||||
viewModelScope.launch {
|
||||
session.cryptoService().verificationService().beginKeyVerification(
|
||||
method = VerificationMethod.SAS,
|
||||
session.cryptoService().verificationService().beginDeviceVerification(
|
||||
otherUserId = initialState.userId,
|
||||
otherDeviceId = action.deviceId,
|
||||
transactionId = null)?.let { txID ->
|
||||
)?.let { txID ->
|
||||
_viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID))
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ class DevicesViewModel @AssistedInject constructor(
|
||||
viewModelScope.launch {
|
||||
val txID = session.cryptoService()
|
||||
.verificationService()
|
||||
.beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null)
|
||||
.beginDeviceVerification(session.myUserId, action.deviceId)
|
||||
_viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
|
||||
session.myUserId,
|
||||
txID
|
||||
|
Loading…
Reference in New Issue
Block a user