crypto: Try to import the recovery key if it was gossiped to us

This commit is contained in:
Damir Jelić 2021-11-04 14:35:01 +01:00
parent d6ecc7d330
commit 50268540c3
4 changed files with 35 additions and 3 deletions

View File

@ -80,6 +80,7 @@ import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent
import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse
import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent
@ -973,6 +974,12 @@ internal class DefaultCryptoService @Inject constructor(
notifyRoomKeyReceived(roomId, sessionId)
}
EventType.SEND_SECRET -> {
// The rust-sdk will clear this event if it's invalid, this will produce an invalid base64 error
// when we try to construct the recovery key.
val secretContent = event.getClearContent().toModel<SecretSendEventContent>() ?: return@forEach
this.keysBackupService?.onSecretKeyGossip(secretContent.secretValue)
}
else -> {
this.verificationService?.onEvent(event)
}

View File

@ -55,6 +55,7 @@ import org.matrix.android.sdk.internal.extensions.foldToCallback
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.util.JsonCanonicalizer
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
import org.matrix.android.sdk.internal.util.awaitCallback
import org.matrix.olm.OlmException
import timber.log.Timber
import uniffi.olm.BackupRecoveryKey
@ -407,7 +408,31 @@ internal class RustKeyBackupService @Inject constructor(
override fun onSecretKeyGossip(secret: String) {
Timber.i("## CrossSigning - onSecretKeyGossip")
TODO()
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
try {
val version = sender.getKeyBackupVersion()
if (version != null) {
val key = BackupRecoveryKey.fromBase64(secret)
awaitCallback<Unit> {
trustKeysBackupVersion(version, true, it)
}
val importResult = awaitCallback<ImportRoomKeysResult> {
cryptoCoroutineScope.launch {
restoreBackup(version, key, null, null, null)
}
}
Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}")
saveBackupRecoveryKey(secret, version.version)
} else {
Timber.e("onSecretKeyGossip: Failed to import backup recovery key, no backup version was found on the server")
}
} catch (failure: Throwable) {
Timber.e("onSecretKeyGossip: failed to trust key backup version ${keysBackupVersion?.version}: $failure")
}
}
}
override fun getBackupProgress(progressListener: ProgressListener) {

View File

@ -57,7 +57,7 @@ impl BackupRecoveryKey {
/// TODO
pub fn from_base64(key: String) -> Self {
Self {
inner: RecoveryKey::from_base64(key).unwrap(),
inner: RecoveryKey::from_base64(&key).unwrap(),
passphrase_info: None,
}
}

View File

@ -1311,7 +1311,7 @@ impl OlmMachine {
key: Option<String>,
version: Option<String>,
) -> Result<(), CryptoStoreError> {
let key = key.map(RecoveryKey::from_base64).transpose().ok().flatten();
let key = key.map(|k| RecoveryKey::from_base64(&k)).transpose().ok().flatten();
Ok(self
.runtime
.block_on(self.inner.backup_machine().save_recovery_key(key, version))?)