mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-12-25 18:38:32 +03:00
Use BackupRecoveryKey instead of plain string
This commit is contained in:
parent
7c76ba8184
commit
b0aae84727
16 changed files with 101 additions and 75 deletions
|
@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_S
|
|||
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.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupAuthData
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey
|
||||
|
@ -250,7 +251,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
|||
return MegolmBackupCreationInfo(
|
||||
algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP,
|
||||
authData = createFakeMegolmBackupAuthData(),
|
||||
recoveryKey = "fake"
|
||||
recoveryKey = BackupRecoveryKey.fromBase58("3cnTdW")
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -445,7 +446,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
|||
// Save it for gossiping
|
||||
session.cryptoService().keysBackupService().saveBackupRecoveryKey(creationInfo.recoveryKey, version = version.version)
|
||||
|
||||
extractCurveKeyFromRecoveryKey(creationInfo.recoveryKey)?.toBase64NoPadding()?.let { secret ->
|
||||
extractCurveKeyFromRecoveryKey(creationInfo.recoveryKey.toBase58())?.toBase64NoPadding()?.let { secret ->
|
||||
ssssService.storeSecret(
|
||||
KEYBACKUP_SECRET_SSSS_NAME,
|
||||
secret,
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.junit.runners.MethodSorters
|
|||
import org.matrix.android.sdk.InstrumentedTest
|
||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
|
||||
import org.matrix.android.sdk.api.listeners.StepProgressListener
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult
|
||||
|
@ -505,7 +506,7 @@ class KeysBackupTest : InstrumentedTest {
|
|||
try {
|
||||
testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey(
|
||||
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
"Bad recovery key"
|
||||
BackupRecoveryKey.fromBase58("Bad recovery key")
|
||||
)
|
||||
fail("Should have failed to trust")
|
||||
} catch (failure: Throwable) {
|
||||
|
@ -645,7 +646,7 @@ class KeysBackupTest : InstrumentedTest {
|
|||
var importRoomKeysResult: ImportRoomKeysResult? = null
|
||||
testHelper.runBlockingTest {
|
||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||
"EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d",
|
||||
BackupRecoveryKey.fromBase58("EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d"),
|
||||
null,
|
||||
null,
|
||||
null
|
||||
|
|
|
@ -142,8 +142,7 @@ interface KeysBackupService {
|
|||
* @param keysBackupVersion the backup version to check.
|
||||
* @param recoveryKey the recovery key to challenge with the key backup public key.
|
||||
*/
|
||||
suspend fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult,
|
||||
recoveryKey: String)
|
||||
suspend fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, recoveryKey: BackupRecoveryKey)
|
||||
|
||||
/**
|
||||
* Set trust on a keys backup version.
|
||||
|
@ -167,7 +166,7 @@ interface KeysBackupService {
|
|||
* @param callback Callback. It provides the number of found keys and the number of successfully imported keys.
|
||||
*/
|
||||
suspend fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult,
|
||||
recoveryKey: String, roomId: String?,
|
||||
recoveryKey: BackupRecoveryKey, roomId: String?,
|
||||
sessionId: String?,
|
||||
stepProgressListener: StepProgressListener?): ImportRoomKeysResult
|
||||
|
||||
|
@ -194,10 +193,10 @@ interface KeysBackupService {
|
|||
val state: KeysBackupState
|
||||
|
||||
// For gossiping
|
||||
fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
|
||||
fun saveBackupRecoveryKey(recoveryKey: BackupRecoveryKey?, version: String?)
|
||||
suspend fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo?
|
||||
|
||||
suspend fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String): Boolean
|
||||
suspend fun isValidRecoveryKeyForCurrentVersion(recoveryKey: BackupRecoveryKey): Boolean
|
||||
|
||||
fun computePrivateKey(passphrase: String,
|
||||
privateKeySalt: String,
|
||||
|
|
|
@ -31,7 +31,7 @@ data class MegolmBackupCreationInfo(
|
|||
val authData: MegolmBackupAuthData,
|
||||
|
||||
/**
|
||||
* The Base58 recovery key.
|
||||
* The recovery key.
|
||||
*/
|
||||
val recoveryKey: String
|
||||
val recoveryKey: BackupRecoveryKey
|
||||
)
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
package org.matrix.android.sdk.api.session.crypto.keysbackup
|
||||
|
||||
data class SavedKeyBackupKeyInfo(
|
||||
val recoveryKey: String,
|
||||
val recoveryKey: BackupRecoveryKey,
|
||||
val version: String
|
||||
)
|
||||
|
|
|
@ -20,10 +20,9 @@ import dagger.Lazy
|
|||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult
|
||||
import org.matrix.android.sdk.api.util.awaitCallback
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
|
@ -101,12 +100,12 @@ internal class PerSessionBackupQueryRateLimiter @Inject constructor(
|
|||
(now - lastTry.timestamp) > MIN_TRY_BACKUP_PERIOD_MILLIS
|
||||
|
||||
if (!shouldQuery) return false
|
||||
|
||||
val recoveryKey = savedKeyBackupKeyInfo?.recoveryKey ?: return false
|
||||
val successfullyImported = withContext(coroutineDispatchers.io) {
|
||||
try {
|
||||
keysBackupService.get().restoreKeysWithRecoveryKey(
|
||||
currentVersion,
|
||||
savedKeyBackupKeyInfo?.recoveryKey ?: "",
|
||||
recoveryKey,
|
||||
roomId,
|
||||
sessionId,
|
||||
null,
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.failure.Failure
|
|||
import org.matrix.android.sdk.api.failure.MatrixError
|
||||
import org.matrix.android.sdk.api.listeners.ProgressListener
|
||||
import org.matrix.android.sdk.api.listeners.StepProgressListener
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState
|
||||
|
@ -60,7 +61,6 @@ import org.matrix.android.sdk.internal.session.SessionScope
|
|||
import org.matrix.android.sdk.internal.util.JsonCanonicalizer
|
||||
import org.matrix.olm.OlmException
|
||||
import timber.log.Timber
|
||||
import uniffi.olm.BackupRecoveryKey
|
||||
import uniffi.olm.Request
|
||||
import uniffi.olm.RequestType
|
||||
import java.security.InvalidParameterException
|
||||
|
@ -150,7 +150,7 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
MegolmBackupCreationInfo(
|
||||
algorithm = publicKey.backupAlgorithm,
|
||||
authData = signedMegolmBackupAuthData,
|
||||
recoveryKey = key.toBase58()
|
||||
recoveryKey = key
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -189,9 +189,11 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) {
|
||||
override fun saveBackupRecoveryKey(recoveryKey: BackupRecoveryKey?, version: String?) {
|
||||
cryptoCoroutineScope.launch {
|
||||
olmMachine.saveRecoveryKey(recoveryKey, version)
|
||||
val recoveryKeyStr = recoveryKey?.toBase64()
|
||||
// TODO : change rust API to use BackupRecoveryKey
|
||||
olmMachine.saveRecoveryKey(recoveryKeyStr, version)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,7 +314,8 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
val body = UpdateKeysBackupVersionBody(
|
||||
algorithm = keysBackupVersion.algorithm,
|
||||
authData = newAuthData.copy(signatures = newSignatures).toJsonDict(),
|
||||
version = keysBackupVersion.version)
|
||||
version = keysBackupVersion.version
|
||||
)
|
||||
|
||||
withContext(coroutineDispatchers.io) {
|
||||
sender.updateBackup(keysBackupVersion, body)
|
||||
|
@ -353,14 +356,13 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, recoveryKey: String) {
|
||||
override suspend fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, recoveryKey: BackupRecoveryKey) {
|
||||
Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}")
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
// This is ~nowhere mentioned, the string here is actually a base58 encoded key.
|
||||
// This not really supported by the spec for the backup key, the 4S key supports
|
||||
// base58 encoding and the same method seems to be used here.
|
||||
val key = BackupRecoveryKey.fromBase58(recoveryKey)
|
||||
checkRecoveryKey(key, keysBackupVersion)
|
||||
checkRecoveryKey(recoveryKey, keysBackupVersion)
|
||||
trustKeysBackupVersion(keysBackupVersion, true)
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +380,7 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
withContext(coroutineDispatchers.crypto) {
|
||||
try {
|
||||
val version = sender.getKeyBackupLastVersion()?.toKeysVersionResult()
|
||||
|
||||
Timber.v("Keybackup version: $version")
|
||||
if (version != null) {
|
||||
val key = BackupRecoveryKey.fromBase64(secret)
|
||||
if (isValidRecoveryKey(key, version)) {
|
||||
|
@ -395,7 +397,9 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
}
|
||||
}
|
||||
// we can save, it's valid
|
||||
saveBackupRecoveryKey(key.toBase64(), version.version)
|
||||
saveBackupRecoveryKey(key, version.version)
|
||||
} else {
|
||||
Timber.d("Invalid recovery key")
|
||||
}
|
||||
} else {
|
||||
Timber.e("onSecretKeyGossip: Failed to import backup recovery key, no backup version was found on the server")
|
||||
|
@ -480,7 +484,7 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
}
|
||||
|
||||
// Save for next time and for gossiping
|
||||
saveBackupRecoveryKey(recoveryKey.toBase64(), keysVersionResult.version)
|
||||
saveBackupRecoveryKey(recoveryKey, keysVersionResult.version)
|
||||
}
|
||||
|
||||
withContext(coroutineDispatchers.main) {
|
||||
|
@ -519,14 +523,18 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
stepProgressListener?.onStepProgress(stepProgress)
|
||||
}
|
||||
|
||||
Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" +
|
||||
" of ${data.roomIdToRoomKeysBackupData.size} rooms from the backup store on the homeserver")
|
||||
Timber.v(
|
||||
"restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" +
|
||||
" of ${data.roomIdToRoomKeysBackupData.size} rooms from the backup store on the homeserver"
|
||||
)
|
||||
|
||||
// Do not trigger a backup for them if they come from the backup version we are using
|
||||
val backUp = keysVersionResult.version != keysBackupVersion?.version
|
||||
if (backUp) {
|
||||
Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up" +
|
||||
" to backup version: ${keysBackupVersion?.version}")
|
||||
Timber.v(
|
||||
"restoreKeysWithRecoveryKey: Those keys will be backed up" +
|
||||
" to backup version: ${keysBackupVersion?.version}"
|
||||
)
|
||||
}
|
||||
|
||||
// Import them into the crypto store
|
||||
|
@ -557,15 +565,12 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
}
|
||||
|
||||
override suspend fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult,
|
||||
recoveryKey: String,
|
||||
recoveryKey: BackupRecoveryKey,
|
||||
roomId: String?,
|
||||
sessionId: String?,
|
||||
stepProgressListener: StepProgressListener?): ImportRoomKeysResult {
|
||||
Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}")
|
||||
|
||||
val key = BackupRecoveryKey.fromBase58(recoveryKey)
|
||||
|
||||
return restoreBackup(keysVersionResult, key, roomId, sessionId, stepProgressListener)
|
||||
return restoreBackup(keysVersionResult, recoveryKey, roomId, sessionId, stepProgressListener)
|
||||
}
|
||||
|
||||
override suspend fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult,
|
||||
|
@ -577,7 +582,6 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
val recoveryKey = withContext(coroutineDispatchers.crypto) {
|
||||
recoveryKeyFromPassword(password, keysBackupVersion)
|
||||
}
|
||||
|
||||
return restoreBackup(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener)
|
||||
}
|
||||
|
||||
|
@ -703,16 +707,15 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
private fun isValidRecoveryKey(recoveryKey: BackupRecoveryKey, version: KeysVersionResult): Boolean {
|
||||
val publicKey = recoveryKey.megolmV1PublicKey().publicKey
|
||||
val authData = getMegolmBackupAuthData(version) ?: return false
|
||||
Timber.v("recoveryKey.megolmV1PublicKey().publicKey $publicKey == getMegolmBackupAuthData(version).publicKey ${authData.publicKey}")
|
||||
return authData.publicKey == publicKey
|
||||
}
|
||||
|
||||
override suspend fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String): Boolean {
|
||||
override suspend fun isValidRecoveryKeyForCurrentVersion(recoveryKey: BackupRecoveryKey): Boolean {
|
||||
return withContext(coroutineDispatchers.crypto) {
|
||||
val keysBackupVersion = keysBackupVersion ?: return@withContext false
|
||||
|
||||
val key = BackupRecoveryKey.fromBase64(recoveryKey)
|
||||
try {
|
||||
isValidRecoveryKey(key, keysBackupVersion)
|
||||
isValidRecoveryKey(recoveryKey, keysBackupVersion)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.i("isValidRecoveryKeyForCurrentVersion: Invalid recovery key")
|
||||
false
|
||||
|
@ -726,7 +729,9 @@ internal class RustKeyBackupService @Inject constructor(
|
|||
|
||||
override suspend fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? {
|
||||
val info = olmMachine.getBackupKeys() ?: return null
|
||||
return SavedKeyBackupKeyInfo(info.recoveryKey, info.backupVersion)
|
||||
// TODO change rust ffi to return BackupRecoveryKey instead of base64 string
|
||||
val backupRecoveryKey = BackupRecoveryKey.fromBase64(info.recoveryKey)
|
||||
return SavedKeyBackupKeyInfo(backupRecoveryKey, info.backupVersion)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState
|
|||
import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.model.AuditTrail
|
||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
||||
|
@ -469,7 +470,8 @@ internal class RealmCryptoStore @Inject constructor(
|
|||
val key = it.keyBackupRecoveryKey
|
||||
val version = it.keyBackupRecoveryKeyVersion
|
||||
if (!key.isNullOrBlank() && !version.isNullOrBlank()) {
|
||||
SavedKeyBackupKeyInfo(recoveryKey = key, version = version)
|
||||
val backupRecoveryKey = BackupRecoveryKey.fromBase58(key)
|
||||
SavedKeyBackupKeyInfo(recoveryKey = backupRecoveryKey, version = version)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
|
|
@ -520,10 +520,9 @@ internal class RoomSyncHandler @Inject constructor(
|
|||
|
||||
private fun decryptIfNeeded(event: Event, roomId: String) {
|
||||
try {
|
||||
// Event from sync does not have roomId, so add it to the event first
|
||||
// note: runBlocking should be used here while we are in realm single thread executor, to avoid thread switching
|
||||
val result = runBlocking {
|
||||
cryptoService.decryptEvent(event.copy(roomId = roomId), "")
|
||||
cryptoService.decryptEvent(event, "")
|
||||
}
|
||||
event.mxDecryptionResult = OlmDecryptionResult(
|
||||
payload = result.clearEvent,
|
||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.core.platform.WaitingViewData
|
|||
import im.vector.app.core.resources.StringProvider
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupRestoreFromKeyViewModel @Inject constructor(
|
||||
|
@ -42,7 +43,7 @@ class KeysBackupRestoreFromKeyViewModel @Inject constructor(
|
|||
sharedViewModel.loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading)))
|
||||
recoveryCodeErrorText.value = null
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val recoveryKey = recoveryCode.value!!
|
||||
val recoveryKey = BackupRecoveryKey.fromBase58(recoveryCode.value!!)
|
||||
try {
|
||||
sharedViewModel.recoverUsingBackupRecoveryKey(recoveryKey)
|
||||
} catch (failure: Throwable) {
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
|
|||
import org.matrix.android.sdk.api.listeners.StepProgressListener
|
||||
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.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey
|
||||
|
@ -88,7 +89,7 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
private val progressObserver = object : StepProgressListener {
|
||||
override fun onStepProgress(step: StepProgressListener.Step) {
|
||||
when (step) {
|
||||
is StepProgressListener.Step.ComputingKey -> {
|
||||
is StepProgressListener.Step.ComputingKey -> {
|
||||
loadingEvent.postValue(
|
||||
WaitingViewData(
|
||||
stringProvider.getString(R.string.keys_backup_restoring_waiting_message) +
|
||||
|
@ -107,7 +108,7 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
)
|
||||
)
|
||||
}
|
||||
is StepProgressListener.Step.ImportingKey -> {
|
||||
is StepProgressListener.Step.ImportingKey -> {
|
||||
Timber.d("backupKeys.ImportingKey.progress: ${step.progress}")
|
||||
// Progress 0 can take a while, display an indeterminate progress in this case
|
||||
if (step.progress == 0) {
|
||||
|
@ -131,14 +132,22 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
}
|
||||
is StepProgressListener.Step.DecryptingKey -> {
|
||||
if (step.progress == 0) {
|
||||
loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) +
|
||||
"\n" + stringProvider.getString(R.string.keys_backup_restoring_decrypting_keys_waiting_message),
|
||||
isIndeterminate = true))
|
||||
loadingEvent.postValue(
|
||||
WaitingViewData(
|
||||
stringProvider.getString(R.string.keys_backup_restoring_waiting_message) +
|
||||
"\n" + stringProvider.getString(R.string.keys_backup_restoring_decrypting_keys_waiting_message),
|
||||
isIndeterminate = true
|
||||
)
|
||||
)
|
||||
} else {
|
||||
loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) +
|
||||
"\n" + stringProvider.getString(R.string.keys_backup_restoring_decrypting_keys_waiting_message),
|
||||
step.progress,
|
||||
step.total))
|
||||
loadingEvent.postValue(
|
||||
WaitingViewData(
|
||||
stringProvider.getString(R.string.keys_backup_restoring_waiting_message) +
|
||||
"\n" + stringProvider.getString(R.string.keys_backup_restoring_decrypting_keys_waiting_message),
|
||||
step.progress,
|
||||
step.total
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +179,7 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
)
|
||||
// Go and use it!!
|
||||
try {
|
||||
recoverUsingBackupRecoveryKey(computeRecoveryKey(savedSecret.recoveryKey.fromBase64()), version)
|
||||
recoverUsingBackupRecoveryKey(savedSecret.recoveryKey, version)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "## recoverUsingBackupRecoveryKey FAILED")
|
||||
keySourceModel.postValue(
|
||||
|
@ -212,7 +221,9 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
recoverUsingBackupRecoveryKey(computeRecoveryKey(secret.fromBase64()))
|
||||
val computedRecoveryKey = computeRecoveryKey(secret.fromBase64())
|
||||
val backupRecoveryKey = BackupRecoveryKey.fromBase58(computedRecoveryKey)
|
||||
recoverUsingBackupRecoveryKey(backupRecoveryKey)
|
||||
} catch (failure: Throwable) {
|
||||
_navigateEvent.postValue(
|
||||
LiveEvent(NAVIGATE_FAILED_TO_LOAD_4S)
|
||||
|
@ -234,7 +245,8 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading)))
|
||||
|
||||
try {
|
||||
val result = keysBackup.restoreKeyBackupWithPassword(keyVersion,
|
||||
val result = keysBackup.restoreKeyBackupWithPassword(
|
||||
keyVersion,
|
||||
passphrase,
|
||||
null,
|
||||
session.myUserId,
|
||||
|
@ -249,7 +261,7 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun recoverUsingBackupRecoveryKey(recoveryKey: String, keyVersion: KeysVersionResult? = null) {
|
||||
suspend fun recoverUsingBackupRecoveryKey(recoveryKey: BackupRecoveryKey, keyVersion: KeysVersionResult? = null) {
|
||||
val keysBackup = session.cryptoService().keysBackupService()
|
||||
// This is badddddd
|
||||
val version = keyVersion ?: keyVersionResult.value ?: return
|
||||
|
@ -257,7 +269,8 @@ class KeysBackupRestoreSharedViewModel @Inject constructor(
|
|||
loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading)))
|
||||
|
||||
try {
|
||||
val result = keysBackup.restoreKeysWithRecoveryKey(version,
|
||||
val result = keysBackup.restoreKeysWithRecoveryKey(
|
||||
version,
|
||||
recoveryKey,
|
||||
null,
|
||||
session.myUserId,
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.core.time.Clock
|
|||
import im.vector.app.core.utils.LiveEvent
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo
|
||||
|
@ -71,7 +72,7 @@ class KeysBackupSetupSharedViewModel @Inject constructor(
|
|||
// Step 3
|
||||
// Var to ignore events from previous request(s) to generate a recovery key
|
||||
private var currentRequestId: MutableLiveData<Long> = MutableLiveData()
|
||||
var recoveryKey: MutableLiveData<String?> = MutableLiveData(null)
|
||||
var recoveryKey: MutableLiveData<BackupRecoveryKey?> = MutableLiveData(null)
|
||||
var prepareRecoverFailError: MutableLiveData<Throwable?> = MutableLiveData(null)
|
||||
var megolmBackupCreationInfo: MegolmBackupCreationInfo? = null
|
||||
var copyHasBeenMade = false
|
||||
|
|
|
@ -66,7 +66,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
|
|||
views.keysBackupSetupStep3Label2.text = getString(R.string.keys_backup_setup_step3_text_line2_no_passphrase)
|
||||
views.keysBackupSetupStep3FinishButton.text = getString(R.string.keys_backup_setup_step3_button_title_no_passphrase)
|
||||
|
||||
views.keysBackupSetupStep3RecoveryKeyText.text = viewModel.recoveryKey.value!!
|
||||
views.keysBackupSetupStep3RecoveryKeyText.text = viewModel.recoveryKey.value!!.toBase58()
|
||||
.replace(" ", "")
|
||||
.chunked(16)
|
||||
.joinToString("\n") {
|
||||
|
@ -114,7 +114,8 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
|
|||
} else {
|
||||
dialog.findViewById<TextView>(R.id.keys_backup_recovery_key_text)?.let {
|
||||
it.isVisible = true
|
||||
it.text = recoveryKey.replace(" ", "")
|
||||
it.text = recoveryKey.toBase58()
|
||||
.replace(" ", "")
|
||||
.chunked(16)
|
||||
.joinToString("\n") {
|
||||
it
|
||||
|
@ -123,7 +124,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
|
|||
}
|
||||
|
||||
it.debouncedClicks {
|
||||
copyToClipboard(requireActivity(), recoveryKey)
|
||||
copyToClipboard(requireActivity(), recoveryKey.toBase58())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +146,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
|
|||
fragment = this,
|
||||
activityResultLauncher = null,
|
||||
chooserTitle = context?.getString(R.string.keys_backup_setup_step3_share_intent_chooser_title),
|
||||
text = recoveryKey,
|
||||
text = recoveryKey.toBase58(),
|
||||
subject = context?.getString(R.string.recovery_key)
|
||||
)
|
||||
viewModel.copyHasBeenMade = true
|
||||
|
@ -159,7 +160,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
|
|||
viewModel.recoveryKey.value?.let {
|
||||
viewModel.copyHasBeenMade = true
|
||||
|
||||
copyToClipboard(requireActivity(), it)
|
||||
copyToClipboard(requireActivity(), it.toBase58())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,7 +203,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
|
|||
val uri = activityRessult.data?.data ?: return@registerStartForActivityResult
|
||||
if (activityRessult.resultCode == Activity.RESULT_OK) {
|
||||
viewModel.recoveryKey.value?.let {
|
||||
exportRecoveryKeyToFile(uri, it)
|
||||
exportRecoveryKeyToFile(uri, it.toBase58())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.core.resources.StringProvider
|
|||
import org.matrix.android.sdk.api.listeners.ProgressListener
|
||||
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.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner
|
||||
|
@ -91,8 +92,8 @@ class BackupToQuadSMigrationTask @Inject constructor(
|
|||
|
||||
reportProgress(params, R.string.bootstrap_progress_compute_curve_key)
|
||||
val recoveryKey = computeRecoveryKey(curveKey)
|
||||
|
||||
val isValid = keysBackupService.isValidRecoveryKeyForCurrentVersion(recoveryKey)
|
||||
val backupRecoveryKey = BackupRecoveryKey.fromBase58(recoveryKey)
|
||||
val isValid = keysBackupService.isValidRecoveryKeyForCurrentVersion(backupRecoveryKey)
|
||||
|
||||
if (!isValid) return Result.InvalidRecoverySecret
|
||||
|
||||
|
@ -143,7 +144,7 @@ class BackupToQuadSMigrationTask @Inject constructor(
|
|||
)
|
||||
|
||||
// save for gossiping
|
||||
keysBackupService.saveBackupRecoveryKey(recoveryKey, version.version)
|
||||
keysBackupService.saveBackupRecoveryKey(backupRecoveryKey, version.version)
|
||||
// It's not a good idea to download the full backup, it might take very long
|
||||
// and use a lot of resources
|
||||
return Result.Success
|
||||
|
|
|
@ -236,7 +236,7 @@ class BootstrapCrossSigningTask @Inject constructor(
|
|||
Timber.d("## BootstrapCrossSigningTask: Creating 4S - Save megolm backup key for gossiping")
|
||||
session.cryptoService().keysBackupService().saveBackupRecoveryKey(creationInfo.recoveryKey, version = version.version)
|
||||
|
||||
extractCurveKeyFromRecoveryKey(creationInfo.recoveryKey)?.toBase64NoPadding()?.let { secret ->
|
||||
extractCurveKeyFromRecoveryKey(creationInfo.recoveryKey.toBase58())?.toBase64NoPadding()?.let { secret ->
|
||||
ssssService.storeSecret(
|
||||
KEYBACKUP_SECRET_SSSS_NAME,
|
||||
secret,
|
||||
|
@ -251,7 +251,7 @@ class BootstrapCrossSigningTask @Inject constructor(
|
|||
val isValid = session.cryptoService().keysBackupService().isValidRecoveryKeyForCurrentVersion(knownMegolmSecret!!.recoveryKey)
|
||||
if (isValid) {
|
||||
Timber.d("## BootstrapCrossSigningTask: Creating 4S - Megolm key valid and known")
|
||||
extractCurveKeyFromRecoveryKey(knownMegolmSecret.recoveryKey)?.toBase64NoPadding()?.let { secret ->
|
||||
extractCurveKeyFromRecoveryKey(knownMegolmSecret.recoveryKey.toBase58())?.toBase64NoPadding()?.let { secret ->
|
||||
ssssService.storeSecret(
|
||||
KEYBACKUP_SECRET_SSSS_NAME,
|
||||
secret,
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NA
|
|||
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.session.crypto.crosssigning.isVerified
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||
|
@ -431,9 +432,10 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
val version = session.cryptoService().keysBackupService().getCurrentVersion()?.toKeysVersionResult() ?: return@launch
|
||||
|
||||
val recoveryKey = computeRecoveryKey(secret.fromBase64())
|
||||
val isValid = session.cryptoService().keysBackupService().isValidRecoveryKeyForCurrentVersion(recoveryKey)
|
||||
val backupRecoveryKey = BackupRecoveryKey.fromBase58(recoveryKey)
|
||||
val isValid = session.cryptoService().keysBackupService().isValidRecoveryKeyForCurrentVersion(backupRecoveryKey)
|
||||
if (isValid) {
|
||||
session.cryptoService().keysBackupService().saveBackupRecoveryKey(recoveryKey, version.version)
|
||||
session.cryptoService().keysBackupService().saveBackupRecoveryKey(backupRecoveryKey, version.version)
|
||||
}
|
||||
session.cryptoService().keysBackupService().trustKeysBackupVersion(version, true)
|
||||
} catch (failure: Throwable) {
|
||||
|
@ -502,6 +504,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override fun transactionUpdated(tx: VerificationTransaction) = withState { state ->
|
||||
Timber.v("transactionUpdated: $tx")
|
||||
handleTransactionUpdate(state, tx)
|
||||
}
|
||||
|
||||
|
@ -510,7 +513,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) = withState { state ->
|
||||
|
||||
Timber.v("VerificationRequestUpdated: $pr")
|
||||
if (state.selfVerificationMode && state.pendingRequest.invoke() == null && state.transactionId == null) {
|
||||
// is this an incoming with that user
|
||||
if (pr.isIncoming && pr.otherUserId == state.otherUserMxItem?.id) {
|
||||
|
|
Loading…
Reference in a new issue