Create fromBase64Safe() to parse data received from external source

This commit is contained in:
Benoit Marty 2020-02-27 19:17:14 +01:00
parent 0a9008a73d
commit b1b8513da4
6 changed files with 25 additions and 3 deletions

View File

@ -16,6 +16,7 @@
package im.vector.matrix.android.internal.crypto.crosssigning
import org.amshove.kluent.shouldBeNull
import org.amshove.kluent.shouldBeTrue
import org.junit.Test
@ -29,4 +30,9 @@ class ExtensionsKtTest {
// With padding
"NMJyumnhMic".fromBase64().contentEquals("NMJyumnhMic=".fromBase64()).shouldBeTrue()
}
@Test
fun testBadBase64() {
"===".fromBase64Safe().shouldBeNull()
}
}

View File

@ -28,5 +28,7 @@ sealed class SharedSecretStorageError(message: String?) : Throwable(message) {
object BadKeyFormat : SharedSecretStorageError("Bad Key Format")
object ParsingError : SharedSecretStorageError("parsing Error")
object BadMac : SharedSecretStorageError("Bad mac")
object BadCipherText : SharedSecretStorageError("Bad cipher text")
data class OtherError(val reason: Throwable) : SharedSecretStorageError(reason.localizedMessage)
}

View File

@ -19,6 +19,7 @@ import android.util.Base64
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.util.JsonCanonicalizer
import timber.log.Timber
fun CryptoDeviceInfo.canonicalSignable(): String {
return JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableJSONDictionary())
@ -35,3 +36,15 @@ fun ByteArray.toBase64NoPadding(): String {
fun String.fromBase64(): ByteArray {
return Base64.decode(this, Base64.DEFAULT)
}
/**
* Decode the base 64. Return null in case of bad format. Should be used when parsing received data from external source
*/
fun String.fromBase64Safe(): ByteArray? {
return try {
Base64.decode(this, Base64.DEFAULT)
} catch (throwable: Throwable) {
Timber.e(throwable, "Unable to decode base64 string")
null
}
}

View File

@ -297,7 +297,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
val iv = cipherContent.initializationVector?.fromBase64() ?: ByteArray(16)
val cipherRawBytes = cipherContent.ciphertext!!.fromBase64()
val cipherRawBytes = cipherContent.ciphertext?.fromBase64() ?: throw SharedSecretStorageError.BadCipherText
val cipher = Cipher.getInstance("AES/CTR/NoPadding")

View File

@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64
import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64Safe
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.verification.DefaultVerificationTransaction
import im.vector.matrix.android.internal.crypto.verification.VerificationInfo
@ -200,7 +201,7 @@ internal class DefaultQrCodeVerificationTransaction(
return
}
if ((startReq.sharedSecret?.fromBase64()?.contentEquals(qrCodeData.sharedSecret.fromBase64()) == true)) {
if (startReq.sharedSecret?.fromBase64Safe()?.contentEquals(qrCodeData.sharedSecret.fromBase64()) == true) {
// Ok, we can trust the other user
// We can only trust the master key in this case
// But first, ask the user for a confirmation

View File

@ -98,7 +98,7 @@ fun String.toQrCodeData(): QrCodeData? {
val msb = byteArray[cursor].toUnsignedInt()
val lsb = byteArray[cursor + 1].toUnsignedInt()
val transactionLength = msb.shl(8) + lsb
val transactionLength = msb.shl(8) + lsb
cursor++
cursor++