diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 46457ee494..59acf1b8db 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -1349,13 +1349,14 @@ internal class DefaultCryptoService @Inject constructor( val deviceId = it.key sessionInfoSet?.mapNotNull { sessionInfoPair -> // Get inbound session from sessionId and sessionKey - cryptoStore.getInboundGroupSession(sessionInfoPair.first, sessionInfoPair.second) - }?.filter { inboundGroupSession -> - // Filter only sessions with sharedHistory enabled - inboundGroupSession.sharedHistory + cryptoStore.getInboundGroupSession( + sessionId = sessionInfoPair.first, + senderKey = sessionInfoPair.second, + sharedHistory = true + ) }?.forEach { inboundGroupSession -> - // Share the session to userId with deviceId - val exportedKeys = inboundGroupSession.exportKeys() + // Share the sharable session to userId with deviceId + val exportedKeys = inboundGroupSession.exportKeys(sharedHistory = true) val algorithm = exportedKeys?.algorithm val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, algorithm) decryptor?.shareKeysWithDevice(exportedKeys, deviceId, userId) @@ -1366,26 +1367,6 @@ internal class DefaultCryptoService @Inject constructor( } } - override fun sendSharedHistoryKeys(roomId: String, userId: String) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - val userDevices = cryptoStore.getUserDevices(userId) - userDevices?.forEach { - // Lets share our existing inbound sessions for every user device - val deviceId = it.key - val inboundSessions = cryptoStore.getInboundGroupSessions(roomId) - inboundSessions.filter { inboundGroupSession -> - inboundGroupSession.sharedHistory - }.forEach { inboundGroupSession -> - // Share the session to userId with deviceId - val exportedKeys = inboundGroupSession.exportKeys() - val algorithm = exportedKeys?.algorithm - val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, algorithm) - decryptor?.shareKeysWithDevice(exportedKeys, deviceId, userId) - Timber.i("## CRYPTO | Sharing inbound session") - } - } - } - } /* ========================================================================================== * For test only * ========================================================================================== */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt index f6bc9a9148..43b88c0b42 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt @@ -69,5 +69,13 @@ internal data class MegolmSessionData( * Devices which forwarded this session to us (normally empty). */ @Json(name = "forwarding_curve25519_key_chain") - val forwardingCurve25519KeyChain: List? = null + val forwardingCurve25519KeyChain: List? = null, + + /** + * Flag that indicates whether or not the current inboundSession will be shared to + * invited users to decrypt past messages + */ + // When this feature lands in spec name = shared_history should be used + @Json(name = "org.matrix.msc3061.shared_history") + val sharedHistory: Boolean = false, ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt index 570532ae8b..b3898e001b 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt @@ -43,10 +43,6 @@ internal class OlmInboundGroupSessionWrapper2 : Serializable { // Devices which forwarded this session to us (normally empty). var forwardingCurve25519KeyChain: List? = ArrayList() - // Flag that indicates whether or not the current inboundSession will be shared to - // invited users to decrypt past messages - var sharedHistory: Boolean = false - /** * @return the first known message index */ @@ -110,10 +106,10 @@ internal class OlmInboundGroupSessionWrapper2 : Serializable { /** * Export the inbound group session keys. * @param index the index to export. If null, the first known index will be used - * + * @param sharedHistory the flag that indicates whether or not the session can be shared * @return the inbound group session as MegolmSessionData if the operation succeeds */ - fun exportKeys(index: Long? = null): MegolmSessionData? { + fun exportKeys(sharedHistory: Boolean = false, index: Long? = null): MegolmSessionData? { return try { if (null == forwardingCurve25519KeyChain) { forwardingCurve25519KeyChain = ArrayList() @@ -135,7 +131,8 @@ internal class OlmInboundGroupSessionWrapper2 : Serializable { roomId = roomId, sessionId = safeOlmInboundGroupSession.sessionIdentifier(), sessionKey = safeOlmInboundGroupSession.export(wantedIndex), - algorithm = MXCRYPTO_ALGORITHM_MEGOLM + algorithm = MXCRYPTO_ALGORITHM_MEGOLM, + sharedHistory = sharedHistory ) } catch (e: Exception) { Timber.e(e, "## export() : senderKey $senderKey failed") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index ceb91aa8ce..65e360a4f3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -321,7 +321,17 @@ internal interface IMXCryptoStore { fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper2? /** - * Get the current outbound group session for this encrypted room. + * Retrieve an inbound group session, filtering shared history. + * + * @param sessionId the session identifier. + * @param senderKey the base64-encoded curve25519 key of the sender. + * @param sharedHistory filter inbound session with respect to shared history field + * @return an inbound group session. + */ + fun getInboundGroupSession(sessionId: String, senderKey: String, sharedHistory: Boolean): OlmInboundGroupSessionWrapper2? + + /** + * Get the current outbound group session for this encrypted room */ fun getCurrentOutboundGroupSessionForRoom(roomId: String): OutboundGroupSessionWrapper? diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 7cc2f75285..3034d432c2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -759,7 +759,6 @@ internal class RealmCryptoStore @Inject constructor( val shouldShareHistory = session.roomId?.let { roomId -> CryptoRoomEntity.getById(realm, roomId)?.shouldShareHistory } ?: false - session.sharedHistory = shouldShareHistory val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionIdentifier, session.senderKey) val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply { @@ -788,6 +787,17 @@ internal class RealmCryptoStore @Inject constructor( } } + override fun getInboundGroupSession(sessionId: String, senderKey: String, sharedHistory: Boolean): OlmInboundGroupSessionWrapper2? { + val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey) + return doWithRealm(realmConfiguration) { + it.where() + .equalTo(OlmInboundGroupSessionEntityFields.SHARED_HISTORY, sharedHistory) + .equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key) + .findFirst() + ?.getInboundGroupSession() + } + } + override fun getCurrentOutboundGroupSessionForRoom(roomId: String): OutboundGroupSessionWrapper? { return doWithRealm(realmConfiguration) { realm -> realm.where()