diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt index cb04fa45..4ef996c6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt @@ -26,8 +26,7 @@ import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.di.MoshiProvider import timber.log.Timber import java.lang.reflect.ParameterizedType -import java.util.ArrayList -import java.util.HashMap +import java.util.* typealias Content = JsonDict @@ -94,7 +93,8 @@ data class Event( * This is a small MXEvent instance with typically value for `type` and 'content' fields. */ @Transient - private var mClearEvent: Event? = null + var mClearEvent: Event? = null + private set /** * Curve25519 key which we believe belongs to the sender of the event. @@ -121,7 +121,8 @@ data class Event( * Decryption error */ @Transient - private var mCryptoError: MXCryptoError? = null + var mCryptoError: MXCryptoError? = null + private set /** * @return true if this event is encrypted. @@ -141,16 +142,16 @@ data class Event( mClearEvent = null if (null != decryptionResult) { - if (null != decryptionResult!!.mClearEvent) { - mClearEvent = decryptionResult!!.mClearEvent + if (null != decryptionResult.mClearEvent) { + mClearEvent = decryptionResult.mClearEvent } if (null != mClearEvent) { - mClearEvent!!.mSenderCurve25519Key = decryptionResult!!.mSenderCurve25519Key - mClearEvent!!.mClaimedEd25519Key = decryptionResult!!.mClaimedEd25519Key + mClearEvent!!.mSenderCurve25519Key = decryptionResult.mSenderCurve25519Key + mClearEvent!!.mClaimedEd25519Key = decryptionResult.mClaimedEd25519Key - if (null != decryptionResult!!.mForwardingCurve25519KeyChain) { - mClearEvent!!.mForwardingCurve25519KeyChain = decryptionResult!!.mForwardingCurve25519KeyChain + if (null != decryptionResult.mForwardingCurve25519KeyChain) { + mClearEvent!!.mForwardingCurve25519KeyChain = decryptionResult.mForwardingCurve25519KeyChain } else { mClearEvent!!.mForwardingCurve25519KeyChain = ArrayList() } @@ -163,7 +164,7 @@ data class Event( // .add("m.relates_to", getWireContent().getAsJsonObject().get("m.relates_to")) //} } catch (e: Exception) { - Timber.e(e,"Unable to restore 'm.relates_to' the clear event") + Timber.e(e, "Unable to restore 'm.relates_to' the clear event") } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt index ea606133..787e6101 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt @@ -151,7 +151,7 @@ internal class CryptoManager( fun onLiveEvent(roomId: String, event: Event) { if (event.type == EventType.ENCRYPTION) { - onCryptoEvent(roomId, event) + onRoomEncryptionEvent(roomId, event) } else if (event.type == EventType.STATE_ROOM_MEMBER) { onRoomMembershipEvent(roomId, event) } @@ -206,7 +206,7 @@ internal class CryptoManager( mCryptoConfig = MXCryptoConfig() } - mRoomEncryptors = HashMap() + mRoomEncryptors = HashMap() // TODO Merge with declaration var deviceId = mCredentials.deviceId // deviceId should always be defined @@ -770,6 +770,7 @@ internal class CryptoManager( alg.initWithMatrixSession(this, mOlmDevice, + mKeysBackup, deviceListManager, mCredentials, mSendToDeviceTask, @@ -1146,7 +1147,7 @@ internal class CryptoManager( getDecryptingThreadHandler().post { var result: MXEventDecryptionResult? = null - val alg = roomDecryptorProvider.getRoomDecryptor(event.roomId, eventContent["algorithm"] as String) + val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(this, event.roomId, eventContent["algorithm"] as String) if (null == alg) { val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, eventContent["algorithm"] as String) @@ -1342,7 +1343,8 @@ internal class CryptoManager( * * @param event the encryption event. */ - fun onCryptoEvent(roomId: String, event: Event) { + private fun onRoomEncryptionEvent(roomId: String, event: Event) { + // TODO Parse the event val eventContent = event.content // wireEventContent val room = mRoomService.getRoom(roomId)!! @@ -1520,7 +1522,7 @@ internal class CryptoManager( // But that message might never arrive leaving us stuck with duff // private keys clogging up our local storage. // So we need some kind of enginering compromise to balance all of - // these factors. + // these factors. // TODO Why we do not set mOneTimeKeyCount here? val keyCount = data.oneTimeKeyCountsForAlgorithm(MXKey.KEY_SIGNED_CURVE_25519_TYPE) uploadOTK(keyCount, keyLimit, callback) } @@ -1765,7 +1767,7 @@ internal class CryptoManager( cpt++ - val decrypting = roomDecryptorProvider.getRoomDecryptor(megolmSessionData.roomId, megolmSessionData.algorithm) + val decrypting = roomDecryptorProvider.getOrCreateRoomDecryptor(this, megolmSessionData.roomId, megolmSessionData.algorithm) if (null != decrypting) { try { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt index 63275c4b..f8fa39ed 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt @@ -51,10 +51,10 @@ internal class MXOlmDevice( var deviceEd25519Key: String? = null private set - // The OLMKit account instance. + // The OLM lib account instance. private var mOlmAccount: OlmAccount? = null - // The OLMKit utility instance. + // The OLM lib utility instance. private var mOlmUtility: OlmUtility? = null // The outbound group session. @@ -144,9 +144,7 @@ internal class MXOlmDevice( * Release the instance */ fun release() { - if (null != mOlmAccount) { - mOlmAccount!!.releaseAccount() - } + mOlmAccount?.releaseAccount() } /** @@ -265,7 +263,7 @@ internal class MXOlmDevice( Timber.d("## createInboundSession() : ciphertext: $ciphertext") try { - Timber.d("## createInboundSession() :ciphertext: SHA256:" + mOlmUtility!!.sha256(URLEncoder.encode(ciphertext, "utf-8"))) + Timber.d("## createInboundSession() :ciphertext: SHA256:" + mOlmUtility!!.sha256(URLEncoder.encode(ciphertext, "utf-8"))) // TODO Extract code from the Log method... } catch (e: Exception) { Timber.e(e, "## createInboundSession() :ciphertext: cannot encode ciphertext") } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOutgoingRoomKeyRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOutgoingRoomKeyRequestManager.kt index c314fcba..a56f2cb6 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOutgoingRoomKeyRequestManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOutgoingRoomKeyRequestManager.kt @@ -298,7 +298,7 @@ internal class MXOutgoingRoomKeyRequestManager( val contentMap = MXUsersDevicesMap() for (recipient in recipients) { - contentMap.setObject(message, recipient["userId"], recipient["deviceId"]) + contentMap.setObject(message, recipient["userId"], recipient["deviceId"]) // TODO Change this two hard coded key to something better } mSendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ROOM_KEY_REQUEST, contentMap, transactionId)) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/RoomDecryptorProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/RoomDecryptorProvider.kt index 04a0f596..7a687221 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/RoomDecryptorProvider.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/RoomDecryptorProvider.kt @@ -33,7 +33,7 @@ internal class RoomDecryptorProvider( ) { // A map from algorithm to MXDecrypting instance, for each room - private val mRoomDecryptors: MutableMap>/* room id */ = HashMap() + private val mRoomDecryptors: MutableMap> = HashMap() /** * Get a decryptor for a given room and algorithm. @@ -43,7 +43,7 @@ internal class RoomDecryptorProvider( * @param roomId the room id * @param algorithm the crypto algorithm * @return the decryptor - * TODO do not provide cryptoManager? + * TODO do not provide cryptoManager? // TODO Create another method for the case of roomId is null */ fun getOrCreateRoomDecryptor(cryptoManager: CryptoManager, roomId: String?, algorithm: String?): IMXDecrypting? { // sanity check diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt index dafec264..bbfe7201 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXEncrypting.kt @@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.internal.crypto.DeviceListManager import im.vector.matrix.android.internal.crypto.MXOlmDevice import im.vector.matrix.android.internal.crypto.CryptoManager +import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask import im.vector.matrix.android.internal.task.TaskExecutor @@ -39,6 +40,7 @@ internal interface IMXEncrypting { */ fun initWithMatrixSession(crypto: CryptoManager, olmDevice: MXOlmDevice, + keysBackup: KeysBackup, deviceListManager: DeviceListManager, credentials: Credentials, sendToDeviceTask: SendToDeviceTask, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index 74bf33cc..b87867d5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -62,7 +62,7 @@ internal class MXMegolmDecryption : IMXDecrypting { * Events which we couldn't decrypt due to unknown sessions / indexes: map from * senderKey|sessionId to timelines to list of MatrixEvents. */ - private var mPendingEvents: MutableMap>>? = null/* senderKey|sessionId */ + private var mPendingEvents: MutableMap>> = HashMap() /** * Init the object fields @@ -74,11 +74,11 @@ internal class MXMegolmDecryption : IMXDecrypting { sendToDeviceTask: SendToDeviceTask, taskExecutor: TaskExecutor) { mCredentials = credentials + mCrypto = crypto + mOlmDevice = olmDevice mDeviceListManager = deviceListManager mSendToDeviceTask = sendToDeviceTask mTaskExecutor = taskExecutor - mOlmDevice = olmDevice - mPendingEvents = HashMap() } @Throws(MXDecryptionException::class) @@ -167,7 +167,7 @@ internal class MXMegolmDecryption : IMXDecrypting { val recipients = ArrayList>() val selfMap = HashMap() - selfMap["userId"] = mCredentials.userId + selfMap["userId"] = mCredentials.userId // TODO Replace this hard coded keys (see MXOutgoingRoomKeyRequestManager) selfMap["deviceId"] = "*" recipients.add(selfMap) @@ -196,27 +196,21 @@ internal class MXMegolmDecryption : IMXDecrypting { * @param timelineId the timeline identifier */ private fun addEventToPendingList(event: Event, timelineId: String) { - var timelineId = timelineId val encryptedEventContent = event.content.toModel()!! val k = "${encryptedEventContent.senderKey}|${encryptedEventContent.sessionId}" - // avoid undefined timelineId - if (TextUtils.isEmpty(timelineId)) { - timelineId = "" + if (!mPendingEvents.containsKey(k)) { + mPendingEvents[k] = HashMap() } - if (!mPendingEvents!!.containsKey(k)) { - mPendingEvents!![k] = HashMap() + if (!mPendingEvents[k]!!.containsKey(timelineId)) { + mPendingEvents[k]!!.put(timelineId, ArrayList()) } - if (!mPendingEvents!![k]!!.containsKey(timelineId)) { - mPendingEvents!![k]!!.put(timelineId, ArrayList()) - } - - if (mPendingEvents!![k]!![timelineId]!!.indexOf(event) < 0) { + if (mPendingEvents[k]!![timelineId]!!.indexOf(event) < 0) { Timber.d("## addEventToPendingList() : add Event " + event.eventId + " in room id " + event.roomId) - mPendingEvents!![k]!![timelineId]!!.add(event) + mPendingEvents[k]!![timelineId]!!.add(event) } } @@ -304,11 +298,11 @@ internal class MXMegolmDecryption : IMXDecrypting { override fun onNewSession(senderKey: String, sessionId: String) { val k = "$senderKey|$sessionId" - val pending = mPendingEvents!![k] + val pending = mPendingEvents[k] if (null != pending) { // Have another go at decrypting events sent with this session. - mPendingEvents!!.remove(k) + mPendingEvents.remove(k) val timelineIds = pending.keys diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index d49f9c87..7b596fa7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -27,17 +27,13 @@ import im.vector.matrix.android.api.session.crypto.MXCryptoError import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toContent -import im.vector.matrix.android.internal.crypto.CryptoAsyncHelper -import im.vector.matrix.android.internal.crypto.DeviceListManager -import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import im.vector.matrix.android.internal.crypto.MXOlmDevice +import im.vector.matrix.android.internal.crypto.* import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting +import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo import im.vector.matrix.android.internal.crypto.model.MXOlmSessionResult import im.vector.matrix.android.internal.crypto.model.MXQueuedEncryption import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap -import im.vector.matrix.android.internal.crypto.CryptoManager -import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.task.TaskExecutor @@ -51,15 +47,15 @@ internal class MXMegolmEncryption : IMXEncrypting { private lateinit var mCrypto: CryptoManager private lateinit var olmDevice: MXOlmDevice + private lateinit var mKeysBackup: KeysBackup private lateinit var mDeviceListManager: DeviceListManager - private lateinit var mKeysBackup: KeysBackup private lateinit var mCredentials: Credentials private lateinit var mSendToDeviceTask: SendToDeviceTask private lateinit var mTaskExecutor: TaskExecutor // The id of the room we will be sending to. - private var mRoomId: String? = null + private lateinit var mRoomId: String private var mDeviceId: String? = null @@ -93,6 +89,7 @@ internal class MXMegolmEncryption : IMXEncrypting { override fun initWithMatrixSession(crypto: CryptoManager, olmDevice: MXOlmDevice, + keysBackup: KeysBackup, deviceListManager: DeviceListManager, credentials: Credentials, sendToDeviceTask: SendToDeviceTask, @@ -101,6 +98,7 @@ internal class MXMegolmEncryption : IMXEncrypting { mCrypto = crypto this.olmDevice = olmDevice mDeviceListManager = deviceListManager + mKeysBackup = keysBackup mCredentials = credentials mSendToDeviceTask = sendToDeviceTask mTaskExecutor = taskExecutor @@ -108,6 +106,7 @@ internal class MXMegolmEncryption : IMXEncrypting { mRoomId = roomId mDeviceId = mCredentials.deviceId + // Default rotation periods // TODO: Make it configurable via parameters mSessionRotationPeriodMsgs = 100 diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt index 8a9a2c25..8aa9f17e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -25,10 +25,9 @@ import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.internal.crypto.* import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting -import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore -import im.vector.matrix.android.internal.crypto.CryptoManager import im.vector.matrix.android.internal.crypto.model.event.OlmEventContent import im.vector.matrix.android.internal.crypto.model.event.OlmPayloadContent +import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.util.convertFromUTF8 @@ -42,7 +41,7 @@ import java.util.* internal class MXOlmDecryption : IMXDecrypting { // The olm device interface - private var mOlmDevice: MXOlmDevice? = null + private lateinit var mOlmDevice: MXOlmDevice // the matrix credentials private lateinit var mCredentials: Credentials @@ -60,9 +59,9 @@ internal class MXOlmDecryption : IMXDecrypting { taskExecutor: TaskExecutor) { mCredentials = credentials mCrypto = crypto + mOlmDevice = olmDevice mSendToDeviceTask = sendToDeviceTask mTaskExecutor = taskExecutor - mOlmDevice = olmDevice } @Throws(MXDecryptionException::class) @@ -81,15 +80,15 @@ internal class MXOlmDecryption : IMXDecrypting { MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON)) } - if (!olmEventContent.ciphertext!!.containsKey(mOlmDevice!!.deviceCurve25519Key)) { - Timber.e("## decryptEvent() : our device " + mOlmDevice!!.deviceCurve25519Key + if (!olmEventContent.ciphertext!!.containsKey(mOlmDevice.deviceCurve25519Key)) { + Timber.e("## decryptEvent() : our device " + mOlmDevice.deviceCurve25519Key + " is not included in recipients. Event") throw MXDecryptionException(MXCryptoError(MXCryptoError.NOT_INCLUDE_IN_RECIPIENTS_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.NOT_INCLUDED_IN_RECIPIENT_REASON)) } // The message for myUser - val message = olmEventContent.ciphertext!![mOlmDevice!!.deviceCurve25519Key] as Map + val message = olmEventContent.ciphertext!![mOlmDevice.deviceCurve25519Key] as Map val payloadString = decryptMessage(message, olmEventContent.senderKey) if (null == payloadString) { @@ -131,7 +130,7 @@ internal class MXOlmDecryption : IMXDecrypting { val ed25519 = olmPayloadContent.recipient_keys!!.get("ed25519") - if (!TextUtils.equals(ed25519, mOlmDevice!!.deviceEd25519Key)) { + if (!TextUtils.equals(ed25519, mOlmDevice.deviceEd25519Key)) { Timber.e("## decryptEvent() : Event " + event.eventId + ": Intended recipient ed25519 key " + ed25519 + " did not match ours") throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_RECIPIENT_KEY_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_RECIPIENT_KEY_REASON)) @@ -194,7 +193,7 @@ internal class MXOlmDecryption : IMXDecrypting { * @return payload, if decrypted successfully. */ private fun decryptMessage(message: Map, theirDeviceIdentityKey: String?): String? { - val sessionIdsSet = mOlmDevice!!.getSessionIds(theirDeviceIdentityKey!!) + val sessionIdsSet = mOlmDevice.getSessionIds(theirDeviceIdentityKey!!) val sessionIds: List @@ -226,13 +225,13 @@ internal class MXOlmDecryption : IMXDecrypting { // Try each session in turn // decryptionErrors = {}; for (sessionId in sessionIds) { - val payload = mOlmDevice!!.decryptMessage(messageBody, messageType, sessionId, theirDeviceIdentityKey) + val payload = mOlmDevice.decryptMessage(messageBody, messageType, sessionId, theirDeviceIdentityKey) if (null != payload) { Timber.d("## decryptMessage() : Decrypted Olm message from $theirDeviceIdentityKey with session $sessionId") return payload } else { - val foundSession = mOlmDevice!!.matchesSession(theirDeviceIdentityKey, sessionId, messageType, messageBody) + val foundSession = mOlmDevice.matchesSession(theirDeviceIdentityKey, sessionId, messageType, messageBody) if (foundSession) { // Decryption failed, but it was a prekey message matching this @@ -258,7 +257,7 @@ internal class MXOlmDecryption : IMXDecrypting { // prekey message which doesn't match any existing sessions: make a new // session. - val res = mOlmDevice!!.createInboundSession(theirDeviceIdentityKey, messageType, messageBody) + val res = mOlmDevice.createInboundSession(theirDeviceIdentityKey, messageType, messageBody) if (null == res) { Timber.e("## decryptMessage() : Error decrypting non-prekey message with existing sessions") @@ -269,8 +268,4 @@ internal class MXOlmDecryption : IMXDecrypting { return res["payload"] } - - companion object { - private val LOG_TAG = "MXOlmDecryption" - } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt index 1242956b..aa4e42a3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmEncryption.kt @@ -24,13 +24,14 @@ import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.toContent +import im.vector.matrix.android.internal.crypto.CryptoManager import im.vector.matrix.android.internal.crypto.DeviceListManager import im.vector.matrix.android.internal.crypto.MXOlmDevice import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting +import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo import im.vector.matrix.android.internal.crypto.model.MXOlmSessionResult import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap -import im.vector.matrix.android.internal.crypto.CryptoManager import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask import im.vector.matrix.android.internal.task.TaskExecutor import java.util.* @@ -49,6 +50,7 @@ internal class MXOlmEncryption : IMXEncrypting { override fun initWithMatrixSession(crypto: CryptoManager, olmDevice: MXOlmDevice, + keysBackup: KeysBackup, deviceListManager: DeviceListManager, credentials: Credentials, sendToDeviceTask: SendToDeviceTask, @@ -69,7 +71,7 @@ internal class MXOlmEncryption : IMXEncrypting { // // TODO: there is a race condition here! What if a new user turns up ensureSession(userIds, object : MatrixCallback { - override fun onSuccess(info: Unit) { + override fun onSuccess(data: Unit) { val deviceInfos = ArrayList() for (userId in userIds) { @@ -95,11 +97,11 @@ internal class MXOlmEncryption : IMXEncrypting { } val messageMap = HashMap() - messageMap["room_id"] = mRoomId!! + messageMap["room_id"] = mRoomId messageMap["type"] = eventType messageMap["content"] = eventContent - mCrypto!!.encryptMessage(messageMap, deviceInfos) + mCrypto.encryptMessage(messageMap, deviceInfos) callback.onSuccess(messageMap.toContent()!!) } @@ -116,7 +118,7 @@ internal class MXOlmEncryption : IMXEncrypting { mDeviceListManager.downloadKeys(users, false, object : MatrixCallback> { override fun onSuccess(data: MXUsersDevicesMap) { - mCrypto!!.ensureOlmSessionsForUsers(users, object : MatrixCallback> { + mCrypto.ensureOlmSessionsForUsers(users, object : MatrixCallback> { override fun onSuccess(data: MXUsersDevicesMap) { callback?.onSuccess(Unit) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt index c37ab767..5eaad8d8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt @@ -201,7 +201,7 @@ internal class RealmCryptoStore(private val enableFileEncryption: Boolean = fals .let { u -> // Add the devices // Ensure all other devices are deleted - u.devices.deleteAllFromRealm() + u.devices.deleteAllFromRealm() // Device is null!! u.devices.addAll( devices.map { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt index 088182c3..bf03e097 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt @@ -16,25 +16,65 @@ package im.vector.matrix.android.internal.session.sync +import android.text.TextUtils +import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.session.events.model.EventType +import im.vector.matrix.android.api.session.events.model.toModel +import im.vector.matrix.android.api.session.room.model.message.MessageContent import im.vector.matrix.android.internal.crypto.CryptoManager +import im.vector.matrix.android.internal.crypto.MXDecryptionException +import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService import im.vector.matrix.android.internal.session.sync.model.SyncResponse import im.vector.matrix.android.internal.session.sync.model.ToDeviceSyncResponse +import timber.log.Timber internal class CryptoSyncHandler(private val cryptoManager: CryptoManager, private val sasVerificationService: DefaultSasVerificationService) { fun handleToDevice(toDevice: ToDeviceSyncResponse) { - toDevice.events?.forEach { - sasVerificationService.onToDeviceEvent(it) - cryptoManager.onToDeviceEvent(it) - } + toDevice.events?.forEach { event -> + // Decrypt event if necessary + decryptEvent(event, null) + if (TextUtils.equals(event.getClearType(), EventType.MESSAGE) + && event.mClearEvent?.content?.toModel()?.type == "m.bad.encrypted") { + Timber.e("## handleToDeviceEvent() : Warning: Unable to decrypt to-device event : " + event.content) + } else { + sasVerificationService.onToDeviceEvent(event) + cryptoManager.onToDeviceEvent(event) + } + } } fun onSyncCompleted(syncResponse: SyncResponse, fromToken: String?, catchingUp: Boolean) { cryptoManager.onSyncCompleted(syncResponse, fromToken, catchingUp) } + + /** + * Decrypt an encrypted event + * + * @param event the event to decrypt + * @param timelineId the timeline identifier + * @return true if the event has been decrypted + */ + private fun decryptEvent(event: Event, timelineId: String?): Boolean { + if (event.type == EventType.ENCRYPTED) { + var result: MXEventDecryptionResult? = null + try { + result = cryptoManager.decryptEvent(event, timelineId ?: "") + } catch (exception: MXDecryptionException) { + event.setCryptoError(exception.cryptoError) + } + + if (null != result) { + event.setClearData(result) + return true + } + } + + return false + } } \ No newline at end of file