diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt index 44af87bcbe..f3650b87be 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt @@ -183,8 +183,8 @@ class XSigningTest : InstrumentedTest { assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice) // Manually mark it as trusted from first session - mTestHelper.doSync { - bobSession.cryptoService().crossSigningService().trustDevice(bobSecondDeviceId, it) + mTestHelper.runBlockingTest { + bobSession.cryptoService().crossSigningService().trustDevice(bobSecondDeviceId) } // Now alice should cross trust bob's second device diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 40659cef11..d1dc65ba83 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -103,7 +103,7 @@ class KeyShareTests : InstrumentedTest { val outgoingRequestsBefore = aliceSession2.cryptoService().getOutgoingRoomKeyRequests() // Try to request - aliceSession2.cryptoService().requestRoomKeyForEvent(receivedEvent.root) + aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root) val waitLatch = CountDownLatch(1) val eventMegolmSessionId = receivedEvent.root.content.toModel()?.sessionId diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index c939952dc9..ac0f50df9a 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -24,7 +24,6 @@ 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.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.EventType @@ -217,8 +216,10 @@ class WithHeldTests : InstrumentedTest { mCryptoTestHelper.initializeCrossSigning(bobSecondSession) // Trust bob second device from Alice POV - aliceSession.cryptoService().crossSigningService().trustDevice(bobSecondSession.sessionParams.deviceId!!, NoOpMatrixCallback()) - bobSecondSession.cryptoService().crossSigningService().trustDevice(aliceSession.sessionParams.deviceId!!, NoOpMatrixCallback()) + mTestHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().trustDevice(bobSecondSession.sessionParams.deviceId!!) + bobSecondSession.cryptoService().crossSigningService().trustDevice(aliceSession.sessionParams.deviceId!!) + } var sessionId: String? = null // Check that the diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index 7c3a0101c8..1d97488ebc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -61,7 +61,7 @@ interface CrossSigningService { * This will check if the injected private cross signing keys match the public ones provided * by the server and if they do so */ - fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, + suspend fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, uskKeyPrivateKey: String?, sskPrivateKey: String?): UserTrustResult @@ -102,8 +102,8 @@ interface CrossSigningService { /** * Sign one of your devices and upload the signature */ - fun trustDevice(deviceId: String, - callback: MatrixCallback) + @Throws + suspend fun trustDevice(deviceId: String) suspend fun shieldForGroup(userIds: List): RoomEncryptionTrustLevel diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index e10778bfbd..dfb76401e0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -554,9 +554,17 @@ internal class OlmMachine( UserIdentity(identity.userId, masterKey, selfSigningKey, this, this.requestSender) } is RustUserIdentity.Own -> { - val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel() - val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel() - val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel() + val verified = this.inner().isIdentityVerified(userId) + + val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } OwnUserIdentity( identity.userId, @@ -823,13 +831,28 @@ internal class OlmMachine( suspend fun importCrossSigningKeys(export: PrivateKeysInfo): UserTrustResult { val rustExport = CrossSigningKeyExport(export.master, export.selfSigned, export.user) + var result: UserTrustResult withContext(Dispatchers.IO) { - inner.importCrossSigningKeys(rustExport) - } + result = try { + inner.importCrossSigningKeys(rustExport) - this.updateLivePrivateKeys() - // TODO map the errors from importCrossSigningKeys to the UserTrustResult - return UserTrustResult.Success + // Sign the cross signing keys with our device + // Fail silently if signature upload fails?? + try { + getIdentity(userId())?.verify() + } catch (failure: Throwable) { + Timber.e(failure, "Failed to sign x-keys with own device") + } + UserTrustResult.Success + } catch (failure: Exception) { + // KeyImportError? + UserTrustResult.Failure(failure.localizedMessage) + } + } + withContext(Dispatchers.Main) { + this@OlmMachine.updateLivePrivateKeys() + } + return result } suspend fun sign(message: String): Map> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index 4c9d62f610..07918870d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -73,7 +73,7 @@ internal class RustCrossSigningService @Inject constructor( if (verified) { UserTrustResult.Success } else { - UserTrustResult.UnknownCrossSignatureInfo(otherUserId) + UserTrustResult.Failure("failed to verify $otherUserId") } } else { UserTrustResult.CrossSigningNotConfigured(otherUserId) @@ -94,15 +94,13 @@ internal class RustCrossSigningService @Inject constructor( * This will check if the injected private cross signing keys match the public ones provided * by the server and if they do so */ - override fun checkTrustFromPrivateKeys( + override suspend fun checkTrustFromPrivateKeys( masterKeyPrivateKey: String?, uskKeyPrivateKey: String?, sskPrivateKey: String? ): UserTrustResult { val export = PrivateKeysInfo(masterKeyPrivateKey, sskPrivateKey, uskKeyPrivateKey) - return runBlocking { - olmMachineProvider.olmMachine.importCrossSigningKeys(export) - } + return olmMachine.importCrossSigningKeys(export) } /** @@ -171,19 +169,19 @@ internal class RustCrossSigningService @Inject constructor( /** * Sign one of your devices and upload the signature */ - override fun trustDevice(deviceId: String, callback: MatrixCallback) { - val device = runBlocking { olmMachine.getDevice(olmMachine.userId(), deviceId) } + override suspend fun trustDevice(deviceId: String) { + val device = olmMachine.getDevice(olmMachine.userId(), deviceId) return if (device != null) { - val verified = runBlocking { device.verify() } + val verified = device.verify() if (verified) { - callback.onSuccess(Unit) + return } else { - callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known, or not yours")) + throw IllegalArgumentException("This device [$deviceId] is not known, or not yours") } } else { - callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known")) + throw IllegalArgumentException("This device [$deviceId] is not known") } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt index 20e7ca09ab..e86c9c377a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt @@ -16,9 +16,6 @@ package org.matrix.android.sdk.internal.crypto.crosssigning -import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey - sealed class UserTrustResult { object Success : UserTrustResult() @@ -26,10 +23,11 @@ sealed class UserTrustResult { // data class UnknownDevice(val deviceID: String) : UserTrustResult() data class CrossSigningNotConfigured(val userID: String) : UserTrustResult() - data class UnknownCrossSignatureInfo(val userID: String) : UserTrustResult() - data class KeysNotTrusted(val key: MXCrossSigningInfo) : UserTrustResult() - data class KeyNotSigned(val key: CryptoCrossSigningKey) : UserTrustResult() - data class InvalidSignature(val key: CryptoCrossSigningKey, val signature: String) : UserTrustResult() + data class Failure(val message: String) : UserTrustResult() +// data class UnknownCrossSignatureInfo(val userID: String) : UserTrustResult() +// data class KeysNotTrusted(val key: MXCrossSigningInfo) : UserTrustResult() +// data class KeyNotSigned(val key: CryptoCrossSigningKey) : UserTrustResult() +// data class InvalidSignature(val key: CryptoCrossSigningKey, val signature: String) : UserTrustResult() } fun UserTrustResult.isVerified() = this is UserTrustResult.Success diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 03940e89e2..ed29f5b1d0 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -33,7 +33,6 @@ import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.session.Session 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 @@ -372,7 +371,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( try { action.cypherData.fromBase64().inputStream().use { ins -> val res = session.loadSecureSecret>(ins, action.alias) - val trustResult = session.cryptoService().crossSigningService().checkTrustFromPrivateKeys( + val crossSigningService = session.cryptoService().crossSigningService() + val trustResult = crossSigningService.checkTrustFromPrivateKeys( res?.get(MASTER_KEY_SSSS_NAME), res?.get(USER_SIGNING_KEY_SSSS_NAME), res?.get(SELF_SIGNING_KEY_SSSS_NAME) @@ -380,12 +380,11 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( if (trustResult.isVerified()) { // Sign this device and upload the signature session.sessionParams.deviceId?.let { deviceId -> - session.cryptoService() - .crossSigningService().trustDevice(deviceId, object : MatrixCallback { - override fun onFailure(failure: Throwable) { - Timber.w(failure, "Failed to sign my device after recovery") - } - }) + try { + crossSigningService.trustDevice(deviceId) + } catch (failure: Exception) { + Timber.w(failure, "Failed to sign my device after recovery") + } } setState { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index c8b595a5ed..b99d1f0aff 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -261,9 +261,7 @@ class DevicesViewModel @AssistedInject constructor( viewModelScope.launch { if (state.hasAccountCrossSigning) { try { - awaitCallback { - session.cryptoService().crossSigningService().trustDevice(action.cryptoDeviceInfo.deviceId, it) - } + session.cryptoService().crossSigningService().trustDevice(action.cryptoDeviceInfo.deviceId) } catch (failure: Throwable) { Timber.e("Failed to manually cross sign device ${action.cryptoDeviceInfo.deviceId} : ${failure.localizedMessage}") _viewEvents.post(DevicesViewEvents.Failure(failure))