KeysBackup: Avoid using `!!`, should fix #2262

This commit is contained in:
Benoit Marty 2020-10-30 17:10:59 +01:00 committed by Benoit Marty
parent 0bcf42dbb8
commit fca0aa2cc4
3 changed files with 84 additions and 87 deletions

View File

@ -21,6 +21,7 @@ Improvements 🙌:
Bugfix 🐛: Bugfix 🐛:
- Messages encrypted with no way to decrypt after SDK update from 0.18 to 1.0.0 (#2252) - Messages encrypted with no way to decrypt after SDK update from 0.18 to 1.0.0 (#2252)
- Search Result | scroll jumps after pagination (#2238) - Search Result | scroll jumps after pagination (#2238)
- KeysBackup: Avoid using `!!` (#2262)
Translations 🗣: Translations 🗣:
- -

View File

@ -257,14 +257,14 @@ class KeysBackupTest : InstrumentedTest {
// - Check encryptGroupSession() returns stg // - Check encryptGroupSession() returns stg
val keyBackupData = keysBackup.encryptGroupSession(session) val keyBackupData = keysBackup.encryptGroupSession(session)
assertNotNull(keyBackupData) assertNotNull(keyBackupData)
assertNotNull(keyBackupData.sessionData) assertNotNull(keyBackupData!!.sessionData)
// - Check pkDecryptionFromRecoveryKey() is able to create a OlmPkDecryption // - Check pkDecryptionFromRecoveryKey() is able to create a OlmPkDecryption
val decryption = keysBackup.pkDecryptionFromRecoveryKey(keyBackupCreationInfo.recoveryKey) val decryption = keysBackup.pkDecryptionFromRecoveryKey(keyBackupCreationInfo.recoveryKey)
assertNotNull(decryption) assertNotNull(decryption)
// - Check decryptKeyBackupData() returns stg // - Check decryptKeyBackupData() returns stg
val sessionData = keysBackup val sessionData = keysBackup
.decryptKeyBackupData(keyBackupData, .decryptKeyBackupData(keyBackupData!!,
session.olmInboundGroupSession!!.sessionIdentifier(), session.olmInboundGroupSession!!.sessionIdentifier(),
cryptoTestData.roomId, cryptoTestData.roomId,
decryption!!) decryption!!)

View File

@ -1212,22 +1212,19 @@ internal class DefaultKeysBackupService @Inject constructor(
// Gather data to send to the homeserver // Gather data to send to the homeserver
// roomId -> sessionId -> MXKeyBackupData // roomId -> sessionId -> MXKeyBackupData
val keysBackupData = KeysBackupData( val keysBackupData = KeysBackupData()
roomIdToRoomKeysBackupData = HashMap()
)
for (olmInboundGroupSessionWrapper in olmInboundGroupSessionWrappers) { olmInboundGroupSessionWrappers.forEach { olmInboundGroupSessionWrapper ->
val keyBackupData = encryptGroupSession(olmInboundGroupSessionWrapper) val roomId = olmInboundGroupSessionWrapper.roomId ?: return@forEach
if (keysBackupData.roomIdToRoomKeysBackupData[olmInboundGroupSessionWrapper.roomId] == null) { val olmInboundGroupSession = olmInboundGroupSessionWrapper.olmInboundGroupSession ?: return@forEach
val roomKeysBackupData = RoomKeysBackupData(
sessionIdToKeyBackupData = HashMap()
)
keysBackupData.roomIdToRoomKeysBackupData[olmInboundGroupSessionWrapper.roomId!!] = roomKeysBackupData
}
try { try {
keysBackupData.roomIdToRoomKeysBackupData[olmInboundGroupSessionWrapper.roomId]!! encryptGroupSession(olmInboundGroupSessionWrapper)
.sessionIdToKeyBackupData[olmInboundGroupSessionWrapper.olmInboundGroupSession!!.sessionIdentifier()] = keyBackupData ?.let {
keysBackupData.roomIdToRoomKeysBackupData
.getOrPut(roomId) { RoomKeysBackupData() }
.sessionIdToKeyBackupData[olmInboundGroupSession.sessionIdentifier()] = it
}
} catch (e: OlmException) { } catch (e: OlmException) {
Timber.e(e, "OlmException") Timber.e(e, "OlmException")
} }
@ -1235,71 +1232,71 @@ internal class DefaultKeysBackupService @Inject constructor(
Timber.v("backupKeys: 4 - Sending request") Timber.v("backupKeys: 4 - Sending request")
val sendingRequestCallback = object : MatrixCallback<BackupKeysResult> { // Make the request
override fun onSuccess(data: BackupKeysResult) { val version = keysBackupVersion?.version ?: return@withContext
uiHandler.post {
Timber.v("backupKeys: 5a - Request complete")
// Mark keys as backed up storeSessionDataTask
cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers) .configureWith(StoreSessionsDataTask.Params(version, keysBackupData)) {
this.callback = object : MatrixCallback<BackupKeysResult> {
override fun onSuccess(data: BackupKeysResult) {
uiHandler.post {
Timber.v("backupKeys: 5a - Request complete")
if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) { // Mark keys as backed up
Timber.v("backupKeys: All keys have been backed up") cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers)
onServerDataRetrieved(data.count, data.hash)
// Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess() if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) {
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp Timber.v("backupKeys: All keys have been backed up")
} else { onServerDataRetrieved(data.count, data.hash)
Timber.v("backupKeys: Continue to back up keys")
keysBackupStateManager.state = KeysBackupState.WillBackUp
backupKeys() // Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess()
} keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
} } else {
} Timber.v("backupKeys: Continue to back up keys")
keysBackupStateManager.state = KeysBackupState.WillBackUp
override fun onFailure(failure: Throwable) { backupKeys()
if (failure is Failure.ServerError) { }
uiHandler.post { }
Timber.e(failure, "backupKeys: backupKeys failed.") }
when (failure.error.code) { override fun onFailure(failure: Throwable) {
MatrixError.M_NOT_FOUND, if (failure is Failure.ServerError) {
MatrixError.M_WRONG_ROOM_KEYS_VERSION -> { uiHandler.post {
// Backup has been deleted on the server, or we are not using the last backup version Timber.e(failure, "backupKeys: backupKeys failed.")
keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion
backupAllGroupSessionsCallback?.onFailure(failure) when (failure.error.code) {
resetBackupAllGroupSessionsListeners() MatrixError.M_NOT_FOUND,
resetKeysBackupData() MatrixError.M_WRONG_ROOM_KEYS_VERSION -> {
keysBackupVersion = null // Backup has been deleted on the server, or we are not using the last backup version
keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion
// Do not stay in KeysBackupState.WrongBackUpVersion but check what is available on the homeserver backupAllGroupSessionsCallback?.onFailure(failure)
checkAndStartKeysBackup() resetBackupAllGroupSessionsListeners()
resetKeysBackupData()
keysBackupVersion = null
// Do not stay in KeysBackupState.WrongBackUpVersion but check what is available on the homeserver
checkAndStartKeysBackup()
}
else ->
// Come back to the ready state so that we will retry on the next received key
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
}
}
} else {
uiHandler.post {
backupAllGroupSessionsCallback?.onFailure(failure)
resetBackupAllGroupSessionsListeners()
Timber.e("backupKeys: backupKeys failed.")
// Retry a bit later
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
maybeBackupKeys()
}
} }
else ->
// Come back to the ready state so that we will retry on the next received key
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
} }
} }
} else {
uiHandler.post {
backupAllGroupSessionsCallback?.onFailure(failure)
resetBackupAllGroupSessionsListeners()
Timber.e("backupKeys: backupKeys failed.")
// Retry a bit later
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
maybeBackupKeys()
}
}
}
}
// Make the request
storeSessionDataTask
.configureWith(StoreSessionsDataTask.Params(keysBackupVersion!!.version, keysBackupData)) {
this.callback = sendingRequestCallback
} }
.executeBy(taskExecutor) .executeBy(taskExecutor)
} }
@ -1308,46 +1305,45 @@ internal class DefaultKeysBackupService @Inject constructor(
@VisibleForTesting @VisibleForTesting
@WorkerThread @WorkerThread
fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2): KeyBackupData { fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2): KeyBackupData? {
// Gather information for each key // Gather information for each key
val device = cryptoStore.deviceWithIdentityKey(olmInboundGroupSessionWrapper.senderKey!!) val device = olmInboundGroupSessionWrapper.senderKey?.let { cryptoStore.deviceWithIdentityKey(it) }
// Build the m.megolm_backup.v1.curve25519-aes-sha2 data as defined at // Build the m.megolm_backup.v1.curve25519-aes-sha2 data as defined at
// https://github.com/uhoreg/matrix-doc/blob/e2e_backup/proposals/1219-storing-megolm-keys-serverside.md#mmegolm_backupv1curve25519-aes-sha2-key-format // https://github.com/uhoreg/matrix-doc/blob/e2e_backup/proposals/1219-storing-megolm-keys-serverside.md#mmegolm_backupv1curve25519-aes-sha2-key-format
val sessionData = olmInboundGroupSessionWrapper.exportKeys() val sessionData = olmInboundGroupSessionWrapper.exportKeys() ?: return null
val sessionBackupData = mapOf( val sessionBackupData = mapOf(
"algorithm" to sessionData!!.algorithm, "algorithm" to sessionData.algorithm,
"sender_key" to sessionData.senderKey, "sender_key" to sessionData.senderKey,
"sender_claimed_keys" to sessionData.senderClaimedKeys, "sender_claimed_keys" to sessionData.senderClaimedKeys,
"forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()), "forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()),
"session_key" to sessionData.sessionKey) "session_key" to sessionData.sessionKey)
var encryptedSessionBackupData: OlmPkMessage? = null val json = MoshiProvider.providesMoshi()
.adapter(Map::class.java)
.toJson(sessionBackupData)
val moshi = MoshiProvider.providesMoshi() val encryptedSessionBackupData = try {
val adapter = moshi.adapter(Map::class.java) backupOlmPkEncryption?.encrypt(json)
try {
val json = adapter.toJson(sessionBackupData)
encryptedSessionBackupData = backupOlmPkEncryption?.encrypt(json)
} catch (e: OlmException) { } catch (e: OlmException) {
Timber.e(e, "OlmException") Timber.e(e, "OlmException")
null
} }
?: return null
// Build backup data for that key // Build backup data for that key
return KeyBackupData( return KeyBackupData(
firstMessageIndex = try { firstMessageIndex = try {
olmInboundGroupSessionWrapper.olmInboundGroupSession!!.firstKnownIndex olmInboundGroupSessionWrapper.olmInboundGroupSession?.firstKnownIndex ?: 0
} catch (e: OlmException) { } catch (e: OlmException) {
Timber.e(e, "OlmException") Timber.e(e, "OlmException")
0L 0L
}, },
forwardedCount = olmInboundGroupSessionWrapper.forwardingCurve25519KeyChain!!.size, forwardedCount = olmInboundGroupSessionWrapper.forwardingCurve25519KeyChain.orEmpty().size,
isVerified = device?.isVerified == true, isVerified = device?.isVerified == true,
sessionData = mapOf( sessionData = mapOf(
"ciphertext" to encryptedSessionBackupData!!.mCipherText, "ciphertext" to encryptedSessionBackupData.mCipherText,
"mac" to encryptedSessionBackupData.mMac, "mac" to encryptedSessionBackupData.mMac,
"ephemeral" to encryptedSessionBackupData.mEphemeralKey) "ephemeral" to encryptedSessionBackupData.mEphemeralKey)
) )