Merge pull request #3724 from vector-im/feature/bma/ensureOTK

Ensure OTKs are uploaded when the session is created
This commit is contained in:
Benoit Marty 2021-07-23 11:21:07 +02:00 committed by GitHub
commit b764746323
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 7 deletions

1
changelog.d/3724.bugfix Normal file
View File

@ -0,0 +1 @@
Ensure OTKs are uploaded when the session is created

View File

@ -314,6 +314,12 @@ internal class DefaultCryptoService @Inject constructor(
cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) { cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) {
// Open the store // Open the store
cryptoStore.open() cryptoStore.open()
if (!cryptoStore.areDeviceKeysUploaded()) {
// Schedule upload of OTK
oneTimeKeysUploader.updateOneTimeKeyCount(0)
}
// this can throw if no network // this can throw if no network
tryOrNull { tryOrNull {
uploadDeviceKeys() uploadDeviceKeys()
@ -905,7 +911,7 @@ internal class DefaultCryptoService @Inject constructor(
* Upload my user's device keys. * Upload my user's device keys.
*/ */
private suspend fun uploadDeviceKeys() { private suspend fun uploadDeviceKeys() {
if (cryptoStore.getDeviceKeysUploaded()) { if (cryptoStore.areDeviceKeysUploaded()) {
Timber.d("Keys already uploaded, nothing to do") Timber.d("Keys already uploaded, nothing to do")
return return
} }

View File

@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.crypto package org.matrix.android.sdk.internal.crypto
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.internal.crypto.model.MXKey import org.matrix.android.sdk.internal.crypto.model.MXKey
import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse
import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask
@ -77,6 +78,10 @@ internal class OneTimeKeysUploader @Inject constructor(
// discard the oldest private keys first. This will eventually clean // discard the oldest private keys first. This will eventually clean
// out stale private keys that won't receive a message. // out stale private keys that won't receive a message.
val keyLimit = floor(maxOneTimeKeys / 2.0).toInt() val keyLimit = floor(maxOneTimeKeys / 2.0).toInt()
if (oneTimeKeyCount == null) {
// Ask the server how many otk he has
oneTimeKeyCount = fetchOtkCount()
}
val oneTimeKeyCountFromSync = oneTimeKeyCount val oneTimeKeyCountFromSync = oneTimeKeyCount
if (oneTimeKeyCountFromSync != null) { if (oneTimeKeyCountFromSync != null) {
// We need to keep a pool of one time public keys on the server so that // We need to keep a pool of one time public keys on the server so that
@ -90,17 +95,22 @@ internal class OneTimeKeysUploader @Inject constructor(
// private keys clogging up our local storage. // private keys clogging up our local storage.
// So we need some kind of engineering compromise to balance all of // So we need some kind of engineering compromise to balance all of
// these factors. // these factors.
try { tryOrNull("Unable to upload OTK") {
val uploadedKeys = uploadOTK(oneTimeKeyCountFromSync, keyLimit) val uploadedKeys = uploadOTK(oneTimeKeyCountFromSync, keyLimit)
Timber.v("## uploadKeys() : success, $uploadedKeys key(s) sent") Timber.v("## uploadKeys() : success, $uploadedKeys key(s) sent")
} finally {
oneTimeKeyCheckInProgress = false
} }
} else { } else {
Timber.w("maybeUploadOneTimeKeys: waiting to know the number of OTK from the sync") Timber.w("maybeUploadOneTimeKeys: waiting to know the number of OTK from the sync")
oneTimeKeyCheckInProgress = false
lastOneTimeKeyCheck = 0 lastOneTimeKeyCheck = 0
} }
oneTimeKeyCheckInProgress = false
}
private suspend fun fetchOtkCount(): Int? {
return tryOrNull("Unable to get OTK count") {
val result = uploadKeysTask.execute(UploadKeysTask.Params(null, null))
result.oneTimeKeyCountsForAlgorithm(MXKey.KEY_SIGNED_CURVE_25519_TYPE)
}
} }
/** /**

View File

@ -475,7 +475,7 @@ internal interface IMXCryptoStore {
fun getGossipingEvents(): List<Event> fun getGossipingEvents(): List<Event>
fun setDeviceKeysUploaded(uploaded: Boolean) fun setDeviceKeysUploaded(uploaded: Boolean)
fun getDeviceKeysUploaded(): Boolean fun areDeviceKeysUploaded(): Boolean
fun tidyUpDataBase() fun tidyUpDataBase()
fun logDbUsageInfo() fun logDbUsageInfo()
} }

View File

@ -937,7 +937,7 @@ internal class RealmCryptoStore @Inject constructor(
} }
} }
override fun getDeviceKeysUploaded(): Boolean { override fun areDeviceKeysUploaded(): Boolean {
return doWithRealm(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<CryptoMetadataEntity>().findFirst()?.deviceKeysSentToServer it.where<CryptoMetadataEntity>().findFirst()?.deviceKeysSentToServer
} ?: false } ?: false