From 191d80e5f54a60534c9be516746db7e3fbaef3e1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 14 Jun 2019 15:42:57 +0200 Subject: [PATCH] Fix issue with key importation --- .../android/internal/crypto/CryptoManager.kt | 18 +++++++-------- .../crypto/MXMegolmExportEncryption.kt | 14 +++-------- .../SASVerificationTransaction.kt | 23 ++++++++++--------- .../android/internal/extensions/Primitives.kt | 22 ++++++++++++++++++ .../features/crypto/keys/KeysImporter.kt | 2 +- .../VectorSettingsPreferencesFragment.kt | 2 ++ 6 files changed, 49 insertions(+), 32 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/extensions/Primitives.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt index b65cfe573e..cb5ed9688f 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt @@ -23,6 +23,7 @@ import android.os.Handler import android.os.Looper import android.text.TextUtils import arrow.core.Try +import com.squareup.moshi.Types import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.data.Credentials @@ -810,8 +811,7 @@ internal class CryptoManager( val adapter = MoshiProvider.providesMoshi() .adapter(List::class.java) - MXMegolmExportEncryption - .encryptMegolmKeyFile(adapter.toJson(exportedSessions), password, iterationCount) + MXMegolmExportEncryption.encryptMegolmKeyFile(adapter.toJson(exportedSessions), password, iterationCount) } }.foldToCallback(callback) } @@ -835,23 +835,23 @@ internal class CryptoManager( Timber.v("## importRoomKeys starts") val t0 = System.currentTimeMillis() - val roomKeys: String = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password) - - val importedSessions: List - + val roomKeys = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password) val t1 = System.currentTimeMillis() Timber.v("## importRoomKeys : decryptMegolmKeyFile done in " + (t1 - t0) + " ms") - val list = MoshiProvider.providesMoshi() - .adapter(List::class.java) + val importedSessions = MoshiProvider.providesMoshi() + .adapter>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java)) .fromJson(roomKeys) - importedSessions = list as List val t2 = System.currentTimeMillis() Timber.v("## importRoomKeys : JSON parsing " + (t2 - t1) + " ms") + if (importedSessions == null) { + throw Exception("Error") + } + megolmSessionDataImporter.handle(importedSessions, true, uiHandler, progressListener) } }.foldToCallback(callback) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXMegolmExportEncryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXMegolmExportEncryption.kt index 6a99101897..82b2c95d89 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXMegolmExportEncryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXMegolmExportEncryption.kt @@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.crypto import android.text.TextUtils import android.util.Base64 +import im.vector.matrix.android.internal.extensions.toUnsignedInt import timber.log.Timber import java.io.ByteArrayOutputStream import java.nio.charset.Charset @@ -43,16 +44,6 @@ object MXMegolmExportEncryption { // default iteration count to export the e2e keys const val DEFAULT_ITERATION_COUNT = 500000 - /** - * Convert a signed byte to a int value - * - * @param bVal the byte value to convert - * @return the matched int value - */ - private fun byteToInt(bVal: Byte): Int { - return (bVal and 0xFF.toByte()).toInt() - } - /** * Extract the AES key from the deriveKeys result. * @@ -108,7 +99,8 @@ object MXMegolmExportEncryption { val salt = Arrays.copyOfRange(body, 1, 1 + 16) val iv = Arrays.copyOfRange(body, 17, 17 + 16) - val iterations = byteToInt(body[33]) shl 24 or (byteToInt(body[34]) shl 16) or (byteToInt(body[35]) shl 8) or byteToInt(body[36]) + val iterations = + (body[33].toUnsignedInt() shl 24) or (body[34].toUnsignedInt() shl 16) or (body[35].toUnsignedInt() shl 8) or body[36].toUnsignedInt() val ciphertext = Arrays.copyOfRange(body, 37, 37 + ciphertextLength) val hmac = Arrays.copyOfRange(body, body.size - 32, body.size) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SASVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SASVerificationTransaction.kt index 1f6d759b56..5390c5ed3c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SASVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SASVerificationTransaction.kt @@ -30,6 +30,7 @@ import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap import im.vector.matrix.android.internal.crypto.model.rest.* import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask +import im.vector.matrix.android.internal.extensions.toUnsignedInt import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith import org.matrix.olm.OlmSAS @@ -354,11 +355,11 @@ internal abstract class SASVerificationTransaction( * or with the three numbers on separate lines. */ fun getDecimalCodeRepresentation(byteArray: ByteArray): String { - val b0 = byteArray[0].toInt().and(0xff) //need unsigned byte - val b1 = byteArray[1].toInt().and(0xff) //need unsigned byte - val b2 = byteArray[2].toInt().and(0xff) //need unsigned byte - val b3 = byteArray[3].toInt().and(0xff) //need unsigned byte - val b4 = byteArray[4].toInt().and(0xff) //need unsigned byte + val b0 = byteArray[0].toUnsignedInt() //need unsigned byte + val b1 = byteArray[1].toUnsignedInt() //need unsigned byte + val b2 = byteArray[2].toUnsignedInt() //need unsigned byte + val b3 = byteArray[3].toUnsignedInt() //need unsigned byte + val b4 = byteArray[4].toUnsignedInt() //need unsigned byte //(B0 << 5 | B1 >> 3) + 1000 val first = (b0.shl(5) or b1.shr(3)) + 1000 //((B1 & 0x7) << 10 | B2 << 2 | B3 >> 6) + 1000 @@ -379,12 +380,12 @@ internal abstract class SASVerificationTransaction( * to that number 7 emoji are selected from a list of 64 emoji (see Appendix A) */ fun getEmojiCodeRepresentation(byteArray: ByteArray): List { - val b0 = byteArray[0].toInt().and(0xff) - val b1 = byteArray[1].toInt().and(0xff) - val b2 = byteArray[2].toInt().and(0xff) - val b3 = byteArray[3].toInt().and(0xff) - val b4 = byteArray[4].toInt().and(0xff) - val b5 = byteArray[5].toInt().and(0xff) + val b0 = byteArray[0].toUnsignedInt() + val b1 = byteArray[1].toUnsignedInt() + val b2 = byteArray[2].toUnsignedInt() + val b3 = byteArray[3].toUnsignedInt() + val b4 = byteArray[4].toUnsignedInt() + val b5 = byteArray[5].toUnsignedInt() return listOf( getEmojiForCode((b0 and 0xFC).shr(2)), getEmojiForCode((b0 and 0x3).shl(4) or (b1 and 0xF0).shr(4)), diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/extensions/Primitives.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/extensions/Primitives.kt new file mode 100644 index 0000000000..0a0ca1a1bd --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/extensions/Primitives.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.extensions + +/** + * Convert a signed byte to a int value + */ +fun Byte.toUnsignedInt() = toInt() and 0xff diff --git a/vector/src/main/java/im/vector/riotredesign/features/crypto/keys/KeysImporter.kt b/vector/src/main/java/im/vector/riotredesign/features/crypto/keys/KeysImporter.kt index f783962d21..e4ed46f6a4 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/crypto/keys/KeysImporter.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/crypto/keys/KeysImporter.kt @@ -33,7 +33,7 @@ import timber.log.Timber class KeysImporter(private val session: Session) { /** - * Export keys and return the file path with the callback + * Import keys from provided Uri */ fun import(context: Context, uri: Uri, diff --git a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt index 472b168060..3fad652a2a 100755 --- a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsPreferencesFragment.kt @@ -2702,6 +2702,8 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref importButton.setOnClickListener(View.OnClickListener { val password = passPhraseEditText.text.toString() + displayLoadingView() + KeysImporter(mSession) .import(requireContext(), uri,