From 3a8c4c11ce8e9f017f156fb009862f4b41defbd3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Sun, 9 Oct 2022 15:09:56 +0100 Subject: [PATCH] adding dedicated error for missing room keys cipher --- .../app/dapk/st/settings/SettingsScreen.kt | 1 + .../dapk/st/matrix/crypto/CryptoService.kt | 1 + .../matrix/crypto/internal/RoomKeyImporter.kt | 24 ++++++++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt index 570c632..fba9c23 100644 --- a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt +++ b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt @@ -156,6 +156,7 @@ internal fun SettingsScreen(viewModel: SettingsViewModel, onSignOut: () -> Unit, ImportResult.Error.Type.UnexpectedDecryptionOutput -> "Unable to decrypt file, double check your passphrase" is ImportResult.Error.Type.Unknown -> "${type.cause::class.java.simpleName}: ${type.cause.message}" ImportResult.Error.Type.UnableToOpenFile -> "Unable to open file" + ImportResult.Error.Type.InvalidFile -> "Unable to process file" } Text(text = "Import failed\n$message", textAlign = TextAlign.Center) diff --git a/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/CryptoService.kt b/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/CryptoService.kt index ba5936b..d4ac8d8 100644 --- a/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/CryptoService.kt +++ b/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/CryptoService.kt @@ -184,6 +184,7 @@ sealed interface ImportResult { object NoKeysFound : Type object UnexpectedDecryptionOutput : Type object UnableToOpenFile : Type + object InvalidFile : Type } } diff --git a/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/internal/RoomKeyImporter.kt b/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/internal/RoomKeyImporter.kt index 24311a9..7adcc3c 100644 --- a/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/internal/RoomKeyImporter.kt +++ b/matrix/services/crypto/src/main/kotlin/app/dapk/st/matrix/crypto/internal/RoomKeyImporter.kt @@ -86,21 +86,27 @@ class RoomKeyImporter( val line = it.joinToString(separator = "").replace("\n", "") val toByteArray = base64.decode(line) if (index == 0) { - decryptCipher.initialize(toByteArray, password) - toByteArray - .copyOfRange(37, toByteArray.size) - .decrypt(decryptCipher) - .also { - if (!it.startsWith("[{")) { - throw ImportException(ImportResult.Error.Type.UnexpectedDecryptionOutput) - } + toByteArray.ensureHasCipherPayloadOrThrow() + val initializer = toByteArray.copyOfRange(0, 37) + decryptCipher.initialize(initializer, password) + val content = toByteArray.copyOfRange(37, toByteArray.size) + content.decrypt(decryptCipher).also { + if (!it.startsWith("[{")) { + throw ImportException(ImportResult.Error.Type.UnexpectedDecryptionOutput) } + } } else { toByteArray.decrypt(decryptCipher) } } } + private fun ByteArray.ensureHasCipherPayloadOrThrow() { + if (this.size < 37) { + throw ImportException(ImportResult.Error.Type.InvalidFile) + } + } + private fun Cipher.initialize(payload: ByteArray, passphrase: String) { val salt = payload.copyOfRange(1, 1 + 16) val iv = payload.copyOfRange(17, 17 + 16) @@ -176,6 +182,7 @@ private class JsonAccumulator { jsonSegment = withLatest null } + else -> { val string = withLatest.substring(objectRange) importJson.decodeFromString(ElementMegolmExportObject.serializer(), string).also { @@ -200,6 +207,7 @@ private class JsonAccumulator { } opens++ } + c == '}' -> { opens-- if (opens == 0) {