diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt index 50f55577d0..0417504cb7 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt @@ -124,9 +124,9 @@ class RxSession(private val session: Session) { } fun liveAccountData(filter: List<String>): Observable<List<UserAccountDataEvent>> { - return session.getLiveAccountData(filter).asObservable() + return session.getLiveAccountDataEvents(filter).asObservable() .startWithCallable { - session.getAccountData(filter) + session.getAccountDataEvents(filter) } } } diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt index badfd09d3f..f0e2161d4c 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt @@ -25,7 +25,7 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.securestorage.Curve25519AesSha2KeySpec import im.vector.matrix.android.api.session.securestorage.EncryptedSecretContent import im.vector.matrix.android.api.session.securestorage.KeySigner -import im.vector.matrix.android.api.session.securestorage.SSSSKeyCreationInfo +import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo import im.vector.matrix.android.api.session.securestorage.SecretStorageKeyContent import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.common.CommonTestHelper @@ -33,8 +33,9 @@ import im.vector.matrix.android.common.CryptoTestHelper import im.vector.matrix.android.common.SessionTestParams import im.vector.matrix.android.common.TestConstants import im.vector.matrix.android.common.TestMatrixCallback +import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2 import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding -import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorage +import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -74,8 +75,8 @@ class QuadSTests : InstrumentedTest { val TEST_KEY_ID = "my.test.Key" quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner, - object : MatrixCallback<SSSSKeyCreationInfo> { - override fun onSuccess(data: SSSSKeyCreationInfo) { + object : MatrixCallback<SsssKeyCreationInfo> { + override fun onSuccess(data: SsssKeyCreationInfo) { recoveryKey = data.recoveryKey aliceLatch.countDown() } @@ -93,7 +94,7 @@ class QuadSTests : InstrumentedTest { var accountData: UserAccountDataEvent? = null val liveAccountData = runBlocking(Dispatchers.Main) { - aliceSession.getLiveAccountData("m.secret_storage.key.$TEST_KEY_ID") + aliceSession.getLiveAccountDataEvent("m.secret_storage.key.$TEST_KEY_ID") } val accountDataObserver = Observer<Optional<UserAccountDataEvent>?> { t -> if (t?.getOrNull()?.type == "m.secret_storage.key.$TEST_KEY_ID") { @@ -108,13 +109,13 @@ class QuadSTests : InstrumentedTest { Assert.assertNotNull("Key should be stored in account data", accountData) val parsed = SecretStorageKeyContent.fromJson(accountData!!.content) Assert.assertNotNull("Key Content cannot be parsed", parsed) - Assert.assertEquals("Unexpected Algorithm", DefaultSharedSecretStorage.ALGORITHM_CURVE25519_AES_SHA2, parsed!!.algorithm) + Assert.assertEquals("Unexpected Algorithm", SSSS_ALGORITHM_CURVE25519_AES_SHA2, parsed!!.algorithm) Assert.assertEquals("Unexpected key name", "Test Key", parsed.name) Assert.assertNull("Key was not generated from passphrase", parsed.passphrase) Assert.assertNotNull("Pubkey should be defined", parsed.publicKey) val privateKeySpec = Curve25519AesSha2KeySpec.fromRecoveryKey(recoveryKey!!) - DefaultSharedSecretStorage.withOlmDecryption { olmPkDecryption -> + DefaultSharedSecretStorageService.withOlmDecryption { olmPkDecryption -> val pubKey = olmPkDecryption.setPrivateKey(privateKeySpec!!.privateKey) Assert.assertEquals("Unexpected Public Key", pubKey, parsed.publicKey) } @@ -126,10 +127,10 @@ class QuadSTests : InstrumentedTest { val defaultDataLock = CountDownLatch(1) val liveDefAccountData = runBlocking(Dispatchers.Main) { - aliceSession.getLiveAccountData(DefaultSharedSecretStorage.DEFAULT_KEY_ID) + aliceSession.getLiveAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID) } val accountDefDataObserver = Observer<Optional<UserAccountDataEvent>?> { t -> - if (t?.getOrNull()?.type == DefaultSharedSecretStorage.DEFAULT_KEY_ID) { + if (t?.getOrNull()?.type == DefaultSharedSecretStorageService.DEFAULT_KEY_ID) { defaultKeyAccountData = t.getOrNull()!! defaultDataLock.countDown() } @@ -247,7 +248,7 @@ class QuadSTests : InstrumentedTest { ) mTestHelper.await(storeLatch) - val accountDataEvent = aliceSession.getAccountData("my.secret") + val accountDataEvent = aliceSession.getAccountDataEvent("my.secret") val encryptedContent = accountDataEvent?.content?.get("encrypted") as? Map<*, *> Assert.assertEquals("Content should contains two encryptions", 2, encryptedContent?.keys?.size ?: 0) @@ -334,7 +335,7 @@ class QuadSTests : InstrumentedTest { var accountData: UserAccountDataEvent? = null val liveAccountData = runBlocking(Dispatchers.Main) { - session.getLiveAccountData(type) + session.getLiveAccountDataEvent(type) } val accountDataObserver = Observer<Optional<UserAccountDataEvent>?> { t -> if (t?.getOrNull()?.type == type) { @@ -350,7 +351,7 @@ class QuadSTests : InstrumentedTest { return accountData!! } - private fun generatedSecret(session: Session, keyId: String, asDefault: Boolean = true): SSSSKeyCreationInfo { + private fun generatedSecret(session: Session, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo { val quadS = session.sharedSecretStorageService val emptyKeySigner = object : KeySigner { @@ -359,13 +360,13 @@ class QuadSTests : InstrumentedTest { } } - var creationInfo: SSSSKeyCreationInfo? = null + var creationInfo: SsssKeyCreationInfo? = null val generateLatch = CountDownLatch(1) quadS.generateKey(keyId, keyId, emptyKeySigner, - object : MatrixCallback<SSSSKeyCreationInfo> { - override fun onSuccess(data: SSSSKeyCreationInfo) { + object : MatrixCallback<SsssKeyCreationInfo> { + override fun onSuccess(data: SsssKeyCreationInfo) { creationInfo = data generateLatch.countDown() } @@ -385,13 +386,13 @@ class QuadSTests : InstrumentedTest { val setDefaultLatch = CountDownLatch(1) quadS.setDefaultKey(keyId, TestMatrixCallback(setDefaultLatch)) mTestHelper.await(setDefaultLatch) - assertAccountData(session, DefaultSharedSecretStorage.DEFAULT_KEY_ID) + assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID) } return creationInfo!! } - private fun generatedSecretFromPassphrase(session: Session, passphrase: String, keyId: String, asDefault: Boolean = true): SSSSKeyCreationInfo { + private fun generatedSecretFromPassphrase(session: Session, passphrase: String, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo { val quadS = session.sharedSecretStorageService val emptyKeySigner = object : KeySigner { @@ -400,7 +401,7 @@ class QuadSTests : InstrumentedTest { } } - var creationInfo: SSSSKeyCreationInfo? = null + var creationInfo: SsssKeyCreationInfo? = null val generateLatch = CountDownLatch(1) @@ -408,8 +409,8 @@ class QuadSTests : InstrumentedTest { passphrase, emptyKeySigner, null, - object : MatrixCallback<SSSSKeyCreationInfo> { - override fun onSuccess(data: SSSSKeyCreationInfo) { + object : MatrixCallback<SsssKeyCreationInfo> { + override fun onSuccess(data: SsssKeyCreationInfo) { creationInfo = data generateLatch.countDown() } @@ -429,7 +430,7 @@ class QuadSTests : InstrumentedTest { val setDefaultLatch = CountDownLatch(1) quadS.setDefaultKey(keyId, TestMatrixCallback(setDefaultLatch)) mTestHelper.await(setDefaultLatch) - assertAccountData(session, DefaultSharedSecretStorage.DEFAULT_KEY_ID) + assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID) } return creationInfo!! diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt index f4ffdce71c..7af7fea214 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt @@ -24,13 +24,13 @@ import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAcco interface AccountDataService { - fun getAccountData(type: String): UserAccountDataEvent? + fun getAccountDataEvent(type: String): UserAccountDataEvent? - fun getLiveAccountData(type: String): LiveData<Optional<UserAccountDataEvent>> + fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>> - fun getAccountData(filterType: List<String>): List<UserAccountDataEvent> + fun getAccountDataEvents(filterType: List<String>): List<UserAccountDataEvent> - fun getLiveAccountData(filterType: List<String>): LiveData<List<UserAccountDataEvent>> + fun getLiveAccountDataEvents(filterType: List<String>): LiveData<List<UserAccountDataEvent>> fun updateAccountData(type: String, content: Content, callback: MatrixCallback<Unit>? = null) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt index 9923aab606..02ccc11026 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019 New Vector Ltd + * Copyright 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. @@ -31,26 +31,38 @@ import im.vector.matrix.android.api.listeners.ProgressListener interface SharedSecretStorageService { /** - * Add a key for encrypting secrets. + * Generates a SSSS key for encrypting secrets. + * Use the SsssKeyCreationInfo object returned by the callback to get more information about the created key (recovery key ...) * - * @param algorithm the algorithm used by the key. - * @param opts the options for the algorithm. The properties used - * depend on the algorithm given. * @param keyId the ID of the key + * @param keyName a human readable name + * @param keySigner Used to add a signature to the key (client should check key signature before storing secret) * - * @return {string} the ID of the key + * @param callback Get key creation info */ fun generateKey(keyId: String, keyName: String, keySigner: KeySigner, - callback: MatrixCallback<SSSSKeyCreationInfo>) + callback: MatrixCallback<SsssKeyCreationInfo>) + /** + * Generates a SSSS key using the given passphrase. + * Use the SsssKeyCreationInfo object returned by the callback to get more information about the created key (recovery key, salt, iteration ...) + * + * @param keyId the ID of the key + * @param keyName human readable key name + * @param passphrase The passphrase used to generate the key + * @param keySigner Used to add a signature to the key (client should check key signature before retrieving secret) + * @param progressListener The derivation of the passphrase may take long depending on the device, use this to report progress + * + * @param callback Get key creation info + */ fun generateKeyWithPassphrase(keyId: String, keyName: String, passphrase: String, keySigner: KeySigner, progressListener: ProgressListener?, - callback: MatrixCallback<SSSSKeyCreationInfo>) + callback: MatrixCallback<SsssKeyCreationInfo>) fun getKey(keyId: String): KeyInfoResult @@ -92,11 +104,9 @@ interface SharedSecretStorageService { * * @param name The name of the secret * @param keyId The id of the key that should be used to decrypt (null for default key) - * @param privateKey the passphrase/secret + * @param secretKey the secret key to use (@see #Curve25519AesSha2KeySpec) * - * @return The decrypted value */ @Throws - fun getSecret(name: String, keyId: String?, secretKey: SSSSKeySpec, callback: MatrixCallback<String>) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SSSSKeyCreationInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeyCreationInfo.kt similarity index 96% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SSSSKeyCreationInfo.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeyCreationInfo.kt index 5b608dd658..1d5522b8bf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SSSSKeyCreationInfo.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeyCreationInfo.kt @@ -16,7 +16,7 @@ package im.vector.matrix.android.api.session.securestorage -data class SSSSKeyCreationInfo( +data class SsssKeyCreationInfo( val keyId: String = "", var content: SecretStorageKeyContent?, val recoveryKey: String = "" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SSSSKeySpec.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeySpec.kt similarity index 100% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SSSSKeySpec.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeySpec.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt index a3b0a567fe..fee81a853d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt @@ -31,6 +31,11 @@ const val MXCRYPTO_ALGORITHM_MEGOLM = "m.megolm.v1.aes-sha2" */ const val MXCRYPTO_ALGORITHM_MEGOLM_BACKUP = "m.megolm_backup.v1.curve25519-aes-sha2" +/** + * Secured Shared Storage algorithm constant + */ +const val SSSS_ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2" + // TODO Refacto: use this constants everywhere const val ed25519 = "ed25519" const val curve25519 = "curve25519" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorage.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorageService.kt similarity index 93% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorage.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorageService.kt index fe6936f7fd..f741021e6c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorage.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/secrets/DefaultSharedSecretStorageService.kt @@ -25,12 +25,13 @@ import im.vector.matrix.android.api.session.securestorage.EncryptedSecretContent import im.vector.matrix.android.api.session.securestorage.KeyInfo import im.vector.matrix.android.api.session.securestorage.KeyInfoResult import im.vector.matrix.android.api.session.securestorage.KeySigner -import im.vector.matrix.android.api.session.securestorage.SSSSKeyCreationInfo +import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo import im.vector.matrix.android.api.session.securestorage.SSSSKeySpec import im.vector.matrix.android.api.session.securestorage.SSSSPassphrase import im.vector.matrix.android.api.session.securestorage.SecretStorageKeyContent import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageError import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService +import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2 import im.vector.matrix.android.internal.crypto.keysbackup.generatePrivateKeyWithPassword import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey import im.vector.matrix.android.internal.extensions.foldToCallback @@ -42,7 +43,7 @@ import org.matrix.olm.OlmPkEncryption import org.matrix.olm.OlmPkMessage import javax.inject.Inject -internal class DefaultSharedSecretStorage @Inject constructor( +internal class DefaultSharedSecretStorageService @Inject constructor( private val accountDataService: AccountDataService, private val coroutineDispatchers: MatrixCoroutineDispatchers, private val cryptoCoroutineScope: CoroutineScope @@ -51,7 +52,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( override fun generateKey(keyId: String, keyName: String, keySigner: KeySigner, - callback: MatrixCallback<SSSSKeyCreationInfo>) { + callback: MatrixCallback<SsssKeyCreationInfo>) { cryptoCoroutineScope.launch(coroutineDispatchers.main) { val pkDecryption = OlmPkDecryption() val pubKey: String @@ -69,7 +70,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( val storageKeyContent = SecretStorageKeyContent( name = keyName, - algorithm = ALGORITHM_CURVE25519_AES_SHA2, + algorithm = SSSS_ALGORITHM_CURVE25519_AES_SHA2, passphrase = null, publicKey = pubKey ) @@ -89,7 +90,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( } override fun onSuccess(data: Unit) { - callback.onSuccess(SSSSKeyCreationInfo( + callback.onSuccess(SsssKeyCreationInfo( keyId = keyId, content = storageKeyContent, recoveryKey = computeRecoveryKey(privateKey) @@ -105,7 +106,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( passphrase: String, keySigner: KeySigner, progressListener: ProgressListener?, - callback: MatrixCallback<SSSSKeyCreationInfo>) { + callback: MatrixCallback<SsssKeyCreationInfo>) { cryptoCoroutineScope.launch(coroutineDispatchers.main) { val privatePart = generatePrivateKeyWithPassword(passphrase, progressListener) @@ -122,7 +123,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( } val storageKeyContent = SecretStorageKeyContent( - algorithm = ALGORITHM_CURVE25519_AES_SHA2, + algorithm = SSSS_ALGORITHM_CURVE25519_AES_SHA2, passphrase = SSSSPassphrase(algorithm = "m.pbkdf2", iterations = privatePart.iterations, salt = privatePart.salt), publicKey = pubKey ) @@ -142,7 +143,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( } override fun onSuccess(data: Unit) { - callback.onSuccess(SSSSKeyCreationInfo( + callback.onSuccess(SsssKeyCreationInfo( keyId = keyId, content = storageKeyContent, recoveryKey = computeRecoveryKey(privatePart.privateKey) @@ -154,11 +155,11 @@ internal class DefaultSharedSecretStorage @Inject constructor( } override fun hasKey(keyId: String): Boolean { - return accountDataService.getAccountData("$KEY_ID_BASE.$keyId") != null + return accountDataService.getAccountDataEvent("$KEY_ID_BASE.$keyId") != null } override fun getKey(keyId: String): KeyInfoResult { - val accountData = accountDataService.getAccountData("$KEY_ID_BASE.$keyId") + val accountData = accountDataService.getAccountDataEvent("$KEY_ID_BASE.$keyId") ?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(keyId)) return SecretStorageKeyContent.fromJson(accountData.content)?.let { KeyInfoResult.Success( @@ -180,7 +181,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( } override fun getDefaultKey(): KeyInfoResult { - val accountData = accountDataService.getAccountData(DEFAULT_KEY_ID) + val accountData = accountDataService.getAccountDataEvent(DEFAULT_KEY_ID) ?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(DEFAULT_KEY_ID)) val keyId = accountData.content["key"] as? String ?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(DEFAULT_KEY_ID)) @@ -196,7 +197,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( val key = getDefaultKey() when (key) { is KeyInfoResult.Success -> { - if (key.keyInfo.content.algorithm == ALGORITHM_CURVE25519_AES_SHA2) { + if (key.keyInfo.content.algorithm == SSSS_ALGORITHM_CURVE25519_AES_SHA2) { withOlmEncryption { olmEncrypt -> olmEncrypt.setRecipientKey(key.keyInfo.content.publicKey) val encryptedResult = olmEncrypt.encrypt(secretBase64) @@ -224,7 +225,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( val key = getKey(keyId) when (key) { is KeyInfoResult.Success -> { - if (key.keyInfo.content.algorithm == ALGORITHM_CURVE25519_AES_SHA2) { + if (key.keyInfo.content.algorithm == SSSS_ALGORITHM_CURVE25519_AES_SHA2) { withOlmEncryption { olmEncrypt -> olmEncrypt.setRecipientKey(key.keyInfo.content.publicKey) val encryptedResult = olmEncrypt.encrypt(secretBase64) @@ -264,7 +265,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( } override fun getAlgorithmsForSecret(name: String): List<KeyInfoResult> { - val accountData = accountDataService.getAccountData(name) + val accountData = accountDataService.getAccountDataEvent(name) ?: return listOf(KeyInfoResult.Error(SharedSecretStorageError.UnknownSecret(name))) val encryptedContent = accountData.content[ENCRYPTED] as? Map<*, *> ?: return listOf(KeyInfoResult.Error(SharedSecretStorageError.SecretNotEncrypted(name))) @@ -279,7 +280,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( } override fun getSecret(name: String, keyId: String?, secretKey: SSSSKeySpec, callback: MatrixCallback<String>) { - val accountData = accountDataService.getAccountData(name) ?: return Unit.also { + val accountData = accountDataService.getAccountDataEvent(name) ?: return Unit.also { callback.onFailure(SharedSecretStorageError.UnknownSecret(name)) } val encryptedContent = accountData.content[ENCRYPTED] as? Map<*, *> ?: return Unit.also { @@ -299,7 +300,7 @@ internal class DefaultSharedSecretStorage @Inject constructor( } val algorithm = key.keyInfo.content - if (ALGORITHM_CURVE25519_AES_SHA2 == algorithm.algorithm) { + if (SSSS_ALGORITHM_CURVE25519_AES_SHA2 == algorithm.algorithm) { val keySpec = secretKey as? Curve25519AesSha2KeySpec ?: return Unit.also { callback.onFailure(SharedSecretStorageError.BadKeyFormat) } @@ -332,8 +333,6 @@ internal class DefaultSharedSecretStorage @Inject constructor( const val ENCRYPTED = "encrypted" const val DEFAULT_KEY_ID = "m.secret_storage.default_key" - const val ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2" - fun withOlmEncryption(block: (OlmPkEncryption) -> Unit) { val olmPkEncryption = OlmPkEncryption() try { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/UserAccountDataEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/UserAccountDataEntity.kt index 9ffbcca527..90f73381dc 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/UserAccountDataEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/UserAccountDataEntity.kt @@ -20,9 +20,10 @@ import io.realm.RealmObject import io.realm.annotations.Index /** - * Clients can store custom config data for their account on their homeserver. + * Clients can store custom config data for their account on their HomeServer. * This account data will be synced between different devices and can persist across installations on a particular device. - * Users may only view the account data for their own accountThe account_data may be either global or scoped to a particular rooms. + * Users may only view the account data for their own account. + * The account_data may be either global or scoped to a particular rooms. */ internal open class UserAccountDataEntity( @Index var type: String? = null, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/parsing/AccountDataJsonAdapterFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/parsing/AccountDataJsonAdapterFactory.kt deleted file mode 100644 index bf8ae84478..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/parsing/AccountDataJsonAdapterFactory.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.network.parsing - -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Moshi -import java.lang.reflect.Type - -class AccountDataJsonAdapterFactory<UserAccountData> : JsonAdapter.Factory { - - override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index b06ddbe123..7352b79073 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -36,7 +36,7 @@ import im.vector.matrix.android.api.session.accountdata.AccountDataService import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService import im.vector.matrix.android.api.session.securestorage.SecureStorageService import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService -import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorage +import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory @@ -269,8 +269,8 @@ internal abstract class SessionModule { abstract fun bindHomeServerCapabilitiesService(homeServerCapabilitiesService: DefaultHomeServerCapabilitiesService): HomeServerCapabilitiesService @Binds - abstract fun bindAccountDataServiceService(accountDataService: DefaultAccountDataService): AccountDataService + abstract fun bindAccountDataService(accountDataService: DefaultAccountDataService): AccountDataService @Binds - abstract fun bindSharedSecuredSecretStorageService(service: DefaultSharedSecretStorage): SharedSecretStorageService + abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt index ee9e1d2550..b40c75992a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt @@ -46,17 +46,17 @@ internal class DefaultAccountDataService @Inject constructor( private val moshi = MoshiProvider.providesMoshi() private val adapter = moshi.adapter<Map<String, Any>>(JSON_DICT_PARAMETERIZED_TYPE) - override fun getAccountData(type: String): UserAccountDataEvent? { - return getAccountData(listOf(type)).firstOrNull() + override fun getAccountDataEvent(type: String): UserAccountDataEvent? { + return getAccountDataEvents(listOf(type)).firstOrNull() } - override fun getLiveAccountData(type: String): LiveData<Optional<UserAccountDataEvent>> { - return Transformations.map(getLiveAccountData(listOf(type))) { + override fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>> { + return Transformations.map(getLiveAccountDataEvents(listOf(type))) { it.firstOrNull()?.toOptional() } } - override fun getAccountData(filterType: List<String>): List<UserAccountDataEvent> { + override fun getAccountDataEvents(filterType: List<String>): List<UserAccountDataEvent> { return monarchy.fetchAllCopiedSync { realm -> realm.where(UserAccountDataEntity::class.java) .apply { @@ -74,7 +74,7 @@ internal class DefaultAccountDataService @Inject constructor( } ?: emptyList() } - override fun getLiveAccountData(filterType: List<String>): LiveData<List<UserAccountDataEvent>> { + override fun getLiveAccountDataEvents(filterType: List<String>): LiveData<List<UserAccountDataEvent>> { return monarchy.findAllMappedWithChanges({ realm -> realm.where(UserAccountDataEntity::class.java) .apply { diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt index 0799ae270b..7a57a03deb 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt @@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent import im.vector.riotx.R +import im.vector.riotx.core.extensions.cleanup import im.vector.riotx.core.extensions.configureWith import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseFragment @@ -58,6 +59,12 @@ class AccountDataFragment @Inject constructor( epoxyController.interactionListener = this } + override fun onDestroyView() { + super.onDestroyView() + recyclerView.cleanup() + epoxyController.interactionListener = null + } + override fun didTap(data: UserAccountData) { val fb = data as? UserAccountDataEvent ?: return val jsonString = MoshiProvider.providesMoshi()