diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeV2Test.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeV2Test.kt new file mode 100644 index 0000000000..3bcb5c660f --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeV2Test.kt @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2020 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.crypto.verification.qrcode + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import im.vector.matrix.android.InstrumentedTest +import org.amshove.kluent.shouldBeNull +import org.amshove.kluent.shouldEqual +import org.amshove.kluent.shouldEqualTo +import org.amshove.kluent.shouldNotBeNull +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters + +@RunWith(AndroidJUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +class QrCodeV2Test : InstrumentedTest { + + private val qrCode1 = QrCodeDataV2.VerifyingAnotherUser( + transactionId = "MaTransaction", + userMasterCrossSigningPublicKey = "ktEwcUP6su1xh+GuE+CYkQ3H6W/DIl+ybHFdaEOrolU", + otherUserMasterCrossSigningPublicKey = "TXluZKTZLvSRWOTPlOqLq534bA+/K4zLFKSu9cGLQaU", + sharedSecret = "MTIzNDU2Nzg" + ) + + private val value1 = "MATRIX\u0002\u0000\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678" + + private val qrCode2 = QrCodeDataV2.SelfVerifyingMasterKeyTrusted( + transactionId = "MaTransaction", + userMasterCrossSigningPublicKey = "ktEwcUP6su1xh+GuE+CYkQ3H6W/DIl+ybHFdaEOrolU", + otherDeviceKey = "TXluZKTZLvSRWOTPlOqLq534bA+/K4zLFKSu9cGLQaU", + sharedSecret = "MTIzNDU2Nzg" + ) + + private val value2 = "MATRIX\u0002\u0001\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678" + + private val qrCode3 = QrCodeDataV2.SelfVerifyingMasterKeyNotTrusted( + transactionId = "MaTransaction", + deviceKey = "TXluZKTZLvSRWOTPlOqLq534bA+/K4zLFKSu9cGLQaU", + userMasterCrossSigningPublicKey = "ktEwcUP6su1xh+GuE+CYkQ3H6W/DIl+ybHFdaEOrolU", + sharedSecret = "MTIzNDU2Nzg" + ) + + private val value3 = "MATRIX\u0002\u0002\u0000\u000DMaTransactionMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢U12345678" + + private val sharedSecretByteArray = "12345678".toByteArray(Charsets.ISO_8859_1) + + // 4d 79 6e 64 a4 d9 2e f4 91 58 e4 cf 94 ea 8b ab 9d f8 6c 0f bf 2b 8c cb 14 a4 ae f5 c1 8b 41 a5 + private val tlx_byteArray = ByteArray(32) { + when (it) { + 0 -> 0x4D.toByte() + 1 -> 0x79.toByte() + 2 -> 0x6E.toByte() + 3 -> 0x64.toByte() + 4 -> 0xA4.toByte() + 5 -> 0xD9.toByte() + 6 -> 0x2E.toByte() + 7 -> 0xF4.toByte() + 8 -> 0x91.toByte() + 9 -> 0x58.toByte() + 10 -> 0xE4.toByte() + 11 -> 0xCF.toByte() + 12 -> 0x94.toByte() + 13 -> 0xEA.toByte() + 14 -> 0x8B.toByte() + 15 -> 0xAB.toByte() + 16 -> 0x9D.toByte() + 17 -> 0xF8.toByte() + 18 -> 0x6C.toByte() + 19 -> 0x0F.toByte() + 20 -> 0xBF.toByte() + 21 -> 0x2B.toByte() + 22 -> 0x8C.toByte() + 23 -> 0xCB.toByte() + 24 -> 0x14.toByte() + 25 -> 0xA4.toByte() + 26 -> 0xAE.toByte() + 27 -> 0xF5.toByte() + 28 -> 0xC1.toByte() + 29 -> 0x8B.toByte() + 30 -> 0x41.toByte() + else -> 0xA5.toByte() + } + } + + // 92 d1 30 71 43 fa b2 ed 71 87 e1 ae 13 e0 98 91 0d c7 e9 6f c3 22 5f b2 6c 71 5d 68 43 ab a2 55 + private val kte_byteArray = ByteArray(32) { + when (it) { + 0 -> 0x92.toByte() + 1 -> 0xd1.toByte() + 2 -> 0x30.toByte() + 3 -> 0x71.toByte() + 4 -> 0x43.toByte() + 5 -> 0xfa.toByte() + 6 -> 0xb2.toByte() + 7 -> 0xed.toByte() + 8 -> 0x71.toByte() + 9 -> 0x87.toByte() + 10 -> 0xe1.toByte() + 11 -> 0xae.toByte() + 12 -> 0x13.toByte() + 13 -> 0xe0.toByte() + 14 -> 0x98.toByte() + 15 -> 0x91.toByte() + 16 -> 0x0d.toByte() + 17 -> 0xc7.toByte() + 18 -> 0xe9.toByte() + 19 -> 0x6f.toByte() + 20 -> 0xc3.toByte() + 21 -> 0x22.toByte() + 22 -> 0x5f.toByte() + 23 -> 0xb2.toByte() + 24 -> 0x6c.toByte() + 25 -> 0x71.toByte() + 26 -> 0x5d.toByte() + 27 -> 0x68.toByte() + 28 -> 0x43.toByte() + 29 -> 0xab.toByte() + 30 -> 0xa2.toByte() + else -> 0x55.toByte() + } + } + + @Test + fun testEncoding1() { + qrCode1.toEncodedString() shouldEqual value1 + } + + @Test + fun testEncoding2() { + qrCode2.toEncodedString() shouldEqual value2 + } + + @Test + fun testEncoding3() { + qrCode3.toEncodedString() shouldEqual value3 + } + + @Test + fun testSymmetry1() { + qrCode1.toEncodedString().toQrCodeDataV2() shouldEqual qrCode1 + } + + @Test + fun testSymmetry2() { + qrCode2.toEncodedString().toQrCodeDataV2() shouldEqual qrCode2 + } + + @Test + fun testSymmetry3() { + qrCode3.toEncodedString().toQrCodeDataV2() shouldEqual qrCode3 + } + + @Test + fun testCase1() { + val url = qrCode1.toEncodedString() + + val byteArray = url.toByteArray(Charsets.ISO_8859_1) + checkHeader(byteArray) + + // Mode + byteArray[7] shouldEqualTo 0 + + checkSizeAndTransaction(byteArray) + + compareArray(byteArray.copyOfRange(23, 23 + 32), kte_byteArray) + compareArray(byteArray.copyOfRange(23 + 32, 23 + 64), tlx_byteArray) + + compareArray(byteArray.copyOfRange(23 + 64, byteArray.size), sharedSecretByteArray) + } + + @Test + fun testCase2() { + val url = qrCode2.toEncodedString() + + val byteArray = url.toByteArray(Charsets.ISO_8859_1) + checkHeader(byteArray) + + // Mode + byteArray[7] shouldEqualTo 1 + + checkSizeAndTransaction(byteArray) + compareArray(byteArray.copyOfRange(23, 23 + 32), kte_byteArray) + compareArray(byteArray.copyOfRange(23 + 32, 23 + 64), tlx_byteArray) + + compareArray(byteArray.copyOfRange(23 + 64, byteArray.size), sharedSecretByteArray) + } + + @Test + fun testCase3() { + val url = qrCode3.toEncodedString() + + val byteArray = url.toByteArray(Charsets.ISO_8859_1) + checkHeader(byteArray) + + // Mode + byteArray[7] shouldEqualTo 2 + + checkSizeAndTransaction(byteArray) + compareArray(byteArray.copyOfRange(23, 23 + 32), tlx_byteArray) + compareArray(byteArray.copyOfRange(23 + 32, 23 + 64), kte_byteArray) + + compareArray(byteArray.copyOfRange(23 + 64, byteArray.size), sharedSecretByteArray) + } + + // Error cases + @Test + fun testErrorHeader() { + value1.replace("MATRIX", "MOTRIX").toQrCodeDataV2().shouldBeNull() + value1.replace("MATRIX", "MATRI").toQrCodeDataV2().shouldBeNull() + value1.replace("MATRIX", "").toQrCodeDataV2().shouldBeNull() + } + + @Test + fun testErrorVersion() { + value1.replace("MATRIX\u0002", "MATRIX\u0000").toQrCodeDataV2().shouldBeNull() + value1.replace("MATRIX\u0002", "MATRIX\u0001").toQrCodeDataV2().shouldBeNull() + value1.replace("MATRIX\u0002", "MATRIX\u0003").toQrCodeDataV2().shouldBeNull() + value1.replace("MATRIX\u0002", "MATRIX").toQrCodeDataV2().shouldBeNull() + } + + @Test + fun testErrorSecretTooShort() { + value1.replace("12345678", "1234567").toQrCodeDataV2().shouldBeNull() + } + + @Test + fun testErrorNoTransactionNoKeyNoSecret() { + // But keep transaction length + "MATRIX\u0002\u0000\u0000\u000D".toQrCodeDataV2().shouldBeNull() + } + + @Test + fun testErrorNoKeyNoSecret() { + "MATRIX\u0002\u0000\u0000\u000DMaTransaction".toQrCodeDataV2().shouldBeNull() + } + + @Test + fun testErrorTransactionLengthTooShort() { + // In this case, the secret will be longer, so this is not an error, but it will lead to keys mismatch + value1.replace("\u000DMaTransaction", "\u000CMaTransaction").toQrCodeDataV2().shouldNotBeNull() + } + + @Test + fun testErrorTransactionLengthTooBig() { + value1.replace("\u000DMaTransaction", "\u000EMaTransaction").toQrCodeDataV2().shouldBeNull() + } + + private fun compareArray(actual: ByteArray, expected: ByteArray) { + actual.size shouldEqual expected.size + + for (i in actual.indices) { + actual[i] shouldEqualTo expected[i] + } + } + + private fun checkHeader(byteArray: ByteArray) { + // MATRIX + byteArray[0] shouldEqualTo 'M'.toByte() + byteArray[1] shouldEqualTo 'A'.toByte() + byteArray[2] shouldEqualTo 'T'.toByte() + byteArray[3] shouldEqualTo 'R'.toByte() + byteArray[4] shouldEqualTo 'I'.toByte() + byteArray[5] shouldEqualTo 'X'.toByte() + + // Version + byteArray[6] shouldEqualTo 2 + } + + private fun checkSizeAndTransaction(byteArray: ByteArray) { + // Size + byteArray[8] shouldEqualTo 0 + byteArray[9] shouldEqualTo 13 + + // Transaction + byteArray.copyOfRange(10, 10 + "MaTransaction".length).toString(Charsets.ISO_8859_1) shouldEqual "MaTransaction" + } +} diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecretV2Test.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecretV2Test.kt new file mode 100644 index 0000000000..6c46fcd6a9 --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecretV2Test.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 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.crypto.verification.qrcode + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import im.vector.matrix.android.InstrumentedTest +import org.amshove.kluent.shouldBe +import org.amshove.kluent.shouldNotBeEqualTo +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters + +@RunWith(AndroidJUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +class SharedSecretV2Test : InstrumentedTest { + + @Test + fun testSharedSecretLengthCase() { + repeat(100) { + generateSharedSecretV2().length shouldBe 11 + } + } + + @Test + fun testSharedDiffCase() { + val sharedSecret1 = generateSharedSecretV2() + val sharedSecret2 = generateSharedSecretV2() + + sharedSecret1 shouldNotBeEqualTo sharedSecret2 + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/Extensions.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/Extensions.kt index d539152135..a6f2927418 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/Extensions.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/Extensions.kt @@ -45,6 +45,7 @@ private const val ENCODING = "utf-8" * &other_device_key=WqSVLkBREDACTEDBsfszdvsdBEvefqsdcsfBvsfcsFb * */ +// @Deprecated(message = "Use QrCodeDataV2") fun QrCodeData.toUrl(): String { return buildString { append(PermalinkFactory.createPermalink(userId)) @@ -72,6 +73,7 @@ fun QrCodeData.toUrl(): String { } } +// @Deprecated(message = "Use QrCodeDataV2") fun String.toQrCodeData(): QrCodeData? { if (!startsWith(PermalinkFactory.MATRIX_TO_URL_BASE)) { return null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/ExtensionsV2.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/ExtensionsV2.kt new file mode 100644 index 0000000000..5e6c984990 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/ExtensionsV2.kt @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020 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.crypto.verification.qrcode + +import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64NoPadding +import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding + +// MATRIX +private val prefix = "MATRIX".toByteArray(Charsets.ISO_8859_1) + +fun QrCodeDataV2.toEncodedString(): String { + var result = ByteArray(0) + + // MATRIX + for (i in prefix.indices) { + result += prefix[i] + } + + // Version + result += 2 + + // Mode + result += when (this) { + is QrCodeDataV2.VerifyingAnotherUser -> 0 + is QrCodeDataV2.SelfVerifyingMasterKeyTrusted -> 1 + is QrCodeDataV2.SelfVerifyingMasterKeyNotTrusted -> 2 + }.toByte() + + // TransactionId length + val length = transactionId.length + result += ((length and 0xFF00) shr 8).toByte() + result += length.toByte() + + // TransactionId + transactionId.forEach { + result += it.toByte() + } + + // Keys + firstKey.fromBase64NoPadding().forEach { + result += it + } + secondKey.fromBase64NoPadding().forEach { + result += it + } + + // Secret + sharedSecret.fromBase64NoPadding().forEach { + result += it + } + + return result.toString(Charsets.ISO_8859_1) +} + +fun String.toQrCodeDataV2(): QrCodeDataV2? { + val byteArray = toByteArray(Charsets.ISO_8859_1) + + // Size should be min 6 + 1 + 1 + 2 + ? + 32 + 32 + ? = 74 + transactionLength + secretLength + + // Check header + // MATRIX + if (byteArray.size < 10) return null + + for (i in prefix.indices) { + if (byteArray[i] != prefix[i]) { + return null + } + } + + var cursor = prefix.size // 6 + + // Version + if (byteArray[cursor] != 2.toByte()) { + return null + } + cursor++ + + // Get mode + val mode = byteArray[cursor].toInt() + cursor++ + + // Get transaction length + val transactionLength = (byteArray[cursor].toInt() shr 8) + byteArray[cursor + 1].toInt() + + cursor++ + cursor++ + + val secretLength = byteArray.size - 74 - transactionLength + + // ensure the secret length is 8 bytes min + if (secretLength < 8) { + return null + } + + val transactionId = byteArray.copyOfRange(cursor, cursor + transactionLength).toString(Charsets.ISO_8859_1) + cursor += transactionLength + val key1 = byteArray.copyOfRange(cursor, cursor + 32).toBase64NoPadding() + cursor += 32 + val key2 = byteArray.copyOfRange(cursor, cursor + 32).toBase64NoPadding() + cursor += 32 + val secret = byteArray.copyOfRange(cursor, byteArray.size).toBase64NoPadding() + + return when (mode) { + 0 -> QrCodeDataV2.VerifyingAnotherUser(transactionId, key1, key2, secret) + 1 -> QrCodeDataV2.SelfVerifyingMasterKeyTrusted(transactionId, key1, key2, secret) + 2 -> QrCodeDataV2.SelfVerifyingMasterKeyNotTrusted(transactionId, key1, key2, secret) + else -> null + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeData.kt index 0f9a31ab32..07a11699ba 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeData.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeData.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.crypto.verification.qrcode /** * Ref: https://github.com/uhoreg/matrix-doc/blob/qr_key_verification/proposals/1543-qr_code_key_verification.md#qr-code-format */ +//@Deprecated(message = "Use QrCodeDataV2") data class QrCodeData( val userId: String, // Request Id. Can be an arbitrary value. In DM, it will be the event ID of the associated verification request event. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeDataV2.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeDataV2.kt new file mode 100644 index 0000000000..d3b23b30de --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeDataV2.kt @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020 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.crypto.verification.qrcode + +/** + * Ref: https://github.com/uhoreg/matrix-doc/blob/qr_key_verification/proposals/1543-qr_code_key_verification.md#qr-code-format + */ +sealed class QrCodeDataV2( + /** + * the event ID or transaction_id of the associated verification + */ + open val transactionId: String, + /** + * First key (32 bytes, in base64 no padding) + */ + val firstKey: String, + /** + * Second key (32 bytes, in base64 no padding) + */ + val secondKey: String, + /** + * a random shared secret (in base64 no padding) + */ + open val sharedSecret: String +) { + /** + * verifying another user with cross-signing + * QR code verification mode: 0x00 + */ + data class VerifyingAnotherUser( + override val transactionId: String, + /** + * the user's own master cross-signing public key + */ + val userMasterCrossSigningPublicKey: String, + /** + * what the device thinks the other user's master cross-signing key is + */ + val otherUserMasterCrossSigningPublicKey: String, + override val sharedSecret: String + ) : QrCodeDataV2( + transactionId, + userMasterCrossSigningPublicKey, + otherUserMasterCrossSigningPublicKey, + sharedSecret) + + /** + * self-verifying in which the current device does trust the master key + * QR code verification mode: 0x01 + */ + data class SelfVerifyingMasterKeyTrusted( + override val transactionId: String, + /** + * the user's own master cross-signing public key + */ + val userMasterCrossSigningPublicKey: String, + /** + * what the device thinks the other device's device key is + */ + val otherDeviceKey: String, + override val sharedSecret: String + ) : QrCodeDataV2( + transactionId, + userMasterCrossSigningPublicKey, + otherDeviceKey, + sharedSecret) + + /** + * self-verifying in which the current device does not yet trust the master key + * QR code verification mode: 0x02 + */ + data class SelfVerifyingMasterKeyNotTrusted( + override val transactionId: String, + /** + * the current device's device key + */ + val deviceKey: String, + /** + * what the device thinks the user's master cross-signing key is + */ + val userMasterCrossSigningPublicKey: String, + override val sharedSecret: String + ) : QrCodeDataV2( + transactionId, + deviceKey, + userMasterCrossSigningPublicKey, + sharedSecret) +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecret.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecret.kt index d319ebd88c..b34ff85346 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecret.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecret.kt @@ -27,3 +27,12 @@ fun generateSharedSecret(): String { secureRandom.nextBytes(secretBytes) return secretBytes.toBase64NoPadding() } + +fun generateSharedSecretV2(): String { + val secureRandom = SecureRandom() + + // 8 bytes long + val secretBytes = ByteArray(8) + secureRandom.nextBytes(secretBytes) + return secretBytes.toBase64NoPadding() +}