mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-12-28 03:48:37 +03:00
Fix verify with passphrase own device not trusted
This commit is contained in:
parent
2167564812
commit
f0f64d8380
9 changed files with 63 additions and 46 deletions
|
@ -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<Unit> {
|
||||
bobSession.cryptoService().crossSigningService().trustDevice(bobSecondDeviceId, it)
|
||||
mTestHelper.runBlockingTest {
|
||||
bobSession.cryptoService().crossSigningService().trustDevice(bobSecondDeviceId)
|
||||
}
|
||||
|
||||
// Now alice should cross trust bob's second device
|
||||
|
|
|
@ -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<EncryptedEventContent>()?.sessionId
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Unit>)
|
||||
@Throws
|
||||
suspend fun trustDevice(deviceId: String)
|
||||
|
||||
suspend fun shieldForGroup(userIds: List<String>): RoomEncryptionTrustLevel
|
||||
|
||||
|
|
|
@ -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<String, Map<String, String>> {
|
||||
|
|
|
@ -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<Unit>) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Map<String, String>>(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<Unit> {
|
||||
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 {
|
||||
|
|
|
@ -261,9 +261,7 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
viewModelScope.launch {
|
||||
if (state.hasAccountCrossSigning) {
|
||||
try {
|
||||
awaitCallback<Unit> {
|
||||
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))
|
||||
|
|
Loading…
Reference in a new issue