Merge pull request #8654 from vector-im/bca/fix_8653_qr_code
Fix QR code login support in rust
This commit is contained in:
commit
59ddf1a107
|
@ -0,0 +1 @@
|
||||||
|
Fix Login with QR code not working with rust crypto.
|
|
@ -216,7 +216,7 @@ dependencies {
|
||||||
|
|
||||||
implementation libs.google.phonenumber
|
implementation libs.google.phonenumber
|
||||||
|
|
||||||
rustCryptoImplementation("org.matrix.rustcomponents:crypto-android:0.3.14")
|
rustCryptoImplementation("org.matrix.rustcomponents:crypto-android:0.3.15")
|
||||||
// rustCryptoApi project(":library:rustCrypto")
|
// rustCryptoApi project(":library:rustCrypto")
|
||||||
|
|
||||||
testImplementation libs.tests.junit
|
testImplementation libs.tests.junit
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.JUnit4
|
import org.junit.runners.JUnit4
|
||||||
import org.junit.runners.MethodSorters
|
import org.junit.runners.MethodSorters
|
||||||
|
import org.matrix.android.sdk.BuildConfig
|
||||||
import org.matrix.android.sdk.InstrumentedTest
|
import org.matrix.android.sdk.InstrumentedTest
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
@ -196,6 +197,7 @@ class E2eeShareKeysHistoryTest : InstrumentedTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNeedsRotationFromSharedToWorldReadable() {
|
fun testNeedsRotationFromSharedToWorldReadable() {
|
||||||
|
Assume.assumeTrue("Test is flacky on legacy crypto", BuildConfig.FLAVOR == "rustCrypto")
|
||||||
testRotationDueToVisibilityChange(RoomHistoryVisibility.SHARED, RoomHistoryVisibilityContent("world_readable"))
|
testRotationDueToVisibilityChange(RoomHistoryVisibility.SHARED, RoomHistoryVisibilityContent("world_readable"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,13 @@ internal class SecretShareManager @Inject constructor(
|
||||||
.w("handleSecretRequest() : malformed request norequestingDeviceId ")
|
.w("handleSecretRequest() : malformed request norequestingDeviceId ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (deviceId == credentials.deviceId) {
|
||||||
|
return Unit.also {
|
||||||
|
Timber.tag(loggerTag.value)
|
||||||
|
.v("handleSecretRequest() : Ignore request from self device")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val device = cryptoStore.getUserDevice(credentials.userId, deviceId)
|
val device = cryptoStore.getUserDevice(credentials.userId, deviceId)
|
||||||
?: return Unit.also {
|
?: return Unit.also {
|
||||||
Timber.tag(loggerTag.value)
|
Timber.tag(loggerTag.value)
|
||||||
|
@ -254,6 +261,37 @@ internal class SecretShareManager @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun requestMissingSecrets() {
|
||||||
|
// quick implementation for backward compatibility with rust, will request all secrets to all own devices
|
||||||
|
val secretNames = listOf(MASTER_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, KEYBACKUP_SECRET_SSSS_NAME)
|
||||||
|
|
||||||
|
secretNames.forEach { secretName ->
|
||||||
|
val toDeviceContent = SecretShareRequest(
|
||||||
|
requestingDeviceId = credentials.deviceId,
|
||||||
|
secretName = secretName,
|
||||||
|
requestId = createUniqueTxnId()
|
||||||
|
)
|
||||||
|
|
||||||
|
val contentMap = MXUsersDevicesMap<Any>()
|
||||||
|
contentMap.setObject(credentials.userId, "*", toDeviceContent)
|
||||||
|
|
||||||
|
val params = SendToDeviceTask.Params(
|
||||||
|
eventType = EventType.REQUEST_SECRET,
|
||||||
|
contentMap = contentMap
|
||||||
|
)
|
||||||
|
try {
|
||||||
|
withContext(coroutineDispatchers.io) {
|
||||||
|
sendToDeviceTask.execute(params)
|
||||||
|
}
|
||||||
|
Timber.tag(loggerTag.value)
|
||||||
|
.d("Secret request sent for $secretName")
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
Timber.tag(loggerTag.value)
|
||||||
|
.w("Failed to request secret $secretName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun onSecretSendReceived(toDevice: Event, handleGossip: ((name: String, value: String) -> Boolean)) {
|
suspend fun onSecretSendReceived(toDevice: Event, handleGossip: ((name: String, value: String) -> Boolean)) {
|
||||||
Timber.tag(loggerTag.value)
|
Timber.tag(loggerTag.value)
|
||||||
.i("onSecretSend() from ${toDevice.senderId} : onSecretSendReceived ${toDevice.content?.get("sender_key")}")
|
.i("onSecretSend() from ${toDevice.senderId} : onSecretSendReceived ${toDevice.content?.get("sender_key")}")
|
||||||
|
|
|
@ -34,10 +34,6 @@ import org.matrix.android.sdk.api.rendezvous.model.SecureRendezvousChannelAlgori
|
||||||
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransport
|
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransport
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
|
import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
|
|
||||||
import org.matrix.android.sdk.api.util.MatrixJsonParser
|
import org.matrix.android.sdk.api.util.MatrixJsonParser
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
@ -222,15 +218,10 @@ class Rendezvous(
|
||||||
Timber.tag(TAG).i("No master key given by verifying device")
|
Timber.tag(TAG).i("No master key given by verifying device")
|
||||||
}
|
}
|
||||||
|
|
||||||
// request secrets from the verifying device
|
// request secrets from other sessions.
|
||||||
Timber.tag(TAG).i("Requesting secrets from $verifyingDeviceId")
|
Timber.tag(TAG).i("Requesting secrets from other sessions")
|
||||||
|
|
||||||
session.sharedSecretStorageService().let {
|
session.sharedSecretStorageService().requestMissingSecrets()
|
||||||
it.requestSecret(MASTER_KEY_SSSS_NAME, verifyingDeviceId)
|
|
||||||
it.requestSecret(SELF_SIGNING_KEY_SSSS_NAME, verifyingDeviceId)
|
|
||||||
it.requestSecret(USER_SIGNING_KEY_SSSS_NAME, verifyingDeviceId)
|
|
||||||
it.requestSecret(KEYBACKUP_SECRET_SSSS_NAME, verifyingDeviceId)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Timber.tag(TAG).i("Not doing verification")
|
Timber.tag(TAG).i("Not doing verification")
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,5 +135,11 @@ interface SharedSecretStorageService {
|
||||||
|
|
||||||
fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?): IntegrityResult
|
fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?): IntegrityResult
|
||||||
|
|
||||||
|
@Deprecated("Requesting custom secrets not yet support by rust stack, prefer requestMissingSecrets")
|
||||||
suspend fun requestSecret(name: String, myOtherDeviceId: String)
|
suspend fun requestSecret(name: String, myOtherDeviceId: String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the missing local secrets to other sessions.
|
||||||
|
*/
|
||||||
|
suspend fun requestMissingSecrets()
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,12 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||||
return IntegrityResult.Success(keyInfo.content.passphrase != null)
|
return IntegrityResult.Success(keyInfo.content.passphrase != null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Requesting custom secrets not yet support by rust stack, prefer requestMissingSecrets")
|
||||||
override suspend fun requestSecret(name: String, myOtherDeviceId: String) {
|
override suspend fun requestSecret(name: String, myOtherDeviceId: String) {
|
||||||
secretShareManager.requestSecretTo(myOtherDeviceId, name)
|
secretShareManager.requestSecretTo(myOtherDeviceId, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun requestMissingSecrets() {
|
||||||
|
secretShareManager.requestMissingSecrets()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ import org.matrix.rustcomponents.sdk.crypto.DeviceLists
|
||||||
import org.matrix.rustcomponents.sdk.crypto.EncryptionSettings
|
import org.matrix.rustcomponents.sdk.crypto.EncryptionSettings
|
||||||
import org.matrix.rustcomponents.sdk.crypto.KeyRequestPair
|
import org.matrix.rustcomponents.sdk.crypto.KeyRequestPair
|
||||||
import org.matrix.rustcomponents.sdk.crypto.KeysImportResult
|
import org.matrix.rustcomponents.sdk.crypto.KeysImportResult
|
||||||
|
import org.matrix.rustcomponents.sdk.crypto.LocalTrust
|
||||||
import org.matrix.rustcomponents.sdk.crypto.Logger
|
import org.matrix.rustcomponents.sdk.crypto.Logger
|
||||||
import org.matrix.rustcomponents.sdk.crypto.MegolmV1BackupKey
|
import org.matrix.rustcomponents.sdk.crypto.MegolmV1BackupKey
|
||||||
import org.matrix.rustcomponents.sdk.crypto.Request
|
import org.matrix.rustcomponents.sdk.crypto.Request
|
||||||
|
@ -869,6 +870,11 @@ internal class OlmMachine @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun requestMissingSecretsFromOtherSessions(): Boolean {
|
||||||
|
return withContext(coroutineDispatchers.io) {
|
||||||
|
inner.queryMissingSecretsFromOtherSessions()
|
||||||
|
}
|
||||||
|
}
|
||||||
@Throws(CryptoStoreException::class)
|
@Throws(CryptoStoreException::class)
|
||||||
suspend fun enableBackupV1(key: String, version: String) {
|
suspend fun enableBackupV1(key: String, version: String) {
|
||||||
return withContext(coroutineDispatchers.computation) {
|
return withContext(coroutineDispatchers.computation) {
|
||||||
|
@ -934,4 +940,11 @@ internal class OlmMachine @Inject constructor(
|
||||||
inner.verifyBackup(serializedAuthData)
|
inner.verifyBackup(serializedAuthData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws(CryptoStoreException::class)
|
||||||
|
suspend fun setDeviceLocalTrust(userId: String, deviceId: String, trusted: Boolean) {
|
||||||
|
withContext(coroutineDispatchers.io) {
|
||||||
|
inner.setLocalTrust(userId, deviceId, if (trusted) LocalTrust.VERIFIED else LocalTrust.UNSET)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.listeners.ProgressListener
|
import org.matrix.android.sdk.api.listeners.ProgressListener
|
||||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||||
|
@ -536,7 +537,8 @@ internal class RustCryptoService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) {
|
override suspend fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) {
|
||||||
TODO("Not yet implemented")
|
Timber.w("Rust stack only support API to set local trust")
|
||||||
|
olmMachine.setDeviceLocalTrust(userId, deviceId, trustLevel.isLocallyVerified().orFalse())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,15 +16,29 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.crypto
|
package org.matrix.android.sdk.internal.crypto
|
||||||
|
|
||||||
import org.matrix.android.sdk.BuildConfig
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.internal.crypto.network.OutgoingRequestsProcessor
|
||||||
|
import org.matrix.rustcomponents.sdk.crypto.Request
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Provider
|
||||||
|
|
||||||
internal class SecretShareManager @Inject constructor() {
|
internal class SecretShareManager @Inject constructor(
|
||||||
|
private val olmMachine: Provider<OlmMachine>,
|
||||||
|
private val outgoingRequestsProcessor: OutgoingRequestsProcessor) {
|
||||||
|
|
||||||
suspend fun requestSecretTo(deviceId: String, secretName: String) {
|
suspend fun requestSecretTo(deviceId: String, secretName: String) {
|
||||||
// nop in rust?
|
Timber.w("SecretShareManager requesting custom secrets not supported $deviceId, $secretName")
|
||||||
if (BuildConfig.DEBUG) TODO("requestSecretTo Not implemented in Rust")
|
// rust stack only support requesting secrets defined in the spec (not custom secret yet)
|
||||||
Timber.e("SecretShareManager Not supported in rust $deviceId, $secretName")
|
requestMissingSecrets()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun requestMissingSecrets() {
|
||||||
|
this.olmMachine.get().requestMissingSecretsFromOtherSessions()
|
||||||
|
|
||||||
|
// immediately send the requests
|
||||||
|
outgoingRequestsProcessor.processOutgoingRequests(this.olmMachine.get()) {
|
||||||
|
it is Request.ToDevice && it.eventType == EventType.REQUEST_SECRET
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,15 @@ class FakeSharedSecretStorageService : SharedSecretStorageService by mockk() {
|
||||||
|
|
||||||
override fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?) = integrityResult
|
override fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?) = integrityResult
|
||||||
|
|
||||||
|
@Deprecated("Requesting custom secrets not yet support by rust stack, prefer requestMissingSecrets")
|
||||||
override suspend fun requestSecret(name: String, myOtherDeviceId: String) {
|
override suspend fun requestSecret(name: String, myOtherDeviceId: String) {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun requestMissingSecrets() {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
fun givenIsRecoverySetupReturns(isRecoverySetup: Boolean) {
|
fun givenIsRecoverySetupReturns(isRecoverySetup: Boolean) {
|
||||||
every { isRecoverySetup() } returns isRecoverySetup
|
every { isRecoverySetup() } returns isRecoverySetup
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue