Fix issue with key importation

This commit is contained in:
Benoit Marty 2019-06-14 15:42:57 +02:00
parent 659ba34fb3
commit 191d80e5f5
6 changed files with 49 additions and 32 deletions

View File

@ -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<MegolmSessionData>

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<List<MegolmSessionData>>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java))
.fromJson(roomKeys)
importedSessions = list as List<MegolmSessionData>

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)

View File

@ -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)


View File

@ -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<EmojiRepresentation> {
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)),

View File

@ -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

View File

@ -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,

View File

@ -2702,6 +2702,8 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
importButton.setOnClickListener(View.OnClickListener {
val password = passPhraseEditText.text.toString()

displayLoadingView()

KeysImporter(mSession)
.import(requireContext(),
uri,