diff --git a/vector/src/main/java/im/vector/riotredesign/core/utils/SecretStoringUtils.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt similarity index 99% rename from vector/src/main/java/im/vector/riotredesign/core/utils/SecretStoringUtils.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt index 1cbb28aeab..6dc0d789cc 100644 --- a/vector/src/main/java/im/vector/riotredesign/core/utils/SecretStoringUtils.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt @@ -5,7 +5,7 @@ * 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 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.riotredesign.core.utils +package im.vector.matrix.android.api.util import android.content.Context import android.os.Build diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt index 472d653dee..2459c3546a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt @@ -23,8 +23,8 @@ import dagger.Provides import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.internal.auth.db.AuthRealmModule import im.vector.matrix.android.internal.auth.db.RealmSessionParamsStore +import im.vector.matrix.android.internal.database.configureEncryption import im.vector.matrix.android.internal.di.AuthDatabase -import im.vector.matrix.android.internal.di.MatrixScope import io.realm.RealmConfiguration import java.io.File @@ -42,6 +42,7 @@ internal abstract class AuthModule { old.renameTo(File(context.filesDir, "matrix-sdk-auth.realm")) } return RealmConfiguration.Builder() + .configureEncryption("matrix-sdk-auth", context) .name("matrix-sdk-auth.realm") .modules(AuthRealmModule()) .deleteRealmIfMigrationNeeded() @@ -50,7 +51,6 @@ internal abstract class AuthModule { } - @Binds abstract fun bindSessionParamsStore(sessionParamsStore: RealmSessionParamsStore): SessionParamsStore diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt index 89baf1c6b1..32a5b3d271 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt @@ -29,12 +29,13 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStore import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreMigration import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreModule -import im.vector.matrix.android.internal.crypto.store.db.hash import im.vector.matrix.android.internal.crypto.tasks.* +import im.vector.matrix.android.internal.database.configureEncryption import im.vector.matrix.android.internal.di.CryptoDatabase import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.cache.ClearCacheTask import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask +import im.vector.matrix.android.internal.util.md5 import io.realm.RealmConfiguration import retrofit2.Retrofit import java.io.File @@ -45,14 +46,16 @@ internal abstract class CryptoModule { @Module companion object { - // Realm configuration, named to avoid clash with main cache realm configuration @JvmStatic @Provides @CryptoDatabase @SessionScope fun providesRealmConfiguration(context: Context, credentials: Credentials): RealmConfiguration { + val userIDHash = credentials.userId.md5() + return RealmConfiguration.Builder() - .directory(File(context.filesDir, credentials.userId.hash())) + .directory(File(context.filesDir, userIDHash)) + .configureEncryption("crypto_module_$userIDHash", context) .name("crypto_store.realm") .modules(RealmCryptoStoreModule()) .schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION) @@ -169,6 +172,4 @@ internal abstract class CryptoModule { @Binds abstract fun bindDeleteDeviceWithUserPasswordTask(deleteDeviceWithUserPasswordTask: DefaultDeleteDeviceWithUserPasswordTask): DeleteDeviceWithUserPasswordTask - - } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt index cbf941f1c1..4ba484ae1a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt @@ -25,27 +25,9 @@ import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream -import java.security.MessageDigest import java.util.zip.GZIPInputStream -/** - * Compute a Hash of a String, using md5 algorithm - */ -fun String.hash() = try { - val digest = MessageDigest.getInstance("md5") - digest.update(toByteArray()) - val bytes = digest.digest() - val sb = StringBuilder() - for (i in bytes.indices) { - sb.append(String.format("%02X", bytes[i])) - } - sb.toString().toLowerCase() -} catch (exc: Exception) { - // Should not happen, but just in case - hashCode().toString() -} - /** * Get realm, invoke the action, close realm, and return the result of the action */ diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmKeysUtils.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmKeysUtils.kt new file mode 100644 index 0000000000..ee8ee41821 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmKeysUtils.kt @@ -0,0 +1,106 @@ +/* + * 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.database + +import android.content.Context +import android.util.Base64 +import im.vector.matrix.android.api.util.SecretStoringUtils +import io.realm.RealmConfiguration +import timber.log.Timber +import java.security.SecureRandom + +/** + * On creation a random key is generated, this key is then encrypted using the system KeyStore. + * The encrypted key is stored in shared preferences. + * When the database is opened again, the encrypted key is taken from the shared pref, + * then the Keystore is used to decrypt the key. The decrypted key is passed to the RealConfiguration. + * + * On android >=M, the KeyStore generates an AES key to encrypt/decrypt the database key, + * and the encrypted key is stored with the initialization vector in base64 in the shared pref. + * On android