forked from GitHub-Mirror/riotX-android
Crypto: continue cleaning. Need threading refactoring
This commit is contained in:
parent
784d55c16c
commit
3d50393b33
@ -19,4 +19,4 @@ package im.vector.matrix.android
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
|
||||
internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(Main, Main, Main, Main, Main)
|
||||
internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(Main, Main, Main, Main)
|
@ -135,20 +135,20 @@ data class Event(
|
||||
internal fun setClearData(decryptionResult: MXEventDecryptionResult?) {
|
||||
mClearEvent = null
|
||||
if (decryptionResult != null) {
|
||||
if (decryptionResult.mClearEvent != null) {
|
||||
if (decryptionResult.clearEvent != null) {
|
||||
val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java)
|
||||
mClearEvent = adapter.fromJsonValue(decryptionResult.mClearEvent)
|
||||
mClearEvent = adapter.fromJsonValue(decryptionResult.clearEvent)
|
||||
|
||||
}
|
||||
mClearEvent?.apply {
|
||||
mSenderCurve25519Key = decryptionResult.mSenderCurve25519Key
|
||||
mClaimedEd25519Key = decryptionResult.mClaimedEd25519Key
|
||||
mForwardingCurve25519KeyChain = decryptionResult.mForwardingCurve25519KeyChain
|
||||
mSenderCurve25519Key = decryptionResult.senderCurve25519Key
|
||||
mClaimedEd25519Key = decryptionResult.claimedEd25519Key
|
||||
mForwardingCurve25519KeyChain = decryptionResult.forwardingCurve25519KeyChain
|
||||
try {
|
||||
// Add "m.relates_to" data from e2e event to the unencrypted event
|
||||
// TODO
|
||||
//if (getWireContent().getAsJsonObject().has("m.relates_to")) {
|
||||
// mClearEvent!!.getContentAsJsonObject()
|
||||
// clearEvent!!.getContentAsJsonObject()
|
||||
// .add("m.relates_to", getWireContent().getAsJsonObject().get("m.relates_to"))
|
||||
//}
|
||||
} catch (e: Exception) {
|
||||
@ -193,7 +193,7 @@ data class Event(
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the event type
|
||||
* @return the event content
|
||||
*/
|
||||
fun getClearContent(): Content? {
|
||||
return mClearEvent?.content ?: content
|
||||
|
@ -22,44 +22,40 @@ import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.Looper
|
||||
|
||||
private const val THREAD_ENCRYPT_NAME = "Crypto_Encrypt_Thread"
|
||||
private const val THREAD_DECRYPT_NAME = "Crypto_Decrypt_Thread"
|
||||
private const val THREAD_CRYPTO_NAME = "Crypto_Thread"
|
||||
|
||||
// TODO Remove and replace by Task
|
||||
internal object CryptoAsyncHelper {
|
||||
|
||||
private var uiHandler: Handler? = null
|
||||
private var decryptBackgroundHandler: Handler? = null
|
||||
private var encryptBackgroundHandler: Handler? = null
|
||||
private var cryptoBackgroundHandler: Handler? = null
|
||||
|
||||
fun getUiHandler(): Handler {
|
||||
return uiHandler
|
||||
?: Handler(Looper.getMainLooper())
|
||||
.also { uiHandler = it }
|
||||
?: Handler(Looper.getMainLooper())
|
||||
.also { uiHandler = it }
|
||||
}
|
||||
|
||||
|
||||
fun getDecryptBackgroundHandler(): Handler {
|
||||
return decryptBackgroundHandler
|
||||
?: createDecryptBackgroundHandler()
|
||||
.also { decryptBackgroundHandler = it }
|
||||
return getCryptoBackgroundHandler()
|
||||
}
|
||||
|
||||
fun getEncryptBackgroundHandler(): Handler {
|
||||
return encryptBackgroundHandler
|
||||
?: createEncryptBackgroundHandler()
|
||||
.also { encryptBackgroundHandler = it }
|
||||
return getCryptoBackgroundHandler()
|
||||
}
|
||||
|
||||
private fun createDecryptBackgroundHandler(): Handler {
|
||||
val handlerThread = HandlerThread(THREAD_DECRYPT_NAME)
|
||||
private fun getCryptoBackgroundHandler(): Handler {
|
||||
return cryptoBackgroundHandler
|
||||
?: createCryptoBackgroundHandler()
|
||||
.also { cryptoBackgroundHandler = it }
|
||||
}
|
||||
|
||||
private fun createCryptoBackgroundHandler(): Handler {
|
||||
val handlerThread = HandlerThread(THREAD_CRYPTO_NAME)
|
||||
handlerThread.start()
|
||||
return Handler(handlerThread.looper)
|
||||
}
|
||||
|
||||
private fun createEncryptBackgroundHandler(): Handler {
|
||||
val handlerThread = HandlerThread(THREAD_ENCRYPT_NAME)
|
||||
handlerThread.start()
|
||||
return Handler(handlerThread.looper)
|
||||
}
|
||||
|
||||
}
|
@ -49,7 +49,6 @@ import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
|
||||
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
||||
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.MXEncryptEventContentResult
|
||||
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.model.event.RoomKeyContent
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
|
||||
@ -488,8 +487,8 @@ internal class CryptoManager(
|
||||
cryptoStore.storeRoomAlgorithm(roomId, algorithm!!)
|
||||
|
||||
val alg: IMXEncrypting = when (algorithm) {
|
||||
MXCRYPTO_ALGORITHM_MEGOLM -> megolmEncryptionFactory.instantiate(roomId)
|
||||
else -> olmEncryptionFactory.instantiate(roomId)
|
||||
MXCRYPTO_ALGORITHM_MEGOLM -> megolmEncryptionFactory.create(roomId)
|
||||
else -> olmEncryptionFactory.create(roomId)
|
||||
}
|
||||
|
||||
synchronized(roomEncryptors) {
|
||||
@ -544,20 +543,6 @@ internal class CryptoManager(
|
||||
return if (null != map) ArrayList(map.values) else ArrayList()
|
||||
}
|
||||
|
||||
// TODO Remove ?
|
||||
/**
|
||||
* Try to make sure we have established olm sessions for the given devices.
|
||||
* It must be called in getCryptoHandler() thread.
|
||||
* The callback is called in the UI thread.
|
||||
*
|
||||
* @param devicesByUser a map from userid to list of devices.
|
||||
* @param callback the asynchronous callback
|
||||
*/
|
||||
fun ensureOlmSessionsForDevices(devicesByUser: Map<String, List<MXDeviceInfo>>,
|
||||
callback: MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>>?) {
|
||||
ensureOlmSessionsForDevicesAction.handle(devicesByUser, callback)
|
||||
}
|
||||
|
||||
fun isEncryptionEnabledForInvitedUser(): Boolean {
|
||||
return cryptoConfig.mEnableEncryptionForInvitedMembers
|
||||
}
|
||||
@ -602,7 +587,7 @@ internal class CryptoManager(
|
||||
var alg = synchronized(roomEncryptors) {
|
||||
roomEncryptors[roomId]
|
||||
}
|
||||
if (null == alg) {
|
||||
if (alg == null) {
|
||||
val algorithm = getEncryptionAlgorithm(roomId)
|
||||
if (null != algorithm) {
|
||||
if (setEncryptionInRoom(roomId, algorithm, false, userIds)) {
|
||||
@ -613,7 +598,7 @@ internal class CryptoManager(
|
||||
}
|
||||
}
|
||||
|
||||
if (null != alg) {
|
||||
if (alg != null) {
|
||||
val t0 = System.currentTimeMillis()
|
||||
Timber.v("## encryptEventContent() starts")
|
||||
|
||||
@ -739,7 +724,7 @@ internal class CryptoManager(
|
||||
* @param event the encryption event.
|
||||
*/
|
||||
private fun onRoomEncryptionEvent(roomId: String, event: Event) {
|
||||
CoroutineScope(coroutineDispatchers.encryption).launch {
|
||||
CoroutineScope(coroutineDispatchers.crypto).launch {
|
||||
val params = LoadRoomMembersTask.Params(roomId)
|
||||
loadRoomMembersTask
|
||||
.execute(params)
|
||||
|
@ -69,8 +69,8 @@ internal class CryptoModule {
|
||||
// CryptoStore
|
||||
scope(DefaultSession.SCOPE) {
|
||||
RealmCryptoStore(false /* TODO*/,
|
||||
get("CryptoRealmConfiguration"),
|
||||
get()) as IMXCryptoStore
|
||||
get("CryptoRealmConfiguration"),
|
||||
get()) as IMXCryptoStore
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
@ -123,7 +123,7 @@ internal class CryptoModule {
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
EnsureOlmSessionsForDevicesAction(get(), get(), get())
|
||||
EnsureOlmSessionsForDevicesAction(get(), get(), get(), get())
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
@ -146,7 +146,7 @@ internal class CryptoModule {
|
||||
// Factories
|
||||
scope(DefaultSession.SCOPE) {
|
||||
MXMegolmDecryptionFactory(
|
||||
get(), get(), get(), get(), get(), get(), get(), get(), get()
|
||||
get(), get(), get(), get(), get(), get(), get(), get(), get(), get()
|
||||
)
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ internal class CryptoModule {
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
MXOlmEncryptionFactory(
|
||||
get(), get(), get(), get(), get()
|
||||
get(), get(), get(), get(), get(),get()
|
||||
)
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ internal class CryptoModule {
|
||||
|
||||
// Device list
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DeviceListManager(get(), get(), get(), get(), get(), get())
|
||||
DeviceListManager(get(), get(), get(), get(), get(), get(), get())
|
||||
}
|
||||
|
||||
// Crypto tasks
|
||||
|
@ -28,7 +28,9 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.tasks.DownloadKeysForUsersTask
|
||||
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.TaskThread
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
@ -38,6 +40,7 @@ internal class DeviceListManager(private val cryptoStore: IMXCryptoStore,
|
||||
private val syncTokenStore: SyncTokenStore,
|
||||
private val credentials: Credentials,
|
||||
private val downloadKeysForUsersTask: DownloadKeysForUsersTask,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val taskExecutor: TaskExecutor) {
|
||||
|
||||
// keys in progress
|
||||
@ -457,6 +460,7 @@ internal class DeviceListManager(private val cryptoStore: IMXCryptoStore,
|
||||
|
||||
downloadKeysForUsersTask
|
||||
.configureWith(DownloadKeysForUsersTask.Params(filteredUsers, syncTokenStore.getLastToken()))
|
||||
.executeOn(TaskThread.ENCRYPTION)
|
||||
.dispatchTo(object : MatrixCallback<KeysQueryResponse> {
|
||||
override fun onSuccess(data: KeysQueryResponse) {
|
||||
CryptoAsyncHelper.getEncryptBackgroundHandler().post {
|
||||
|
@ -30,34 +30,34 @@ open class IncomingRoomKeyRequest {
|
||||
/**
|
||||
* The user id
|
||||
*/
|
||||
var mUserId: String? = null
|
||||
var userId: String? = null
|
||||
|
||||
/**
|
||||
* The device id
|
||||
*/
|
||||
var mDeviceId: String? = null
|
||||
var deviceId: String? = null
|
||||
|
||||
/**
|
||||
* The request id
|
||||
*/
|
||||
var mRequestId: String? = null
|
||||
var requestId: String? = null
|
||||
|
||||
/**
|
||||
* The request body
|
||||
*/
|
||||
var mRequestBody: RoomKeyRequestBody? = null
|
||||
var requestBody: RoomKeyRequestBody? = null
|
||||
|
||||
/**
|
||||
* The runnable to call to accept to share the keys
|
||||
*/
|
||||
@Transient
|
||||
var mShare: Runnable? = null
|
||||
var share: Runnable? = null
|
||||
|
||||
/**
|
||||
* The runnable to call to ignore the key share request.
|
||||
*/
|
||||
@Transient
|
||||
var mIgnore: Runnable? = null
|
||||
var ignore: Runnable? = null
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -65,11 +65,11 @@ open class IncomingRoomKeyRequest {
|
||||
* @param event the event
|
||||
*/
|
||||
constructor(event: Event) {
|
||||
mUserId = event.sender
|
||||
userId = event.sender
|
||||
val roomKeyShareRequest = event.getClearContent().toModel<RoomKeyShareRequest>()!!
|
||||
mDeviceId = roomKeyShareRequest.requestingDeviceId
|
||||
mRequestId = roomKeyShareRequest.requestId
|
||||
mRequestBody = if (null != roomKeyShareRequest.body) roomKeyShareRequest.body else RoomKeyRequestBody()
|
||||
deviceId = roomKeyShareRequest.requestingDeviceId
|
||||
requestId = roomKeyShareRequest.requestId
|
||||
requestBody = if (null != roomKeyShareRequest.body) roomKeyShareRequest.body else RoomKeyRequestBody()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,6 @@ import im.vector.matrix.android.api.session.events.model.Event
|
||||
class IncomingRoomKeyRequestCancellation(event: Event) : IncomingRoomKeyRequest(event) {
|
||||
|
||||
init {
|
||||
mRequestBody = null
|
||||
requestBody = null
|
||||
}
|
||||
}
|
||||
|
@ -80,13 +80,13 @@ internal class IncomingRoomKeyRequestManager(
|
||||
|
||||
if (null != receivedRoomKeyRequests) {
|
||||
for (request in receivedRoomKeyRequests!!) {
|
||||
val userId = request.mUserId!!
|
||||
val deviceId = request.mDeviceId
|
||||
val body = request.mRequestBody
|
||||
val userId = request.userId!!
|
||||
val deviceId = request.deviceId
|
||||
val body = request.requestBody
|
||||
val roomId = body!!.roomId
|
||||
val alg = body.algorithm
|
||||
|
||||
Timber.v("m.room_key_request from " + userId + ":" + deviceId + " for " + roomId + " / " + body.sessionId + " id " + request.mRequestId)
|
||||
Timber.v("m.room_key_request from " + userId + ":" + deviceId + " for " + roomId + " / " + body.sessionId + " id " + request.requestId)
|
||||
|
||||
if (!TextUtils.equals(mCredentials.userId, userId)) {
|
||||
// TODO: determine if we sent this device the keys already: in
|
||||
@ -119,12 +119,12 @@ internal class IncomingRoomKeyRequestManager(
|
||||
continue
|
||||
}
|
||||
|
||||
request.mShare = Runnable {
|
||||
request.share = Runnable {
|
||||
decryptor.shareKeysWithDevice(request)
|
||||
mCryptoStore.deleteIncomingRoomKeyRequest(request)
|
||||
}
|
||||
|
||||
request.mIgnore = Runnable { mCryptoStore.deleteIncomingRoomKeyRequest(request) }
|
||||
request.ignore = Runnable { mCryptoStore.deleteIncomingRoomKeyRequest(request) }
|
||||
|
||||
// if the device is verified already, share the keys
|
||||
val device = mCryptoStore.getUserDevice(deviceId!!, userId)
|
||||
@ -133,7 +133,7 @@ internal class IncomingRoomKeyRequestManager(
|
||||
if (device.isVerified) {
|
||||
Timber.v("## processReceivedRoomKeyRequests() : device is already verified: sharing keys")
|
||||
mCryptoStore.deleteIncomingRoomKeyRequest(request)
|
||||
request.mShare!!.run()
|
||||
request.share!!.run()
|
||||
continue
|
||||
}
|
||||
|
||||
@ -160,8 +160,8 @@ internal class IncomingRoomKeyRequestManager(
|
||||
|
||||
if (null != receivedRoomKeyRequestCancellations) {
|
||||
for (request in receivedRoomKeyRequestCancellations!!) {
|
||||
Timber.v("## ## processReceivedRoomKeyRequests() : m.room_key_request cancellation for " + request.mUserId
|
||||
+ ":" + request.mDeviceId + " id " + request.mRequestId)
|
||||
Timber.v("## ## processReceivedRoomKeyRequests() : m.room_key_request cancellation for " + request.userId
|
||||
+ ":" + request.deviceId + " id " + request.requestId)
|
||||
|
||||
// we should probably only notify the app of cancellations we told it
|
||||
// about, but we don't currently have a record of that, so we just pass
|
||||
|
@ -28,23 +28,23 @@ data class MXEventDecryptionResult(
|
||||
/**
|
||||
* The plaintext payload for the event (typically containing "type" and "content" fields).
|
||||
*/
|
||||
var mClearEvent: JsonDict? = null,
|
||||
var clearEvent: JsonDict? = null,
|
||||
|
||||
/**
|
||||
* Key owned by the sender of this event.
|
||||
* See MXEvent.senderKey.
|
||||
*/
|
||||
var mSenderCurve25519Key: String? = null,
|
||||
var senderCurve25519Key: String? = null,
|
||||
|
||||
/**
|
||||
* Ed25519 key claimed by the sender of this event.
|
||||
* See MXEvent.claimedEd25519Key.
|
||||
*/
|
||||
var mClaimedEd25519Key: String? = null,
|
||||
var claimedEd25519Key: String? = null,
|
||||
|
||||
/**
|
||||
* List of curve25519 keys involved in telling us about the senderCurve25519Key and
|
||||
* claimedEd25519Key. See MXEvent.forwardingCurve25519KeyChain.
|
||||
*/
|
||||
var mForwardingCurve25519KeyChain: List<String> = ArrayList()
|
||||
var forwardingCurve25519KeyChain: List<String> = ArrayList()
|
||||
)
|
||||
|
@ -32,25 +32,25 @@ import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
internal class OutgoingRoomKeyRequestManager(
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mSendToDeviceTask: SendToDeviceTask,
|
||||
private val mTaskExecutor: TaskExecutor) {
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val sendToDeviceTask: SendToDeviceTask,
|
||||
private val taskExecutor: TaskExecutor) {
|
||||
|
||||
// running
|
||||
private var mClientRunning: Boolean = false
|
||||
private var isClientRunning: Boolean = false
|
||||
|
||||
// transaction counter
|
||||
private var mTxnCtr: Int = 0
|
||||
private var txnCtr: Int = 0
|
||||
|
||||
// sanity check to ensure that we don't end up with two concurrent runs
|
||||
// of mSendOutgoingRoomKeyRequestsTimer
|
||||
private var mSendOutgoingRoomKeyRequestsRunning: Boolean = false
|
||||
// of sendOutgoingRoomKeyRequestsTimer
|
||||
private var sendOutgoingRoomKeyRequestsRunning: Boolean = false
|
||||
|
||||
/**
|
||||
* Called when the client is started. Sets background processes running.
|
||||
*/
|
||||
fun start() {
|
||||
mClientRunning = true
|
||||
isClientRunning = true
|
||||
startTimer()
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
* Called when the client is stopped. Stops any running background processes.
|
||||
*/
|
||||
fun stop() {
|
||||
mClientRunning = false
|
||||
isClientRunning = false
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,7 +67,7 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
* @return {string} a new, unique, transaction id
|
||||
*/
|
||||
private fun makeTxnId(): String {
|
||||
return "m" + System.currentTimeMillis() + "." + mTxnCtr++
|
||||
return "m" + System.currentTimeMillis() + "." + txnCtr++
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +83,7 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
* @param recipients recipients
|
||||
*/
|
||||
fun sendRoomKeyRequest(requestBody: RoomKeyRequestBody?, recipients: List<Map<String, String>>) {
|
||||
val req = mCryptoStore.getOrAddOutgoingRoomKeyRequest(
|
||||
val req = cryptoStore.getOrAddOutgoingRoomKeyRequest(
|
||||
OutgoingRoomKeyRequest(requestBody, recipients, makeTxnId(), OutgoingRoomKeyRequest.RequestState.UNSENT))
|
||||
|
||||
|
||||
@ -117,9 +117,9 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
* @param andResend true to resend the key request
|
||||
*/
|
||||
private fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody, andResend: Boolean) {
|
||||
val req = mCryptoStore.getOutgoingRoomKeyRequest(requestBody)
|
||||
?: // no request was made for this key
|
||||
return
|
||||
val req = cryptoStore.getOutgoingRoomKeyRequest(requestBody)
|
||||
?: // no request was made for this key
|
||||
return
|
||||
|
||||
Timber.v("cancelRoomKeyRequest: requestId: " + req.mRequestId + " state: " + req.mState + " andResend: " + andResend)
|
||||
|
||||
@ -127,7 +127,7 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
// nothing to do here
|
||||
} else if (req.mState === OutgoingRoomKeyRequest.RequestState.UNSENT || req.mState === OutgoingRoomKeyRequest.RequestState.FAILED) {
|
||||
Timber.v("## cancelRoomKeyRequest() : deleting unnecessary room key request for $requestBody")
|
||||
mCryptoStore.deleteOutgoingRoomKeyRequest(req.mRequestId)
|
||||
cryptoStore.deleteOutgoingRoomKeyRequest(req.mRequestId)
|
||||
} else if (req.mState === OutgoingRoomKeyRequest.RequestState.SENT) {
|
||||
if (andResend) {
|
||||
req.mState = OutgoingRoomKeyRequest.RequestState.CANCELLATION_PENDING_AND_WILL_RESEND
|
||||
@ -135,7 +135,7 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
req.mState = OutgoingRoomKeyRequest.RequestState.CANCELLATION_PENDING
|
||||
}
|
||||
req.mCancellationTxnId = makeTxnId()
|
||||
mCryptoStore.updateOutgoingRoomKeyRequest(req)
|
||||
cryptoStore.updateOutgoingRoomKeyRequest(req)
|
||||
sendOutgoingRoomKeyRequestCancellation(req)
|
||||
}
|
||||
}
|
||||
@ -145,17 +145,17 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
* Start the background timer to send queued requests, if the timer isn't already running.
|
||||
*/
|
||||
private fun startTimer() {
|
||||
if (mSendOutgoingRoomKeyRequestsRunning) {
|
||||
if (sendOutgoingRoomKeyRequestsRunning) {
|
||||
return
|
||||
}
|
||||
|
||||
Handler().postDelayed(Runnable {
|
||||
if (mSendOutgoingRoomKeyRequestsRunning) {
|
||||
if (sendOutgoingRoomKeyRequestsRunning) {
|
||||
Timber.v("## startTimer() : RoomKeyRequestSend already in progress!")
|
||||
return@Runnable
|
||||
}
|
||||
|
||||
mSendOutgoingRoomKeyRequestsRunning = true
|
||||
sendOutgoingRoomKeyRequestsRunning = true
|
||||
sendOutgoingRoomKeyRequests()
|
||||
}, SEND_KEY_REQUESTS_DELAY_MS.toLong())
|
||||
}
|
||||
@ -164,20 +164,20 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
// there are no more requests, or there is an error (in which case, the
|
||||
// timer will be restarted before the promise resolves).
|
||||
private fun sendOutgoingRoomKeyRequests() {
|
||||
if (!mClientRunning) {
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
if (!isClientRunning) {
|
||||
sendOutgoingRoomKeyRequestsRunning = false
|
||||
return
|
||||
}
|
||||
|
||||
Timber.v("## sendOutgoingRoomKeyRequests() : Looking for queued outgoing room key requests")
|
||||
val outgoingRoomKeyRequest = mCryptoStore.getOutgoingRoomKeyRequestByState(
|
||||
val outgoingRoomKeyRequest = cryptoStore.getOutgoingRoomKeyRequestByState(
|
||||
HashSet<OutgoingRoomKeyRequest.RequestState>(Arrays.asList<OutgoingRoomKeyRequest.RequestState>(OutgoingRoomKeyRequest.RequestState.UNSENT,
|
||||
OutgoingRoomKeyRequest.RequestState.CANCELLATION_PENDING,
|
||||
OutgoingRoomKeyRequest.RequestState.CANCELLATION_PENDING_AND_WILL_RESEND)))
|
||||
|
||||
if (null == outgoingRoomKeyRequest) {
|
||||
Timber.e("## sendOutgoingRoomKeyRequests() : No more outgoing room key requests")
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
sendOutgoingRoomKeyRequestsRunning = false
|
||||
return
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
+ " from " + request.mRecipients + " id " + request.mRequestId)
|
||||
|
||||
val requestMessage = RoomKeyShareRequest()
|
||||
requestMessage.requestingDeviceId = mCryptoStore.getDeviceId()
|
||||
requestMessage.requestingDeviceId = cryptoStore.getDeviceId()
|
||||
requestMessage.requestId = request.mRequestId
|
||||
requestMessage.body = request.mRequestBody
|
||||
|
||||
@ -208,10 +208,10 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
Timber.v("## sendOutgoingRoomKeyRequest() : Cannot update room key request from UNSENT as it was already updated to " + request.mState)
|
||||
} else {
|
||||
request.mState = state
|
||||
mCryptoStore.updateOutgoingRoomKeyRequest(request)
|
||||
cryptoStore.updateOutgoingRoomKeyRequest(request)
|
||||
}
|
||||
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
sendOutgoingRoomKeyRequestsRunning = false
|
||||
startTimer()
|
||||
}
|
||||
|
||||
@ -238,13 +238,13 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
+ " cancellation id " + request.mCancellationTxnId)
|
||||
|
||||
val roomKeyShareCancellation = RoomKeyShareCancellation()
|
||||
roomKeyShareCancellation.requestingDeviceId = mCryptoStore.getDeviceId()
|
||||
roomKeyShareCancellation.requestingDeviceId = cryptoStore.getDeviceId()
|
||||
roomKeyShareCancellation.requestId = request.mCancellationTxnId
|
||||
|
||||
sendMessageToDevices(roomKeyShareCancellation, request.mRecipients, request.mCancellationTxnId, object : MatrixCallback<Unit> {
|
||||
private fun onDone() {
|
||||
mCryptoStore.deleteOutgoingRoomKeyRequest(request.mRequestId)
|
||||
mSendOutgoingRoomKeyRequestsRunning = false
|
||||
cryptoStore.deleteOutgoingRoomKeyRequest(request.mRequestId)
|
||||
sendOutgoingRoomKeyRequestsRunning = false
|
||||
startTimer()
|
||||
}
|
||||
|
||||
@ -286,9 +286,9 @@ internal class OutgoingRoomKeyRequestManager(
|
||||
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))
|
||||
sendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ROOM_KEY_REQUEST, contentMap, transactionId))
|
||||
.dispatchTo(callback)
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -68,8 +68,8 @@ internal class RoomDecryptorProvider(
|
||||
|
||||
if (decryptingClass) {
|
||||
alg = when (algorithm) {
|
||||
MXCRYPTO_ALGORITHM_MEGOLM -> mMXMegolmDecryptionFactory.instantiate()
|
||||
else -> mMXOlmDecryptionFactory.instantiate()
|
||||
MXCRYPTO_ALGORITHM_MEGOLM -> mMXMegolmDecryptionFactory.create()
|
||||
else -> mMXOlmDecryptionFactory.create()
|
||||
}
|
||||
|
||||
if (null != alg) {
|
||||
|
@ -26,12 +26,14 @@ import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
|
||||
import im.vector.matrix.android.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
internal class EnsureOlmSessionsForDevicesAction(private val mOlmDevice: MXOlmDevice,
|
||||
private val mClaimOneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask,
|
||||
private val mTaskExecutor: TaskExecutor) {
|
||||
internal class EnsureOlmSessionsForDevicesAction(private val olmDevice: MXOlmDevice,
|
||||
private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val taskExecutor: TaskExecutor) {
|
||||
|
||||
|
||||
fun handle(devicesByUser: Map<String, List<MXDeviceInfo>>, callback: MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>>?) {
|
||||
@ -48,7 +50,7 @@ internal class EnsureOlmSessionsForDevicesAction(private val mOlmDevice: MXOlmDe
|
||||
val deviceId = deviceInfo.deviceId
|
||||
val key = deviceInfo.identityKey()
|
||||
|
||||
val sessionId = mOlmDevice.getSessionId(key!!)
|
||||
val sessionId = olmDevice.getSessionId(key!!)
|
||||
|
||||
if (TextUtils.isEmpty(sessionId)) {
|
||||
devicesWithoutSession.add(deviceInfo)
|
||||
@ -81,7 +83,8 @@ internal class EnsureOlmSessionsForDevicesAction(private val mOlmDevice: MXOlmDe
|
||||
|
||||
Timber.v("## claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim")
|
||||
|
||||
mClaimOneTimeKeysForUsersDeviceTask
|
||||
|
||||
oneTimeKeysForUsersDeviceTask
|
||||
.configureWith(ClaimOneTimeKeysForUsersDeviceTask.Params(usersDevicesToClaim))
|
||||
.dispatchTo(object : MatrixCallback<MXUsersDevicesMap<MXKey>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXKey>) {
|
||||
@ -137,7 +140,7 @@ internal class EnsureOlmSessionsForDevicesAction(private val mOlmDevice: MXOlmDe
|
||||
callback?.onFailure(failure)
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
|
||||
@ -153,7 +156,7 @@ internal class EnsureOlmSessionsForDevicesAction(private val mOlmDevice: MXOlmDe
|
||||
var errorMessage: String? = null
|
||||
|
||||
try {
|
||||
mOlmDevice.verifySignature(deviceInfo.fingerprint()!!, oneTimeKey.signalableJSONDictionary(), signature)
|
||||
olmDevice.verifySignature(deviceInfo.fingerprint()!!, oneTimeKey.signalableJSONDictionary(), signature)
|
||||
isVerified = true
|
||||
} catch (e: Exception) {
|
||||
errorMessage = e.message
|
||||
@ -161,7 +164,7 @@ internal class EnsureOlmSessionsForDevicesAction(private val mOlmDevice: MXOlmDe
|
||||
|
||||
// Check one-time key signature
|
||||
if (isVerified) {
|
||||
sessionId = mOlmDevice.createOutboundSession(deviceInfo.identityKey()!!, oneTimeKey.value)
|
||||
sessionId = olmDevice.createOutboundSession(deviceInfo.identityKey()!!, oneTimeKey.value)
|
||||
|
||||
if (!TextUtils.isEmpty(sessionId)) {
|
||||
Timber.v("## verifyKeyAndStartSession() : Started new sessionid " + sessionId
|
||||
|
@ -26,9 +26,9 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
internal class EnsureOlmSessionsForUsersAction(private val mOlmDevice: MXOlmDevice,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mEnsureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction) {
|
||||
internal class EnsureOlmSessionsForUsersAction(private val olmDevice: MXOlmDevice,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction) {
|
||||
|
||||
/**
|
||||
* Try to make sure we have established olm sessions for the given users.
|
||||
@ -46,12 +46,12 @@ internal class EnsureOlmSessionsForUsersAction(private val mOlmDevice: MXOlmDevi
|
||||
for (userId in users) {
|
||||
devicesByUser[userId] = ArrayList()
|
||||
|
||||
val devices = mCryptoStore.getUserDevices(userId)?.values ?: emptyList()
|
||||
val devices = cryptoStore.getUserDevices(userId)?.values ?: emptyList()
|
||||
|
||||
for (device in devices) {
|
||||
val key = device.identityKey()
|
||||
|
||||
if (TextUtils.equals(key, mOlmDevice.deviceCurve25519Key)) {
|
||||
if (TextUtils.equals(key, olmDevice.deviceCurve25519Key)) {
|
||||
// Don't bother setting up session to ourself
|
||||
continue
|
||||
}
|
||||
@ -65,6 +65,6 @@ internal class EnsureOlmSessionsForUsersAction(private val mOlmDevice: MXOlmDevi
|
||||
}
|
||||
}
|
||||
|
||||
mEnsureOlmSessionsForDevicesAction.handle(devicesByUser, callback)
|
||||
ensureOlmSessionsForDevicesAction.handle(devicesByUser, callback)
|
||||
}
|
||||
}
|
@ -24,7 +24,13 @@ import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||
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.internal.crypto.*
|
||||
import im.vector.matrix.android.internal.crypto.CryptoAsyncHelper
|
||||
import im.vector.matrix.android.internal.crypto.DeviceListManager
|
||||
import im.vector.matrix.android.internal.crypto.IncomingRoomKeyRequest
|
||||
import im.vector.matrix.android.internal.crypto.MXDecryptionException
|
||||
import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
|
||||
import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||
import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequestManager
|
||||
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
|
||||
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
|
||||
import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting
|
||||
@ -39,27 +45,28 @@ import im.vector.matrix.android.internal.crypto.model.rest.ForwardedRoomKeyConte
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
||||
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.task.configureWith
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
private val mOlmDevice: MXOlmDevice,
|
||||
private val mDeviceListManager: DeviceListManager,
|
||||
private val mOutgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
|
||||
private val mMessageEncrypter: MessageEncrypter,
|
||||
private val mEnsureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mSendToDeviceTask: SendToDeviceTask,
|
||||
private val mTaskExecutor: TaskExecutor)
|
||||
internal class MXMegolmDecryption(private val credentials: Credentials,
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
|
||||
private val messageEncrypter: MessageEncrypter,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val sendToDeviceTask: SendToDeviceTask,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers)
|
||||
: 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<String /* senderKey|sessionId */, MutableMap<String /* timelineId */, MutableList<Event>>> = HashMap()
|
||||
private var pendingEvents: MutableMap<String /* senderKey|sessionId */, MutableMap<String /* timelineId */, MutableList<Event>>> = HashMap()
|
||||
|
||||
@Throws(MXDecryptionException::class)
|
||||
override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult? {
|
||||
@ -72,7 +79,7 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
val encryptedEventContent = event.content.toModel<EncryptedEventContent>()!!
|
||||
if (TextUtils.isEmpty(encryptedEventContent.senderKey) || TextUtils.isEmpty(encryptedEventContent.sessionId) || TextUtils.isEmpty(encryptedEventContent.ciphertext)) {
|
||||
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_FIELDS_ERROR_CODE,
|
||||
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_FIELDS_REASON))
|
||||
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_FIELDS_REASON))
|
||||
}
|
||||
|
||||
var eventDecryptionResult: MXEventDecryptionResult? = null
|
||||
@ -80,24 +87,24 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
var decryptGroupMessageResult: MXDecryptionResult? = null
|
||||
|
||||
try {
|
||||
decryptGroupMessageResult = mOlmDevice.decryptGroupMessage(encryptedEventContent.ciphertext!!, event.roomId!!, timeline, encryptedEventContent.sessionId!!, encryptedEventContent.senderKey!!)
|
||||
decryptGroupMessageResult = olmDevice.decryptGroupMessage(encryptedEventContent.ciphertext!!, event.roomId!!, timeline, encryptedEventContent.sessionId!!, encryptedEventContent.senderKey!!)
|
||||
} catch (e: MXDecryptionException) {
|
||||
cryptoError = e.cryptoError
|
||||
}
|
||||
|
||||
// the decryption succeeds
|
||||
if (null != decryptGroupMessageResult && null != decryptGroupMessageResult.mPayload && null == cryptoError) {
|
||||
if (decryptGroupMessageResult?.mPayload != null && cryptoError == null) {
|
||||
eventDecryptionResult = MXEventDecryptionResult()
|
||||
|
||||
eventDecryptionResult.mClearEvent = decryptGroupMessageResult.mPayload
|
||||
eventDecryptionResult.mSenderCurve25519Key = decryptGroupMessageResult.mSenderKey
|
||||
eventDecryptionResult.clearEvent = decryptGroupMessageResult.mPayload
|
||||
eventDecryptionResult.senderCurve25519Key = decryptGroupMessageResult.mSenderKey
|
||||
|
||||
if (null != decryptGroupMessageResult.mKeysClaimed) {
|
||||
eventDecryptionResult.mClaimedEd25519Key = decryptGroupMessageResult.mKeysClaimed!!["ed25519"]
|
||||
eventDecryptionResult.claimedEd25519Key = decryptGroupMessageResult.mKeysClaimed!!["ed25519"]
|
||||
}
|
||||
|
||||
eventDecryptionResult.mForwardingCurve25519KeyChain = decryptGroupMessageResult.mForwardingCurve25519KeyChain!!
|
||||
} else if (null != cryptoError) {
|
||||
eventDecryptionResult.forwardingCurve25519KeyChain = decryptGroupMessageResult.mForwardingCurve25519KeyChain!!
|
||||
} else if (cryptoError != null) {
|
||||
if (cryptoError.isOlmError) {
|
||||
if (TextUtils.equals("UNKNOWN_MESSAGE_INDEX", cryptoError.message)) {
|
||||
addEventToPendingList(event, timeline)
|
||||
@ -120,7 +127,6 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
requestKeysForEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
throw MXDecryptionException(cryptoError)
|
||||
}
|
||||
|
||||
@ -141,11 +147,11 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
val recipients = ArrayList<Map<String, String>>()
|
||||
|
||||
val selfMap = HashMap<String, String>()
|
||||
selfMap["userId"] = mCredentials.userId // TODO Replace this hard coded keys (see OutgoingRoomKeyRequestManager)
|
||||
selfMap["userId"] = credentials.userId // TODO Replace this hard coded keys (see OutgoingRoomKeyRequestManager)
|
||||
selfMap["deviceId"] = "*"
|
||||
recipients.add(selfMap)
|
||||
|
||||
if (!TextUtils.equals(sender, mCredentials.userId)) {
|
||||
if (!TextUtils.equals(sender, credentials.userId)) {
|
||||
val senderMap = HashMap<String, String>()
|
||||
senderMap["userId"] = sender
|
||||
senderMap["deviceId"] = encryptedEventContent.deviceId!!
|
||||
@ -159,7 +165,7 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
requestBody.senderKey = encryptedEventContent.senderKey
|
||||
requestBody.sessionId = encryptedEventContent.sessionId
|
||||
|
||||
mOutgoingRoomKeyRequestManager.sendRoomKeyRequest(requestBody, recipients)
|
||||
outgoingRoomKeyRequestManager.sendRoomKeyRequest(requestBody, recipients)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,17 +180,17 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
|
||||
val k = "${encryptedEventContent.senderKey}|${encryptedEventContent.sessionId}"
|
||||
|
||||
if (!mPendingEvents.containsKey(k)) {
|
||||
mPendingEvents[k] = HashMap()
|
||||
if (!pendingEvents.containsKey(k)) {
|
||||
pendingEvents[k] = HashMap()
|
||||
}
|
||||
|
||||
if (!mPendingEvents[k]!!.containsKey(timelineId)) {
|
||||
mPendingEvents[k]!!.put(timelineId, ArrayList<Event>())
|
||||
if (!pendingEvents[k]!!.containsKey(timelineId)) {
|
||||
pendingEvents[k]!!.put(timelineId, ArrayList<Event>())
|
||||
}
|
||||
|
||||
if (mPendingEvents[k]!![timelineId]!!.indexOf(event) < 0) {
|
||||
if (pendingEvents[k]!![timelineId]!!.indexOf(event) < 0) {
|
||||
Timber.v("## addEventToPendingList() : add Event " + event.eventId + " in room id " + event.roomId)
|
||||
mPendingEvents[k]!![timelineId]!!.add(event)
|
||||
pendingEvents[k]!![timelineId]!!.add(event)
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,7 +214,7 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
|
||||
if (event.getClearType() == EventType.FORWARDED_ROOM_KEY) {
|
||||
Timber.v("## onRoomKeyEvent(), forward adding key : roomId " + roomKeyContent.roomId + " sessionId " + roomKeyContent.sessionId
|
||||
+ " sessionKey " + roomKeyContent.sessionKey) // from " + event);
|
||||
+ " sessionKey " + roomKeyContent.sessionKey) // from " + event);
|
||||
val forwardedRoomKeyContent = event.getClearContent().toModel<ForwardedRoomKeyContent>()!!
|
||||
|
||||
if (null == forwardedRoomKeyContent.forwardingCurve25519KeyChain) {
|
||||
@ -234,7 +240,7 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
keysClaimed["ed25519"] = forwardedRoomKeyContent.senderClaimedEd25519Key!!
|
||||
} else {
|
||||
Timber.v("## onRoomKeyEvent(), Adding key : roomId " + roomKeyContent.roomId + " sessionId " + roomKeyContent.sessionId
|
||||
+ " sessionKey " + roomKeyContent.sessionKey) // from " + event);
|
||||
+ " sessionKey " + roomKeyContent.sessionKey) // from " + event);
|
||||
|
||||
if (null == senderKey) {
|
||||
Timber.e("## onRoomKeyEvent() : key event has no sender key (not encrypted?)")
|
||||
@ -245,7 +251,7 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
keysClaimed = event.getKeysClaimed().toMutableMap()
|
||||
}
|
||||
|
||||
val added = mOlmDevice.addInboundGroupSession(roomKeyContent.sessionId!!, roomKeyContent.sessionKey!!, roomKeyContent.roomId!!, senderKey, forwarding_curve25519_key_chain!!, keysClaimed, exportFormat)
|
||||
val added = olmDevice.addInboundGroupSession(roomKeyContent.sessionId!!, roomKeyContent.sessionKey!!, roomKeyContent.roomId!!, senderKey, forwarding_curve25519_key_chain!!, keysClaimed, exportFormat)
|
||||
|
||||
if (added) {
|
||||
keysBackup.maybeBackupKeys()
|
||||
@ -257,7 +263,7 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
content.sessionId = roomKeyContent.sessionId
|
||||
content.senderKey = senderKey
|
||||
|
||||
mOutgoingRoomKeyRequestManager.cancelRoomKeyRequest(content)
|
||||
outgoingRoomKeyRequestManager.cancelRoomKeyRequest(content)
|
||||
|
||||
onNewSession(senderKey, roomKeyContent.sessionId!!)
|
||||
}
|
||||
@ -272,11 +278,11 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
override fun onNewSession(senderKey: String, sessionId: String) {
|
||||
val k = "$senderKey|$sessionId"
|
||||
|
||||
val pending = mPendingEvents[k]
|
||||
val pending = pendingEvents[k]
|
||||
|
||||
if (null != pending) {
|
||||
// Have another go at decrypting events sent with this session.
|
||||
mPendingEvents.remove(k)
|
||||
pendingEvents.remove(k)
|
||||
|
||||
val timelineIds = pending.keys
|
||||
|
||||
@ -307,81 +313,81 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials,
|
||||
}
|
||||
|
||||
override fun hasKeysForKeyRequest(request: IncomingRoomKeyRequest): Boolean {
|
||||
return (null != request.mRequestBody
|
||||
&& mOlmDevice.hasInboundSessionKeys(request.mRequestBody!!.roomId!!, request.mRequestBody!!.senderKey!!, request.mRequestBody!!.sessionId!!))
|
||||
return (null != request.requestBody
|
||||
&& olmDevice.hasInboundSessionKeys(request.requestBody!!.roomId!!, request.requestBody!!.senderKey!!, request.requestBody!!.sessionId!!))
|
||||
}
|
||||
|
||||
override fun shareKeysWithDevice(request: IncomingRoomKeyRequest) {
|
||||
// sanity checks
|
||||
if (request.mRequestBody == null) {
|
||||
if (request.requestBody == null) {
|
||||
return
|
||||
}
|
||||
val userId = request.userId!!
|
||||
CoroutineScope(coroutineDispatchers.crypto).launch {
|
||||
deviceListManager.downloadKeys(listOf(userId), false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||
val deviceId = request.deviceId
|
||||
val deviceInfo = cryptoStore.getUserDevice(deviceId!!, userId)
|
||||
|
||||
val userId = request.mUserId!!
|
||||
if (null != deviceInfo) {
|
||||
val body = request.requestBody
|
||||
|
||||
mDeviceListManager.downloadKeys(listOf(userId), false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||
val deviceId = request.mDeviceId
|
||||
val deviceInfo = mCryptoStore.getUserDevice(deviceId!!, userId)
|
||||
val devicesByUser = HashMap<String, List<MXDeviceInfo>>()
|
||||
devicesByUser[userId] = ArrayList(Arrays.asList(deviceInfo))
|
||||
|
||||
if (null != deviceInfo) {
|
||||
val body = request.mRequestBody
|
||||
ensureOlmSessionsForDevicesAction.handle(devicesByUser, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXOlmSessionResult>) {
|
||||
val olmSessionResult = data.getObject(deviceId, userId)
|
||||
|
||||
val devicesByUser = HashMap<String, List<MXDeviceInfo>>()
|
||||
devicesByUser[userId] = ArrayList(Arrays.asList(deviceInfo))
|
||||
if (olmSessionResult?.mSessionId == null) {
|
||||
// no session with this device, probably because there
|
||||
// were no one-time keys.
|
||||
//
|
||||
// ensureOlmSessionsForUsers has already done the logging,
|
||||
// so just skip it.
|
||||
return
|
||||
}
|
||||
Timber.v("## shareKeysWithDevice() : sharing keys for session " + body!!.senderKey + "|" + body.sessionId
|
||||
+ " with device " + userId + ":" + deviceId)
|
||||
val inboundGroupSession = olmDevice.getInboundGroupSession(body.sessionId, body.senderKey, body.roomId)
|
||||
|
||||
mEnsureOlmSessionsForDevicesAction.handle(devicesByUser, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXOlmSessionResult>) {
|
||||
val olmSessionResult = data.getObject(deviceId, userId)
|
||||
val payloadJson = HashMap<String, Any>()
|
||||
payloadJson["type"] = EventType.FORWARDED_ROOM_KEY
|
||||
payloadJson["content"] = inboundGroupSession!!.exportKeys()!!
|
||||
|
||||
if (null == olmSessionResult || null == olmSessionResult.mSessionId) {
|
||||
// no session with this device, probably because there
|
||||
// were no one-time keys.
|
||||
//
|
||||
// ensureOlmSessionsForUsers has already done the logging,
|
||||
// so just skip it.
|
||||
return
|
||||
val encodedPayload = messageEncrypter.encryptMessage(payloadJson, Arrays.asList(deviceInfo))
|
||||
val sendToDeviceMap = MXUsersDevicesMap<Any>()
|
||||
sendToDeviceMap.setObject(encodedPayload, userId, deviceId)
|
||||
Timber.v("## shareKeysWithDevice() : sending to $userId:$deviceId")
|
||||
|
||||
val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
|
||||
sendToDeviceTask
|
||||
.execute(sendToDeviceParams)
|
||||
.fold(
|
||||
{
|
||||
Timber.e(it, "## shareKeysWithDevice() : sendToDevice $userId:$deviceId failed")
|
||||
}
|
||||
, {
|
||||
Timber.v("## shareKeysWithDevice() : sent to $userId:$deviceId")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Timber.v("## shareKeysWithDevice() : sharing keys for session " + body!!.senderKey + "|" + body.sessionId
|
||||
+ " with device " + userId + ":" + deviceId)
|
||||
|
||||
val inboundGroupSession = mOlmDevice.getInboundGroupSession(body.sessionId, body.senderKey, body.roomId)
|
||||
|
||||
val payloadJson = HashMap<String, Any>()
|
||||
payloadJson["type"] = EventType.FORWARDED_ROOM_KEY
|
||||
payloadJson["content"] = inboundGroupSession!!.exportKeys()!!
|
||||
|
||||
val encodedPayload = mMessageEncrypter.encryptMessage(payloadJson, Arrays.asList(deviceInfo))
|
||||
val sendToDeviceMap = MXUsersDevicesMap<Any>()
|
||||
sendToDeviceMap.setObject(encodedPayload, userId, deviceId)
|
||||
|
||||
Timber.v("## shareKeysWithDevice() : sending to $userId:$deviceId")
|
||||
mSendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap))
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.v("## shareKeysWithDevice() : sent to $userId:$deviceId")
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## shareKeysWithDevice() : sendToDevice $userId:$deviceId failed")
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## shareKeysWithDevice() : ensureOlmSessionsForDevices $userId:$deviceId failed")
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Timber.e("## shareKeysWithDevice() : ensureOlmSessionsForDevices $userId:$deviceId not found")
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## shareKeysWithDevice() : ensureOlmSessionsForDevices $userId:$deviceId failed")
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Timber.e("## shareKeysWithDevice() : ensureOlmSessionsForDevices $userId:$deviceId not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## shareKeysWithDevice() : downloadKeys $userId failed")
|
||||
}
|
||||
})
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "## shareKeysWithDevice() : downloadKeys $userId failed")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
|
||||
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.MatrixCoroutineDispatchers
|
||||
|
||||
internal class MXMegolmDecryptionFactory(private val mCredentials: Credentials,
|
||||
private val mOlmDevice: MXOlmDevice,
|
||||
@ -34,9 +35,10 @@ internal class MXMegolmDecryptionFactory(private val mCredentials: Credentials,
|
||||
private val mEnsureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mSendToDeviceTask: SendToDeviceTask,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val mTaskExecutor: TaskExecutor) {
|
||||
|
||||
fun instantiate(): MXMegolmDecryption {
|
||||
fun create(): MXMegolmDecryption {
|
||||
return MXMegolmDecryption(
|
||||
mCredentials,
|
||||
mOlmDevice,
|
||||
@ -46,6 +48,6 @@ internal class MXMegolmDecryptionFactory(private val mCredentials: Credentials,
|
||||
mEnsureOlmSessionsForDevicesAction,
|
||||
mCryptoStore,
|
||||
mSendToDeviceTask,
|
||||
mTaskExecutor)
|
||||
coroutineDispatchers)
|
||||
}
|
||||
}
|
@ -49,36 +49,36 @@ import java.util.*
|
||||
|
||||
internal class MXMegolmEncryption(
|
||||
// The id of the room we will be sending to.
|
||||
private var mRoomId: String,
|
||||
private var roomId: String,
|
||||
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val mKeysBackup: KeysBackup,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mDeviceListManager: DeviceListManager,
|
||||
private val mEnsureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val mCredentials: Credentials,
|
||||
private val mSendToDeviceTask: SendToDeviceTask,
|
||||
private val mTaskExecutor: TaskExecutor,
|
||||
private val mMessageEncrypter: MessageEncrypter,
|
||||
private val mWarnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository
|
||||
private val keysBackup: KeysBackup,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
private val credentials: Credentials,
|
||||
private val sendToDeviceTask: SendToDeviceTask,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val messageEncrypter: MessageEncrypter,
|
||||
private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository
|
||||
) : IMXEncrypting {
|
||||
|
||||
|
||||
// OutboundSessionInfo. Null if we haven't yet started setting one up. Note
|
||||
// that even if this is non-null, it may not be ready for use (in which
|
||||
// case outboundSession.shareOperation will be non-null.)
|
||||
private var mOutboundSession: MXOutboundSessionInfo? = null
|
||||
private var outboundSession: MXOutboundSessionInfo? = null
|
||||
|
||||
// true when there is an HTTP operation in progress
|
||||
private var mShareOperationIsProgress: Boolean = false
|
||||
private var shareOperationIsProgress: Boolean = false
|
||||
|
||||
private val mPendingEncryptions = ArrayList<MXQueuedEncryption>()
|
||||
private val _pendingEncryptions = ArrayList<MXQueuedEncryption>()
|
||||
|
||||
// Default rotation periods
|
||||
// TODO: Make it configurable via parameters
|
||||
// Session rotation periods
|
||||
private var mSessionRotationPeriodMsgs: Int = 100
|
||||
private var mSessionRotationPeriodMs: Int = 7 * 24 * 3600 * 1000
|
||||
private var sessionRotationPeriodMsgs: Int = 100
|
||||
private var sessionRotationPeriodMs: Int = 7 * 24 * 3600 * 1000
|
||||
|
||||
/**
|
||||
* @return a snapshot of the pending encryptions
|
||||
@ -86,11 +86,9 @@ internal class MXMegolmEncryption(
|
||||
private val pendingEncryptions: List<MXQueuedEncryption>
|
||||
get() {
|
||||
val list = ArrayList<MXQueuedEncryption>()
|
||||
|
||||
synchronized(mPendingEncryptions) {
|
||||
list.addAll(mPendingEncryptions)
|
||||
synchronized(_pendingEncryptions) {
|
||||
list.addAll(_pendingEncryptions)
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
@ -102,12 +100,12 @@ internal class MXMegolmEncryption(
|
||||
// It will be processed when everything is set up
|
||||
val queuedEncryption = MXQueuedEncryption()
|
||||
|
||||
queuedEncryption.mEventContent = eventContent
|
||||
queuedEncryption.mEventType = eventType
|
||||
queuedEncryption.mApiCallback = callback
|
||||
queuedEncryption.eventContent = eventContent
|
||||
queuedEncryption.eventType = eventType
|
||||
queuedEncryption.apiCallback = callback
|
||||
|
||||
synchronized(mPendingEncryptions) {
|
||||
mPendingEncryptions.add(queuedEncryption)
|
||||
synchronized(_pendingEncryptions) {
|
||||
_pendingEncryptions.add(queuedEncryption)
|
||||
}
|
||||
|
||||
val t0 = System.currentTimeMillis()
|
||||
@ -124,11 +122,11 @@ internal class MXMegolmEncryption(
|
||||
val queuedEncryptions = pendingEncryptions
|
||||
|
||||
for (queuedEncryption in queuedEncryptions) {
|
||||
queuedEncryption.mApiCallback?.onFailure(failure)
|
||||
queuedEncryption.apiCallback?.onFailure(failure)
|
||||
}
|
||||
|
||||
synchronized(mPendingEncryptions) {
|
||||
mPendingEncryptions.removeAll(queuedEncryptions)
|
||||
synchronized(_pendingEncryptions) {
|
||||
_pendingEncryptions.removeAll(queuedEncryptions)
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,10 +160,10 @@ internal class MXMegolmEncryption(
|
||||
val keysClaimedMap = HashMap<String, String>()
|
||||
keysClaimedMap["ed25519"] = olmDevice.deviceEd25519Key!!
|
||||
|
||||
olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, mRoomId, olmDevice.deviceCurve25519Key!!,
|
||||
ArrayList(), keysClaimedMap, false)
|
||||
olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, roomId, olmDevice.deviceCurve25519Key!!,
|
||||
ArrayList(), keysClaimedMap, false)
|
||||
|
||||
mKeysBackup.maybeBackupKeys()
|
||||
keysBackup.maybeBackupKeys()
|
||||
|
||||
return MXOutboundSessionInfo(sessionId)
|
||||
}
|
||||
@ -177,18 +175,18 @@ internal class MXMegolmEncryption(
|
||||
* @param callback the asynchronous callback.
|
||||
*/
|
||||
private fun ensureOutboundSession(devicesInRoom: MXUsersDevicesMap<MXDeviceInfo>, callback: MatrixCallback<MXOutboundSessionInfo>?) {
|
||||
var session = mOutboundSession
|
||||
var session = outboundSession
|
||||
|
||||
if (null == session
|
||||
// Need to make a brand new session?
|
||||
|| session.needsRotation(mSessionRotationPeriodMsgs, mSessionRotationPeriodMs)
|
||||
// Determine if we have shared with anyone we shouldn't have
|
||||
|| session.sharedWithTooManyDevices(devicesInRoom)) {
|
||||
// Need to make a brand new session?
|
||||
|| session.needsRotation(sessionRotationPeriodMsgs, sessionRotationPeriodMs)
|
||||
// Determine if we have shared with anyone we shouldn't have
|
||||
|| session.sharedWithTooManyDevices(devicesInRoom)) {
|
||||
session = prepareNewSessionInRoom()
|
||||
mOutboundSession = session
|
||||
outboundSession = session
|
||||
}
|
||||
|
||||
if (mShareOperationIsProgress) {
|
||||
if (shareOperationIsProgress) {
|
||||
Timber.v("## ensureOutboundSessionInRoom() : already in progress")
|
||||
// Key share already in progress
|
||||
return
|
||||
@ -218,7 +216,7 @@ internal class MXMegolmEncryption(
|
||||
|
||||
shareKey(fSession, shareMap, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
mShareOperationIsProgress = false
|
||||
shareOperationIsProgress = false
|
||||
callback?.onSuccess(fSession)
|
||||
}
|
||||
|
||||
@ -226,7 +224,7 @@ internal class MXMegolmEncryption(
|
||||
Timber.e("## ensureOutboundSessionInRoom() : shareKey onFailure")
|
||||
|
||||
callback?.onFailure(failure)
|
||||
mShareOperationIsProgress = false
|
||||
shareOperationIsProgress = false
|
||||
}
|
||||
})
|
||||
|
||||
@ -303,7 +301,7 @@ internal class MXMegolmEncryption(
|
||||
|
||||
val submap = HashMap<String, Any>()
|
||||
submap["algorithm"] = MXCRYPTO_ALGORITHM_MEGOLM
|
||||
submap["room_id"] = mRoomId
|
||||
submap["room_id"] = roomId
|
||||
submap["session_id"] = session.mSessionId
|
||||
submap["session_key"] = sessionKey!!
|
||||
submap["chain_index"] = chainIndex
|
||||
@ -315,10 +313,10 @@ internal class MXMegolmEncryption(
|
||||
val t0 = System.currentTimeMillis()
|
||||
Timber.v("## shareUserDevicesKey() : starts")
|
||||
|
||||
mEnsureOlmSessionsForDevicesAction.handle(devicesByUser, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
ensureOlmSessionsForDevicesAction.handle(devicesByUser, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXOlmSessionResult>) {
|
||||
Timber.v("## shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after "
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
val contentMap = MXUsersDevicesMap<Any>()
|
||||
|
||||
var haveTargets = false
|
||||
@ -348,7 +346,7 @@ internal class MXMegolmEncryption(
|
||||
|
||||
Timber.v("## shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
|
||||
//noinspection ArraysAsListWithZeroOrOneArgument,ArraysAsListWithZeroOrOneArgument
|
||||
contentMap.setObject(mMessageEncrypter.encryptMessage(payload, Arrays.asList(sessionResult.mDevice)), userId, deviceID)
|
||||
contentMap.setObject(messageEncrypter.encryptMessage(payload, Arrays.asList(sessionResult.mDevice)), userId, deviceID)
|
||||
haveTargets = true
|
||||
}
|
||||
}
|
||||
@ -357,11 +355,11 @@ internal class MXMegolmEncryption(
|
||||
val t0 = System.currentTimeMillis()
|
||||
Timber.v("## shareUserDevicesKey() : has target")
|
||||
|
||||
mSendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ENCRYPTED, contentMap))
|
||||
sendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ENCRYPTED, contentMap))
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.v("## shareUserDevicesKey() : sendToDevice succeeds after "
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
+ (System.currentTimeMillis() - t0) + " ms")
|
||||
|
||||
// Add the devices we have shared with to session.sharedWithDevices.
|
||||
// we deliberately iterate over devicesByUser (ie, the devices we
|
||||
@ -387,7 +385,7 @@ internal class MXMegolmEncryption(
|
||||
callback?.onFailure(failure)
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
} else {
|
||||
Timber.v("## shareUserDevicesKey() : no need to sharekey")
|
||||
|
||||
@ -416,9 +414,9 @@ internal class MXMegolmEncryption(
|
||||
for (queuedEncryption in queuedEncryptions) {
|
||||
val payloadJson = HashMap<String, Any>()
|
||||
|
||||
payloadJson["room_id"] = mRoomId
|
||||
payloadJson["type"] = queuedEncryption.mEventType!!
|
||||
payloadJson["content"] = queuedEncryption.mEventContent!!
|
||||
payloadJson["room_id"] = roomId
|
||||
payloadJson["type"] = queuedEncryption.eventType!!
|
||||
payloadJson["content"] = queuedEncryption.eventContent!!
|
||||
|
||||
// Get canonical Json from
|
||||
|
||||
@ -433,15 +431,15 @@ internal class MXMegolmEncryption(
|
||||
|
||||
// Include our device ID so that recipients can send us a
|
||||
// m.new_device message if they don't have our session key.
|
||||
map["device_id"] = mCredentials.deviceId!!
|
||||
map["device_id"] = credentials.deviceId!!
|
||||
|
||||
CryptoAsyncHelper.getUiHandler().post { queuedEncryption.mApiCallback?.onSuccess(map) }
|
||||
CryptoAsyncHelper.getUiHandler().post { queuedEncryption.apiCallback?.onSuccess(map) }
|
||||
|
||||
session.mUseCount++
|
||||
}
|
||||
|
||||
synchronized(mPendingEncryptions) {
|
||||
mPendingEncryptions.removeAll(queuedEncryptions)
|
||||
synchronized(_pendingEncryptions) {
|
||||
_pendingEncryptions.removeAll(queuedEncryptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,10 +456,10 @@ internal class MXMegolmEncryption(
|
||||
// have a list of the user's devices, then we already share an e2e room
|
||||
// with them, which means that they will have announced any new devices via
|
||||
// an m.new_device.
|
||||
mDeviceListManager.downloadKeys(userIds, false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||
deviceListManager.downloadKeys(userIds, false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||
val encryptToVerifiedDevicesOnly = mCryptoStore.getGlobalBlacklistUnverifiedDevices()
|
||||
|| mCryptoStore.getRoomsListBlacklistUnverifiedDevices().contains(mRoomId)
|
||||
val encryptToVerifiedDevicesOnly = cryptoStore.getGlobalBlacklistUnverifiedDevices()
|
||||
|| cryptoStore.getRoomsListBlacklistUnverifiedDevices().contains(roomId)
|
||||
|
||||
val devicesInRoom = MXUsersDevicesMap<MXDeviceInfo>()
|
||||
val unknownDevices = MXUsersDevicesMap<MXDeviceInfo>()
|
||||
@ -472,7 +470,7 @@ internal class MXMegolmEncryption(
|
||||
for (deviceId in deviceIds!!) {
|
||||
val deviceInfo = data.getObject(deviceId, userId)
|
||||
|
||||
if (mWarnOnUnknownDevicesRepository.warnOnUnknownDevices() && deviceInfo!!.isUnknown) {
|
||||
if (warnOnUnknownDevicesRepository.warnOnUnknownDevices() && deviceInfo!!.isUnknown) {
|
||||
// The device is not yet known by the user
|
||||
unknownDevices.setObject(deviceInfo, userId, deviceId)
|
||||
continue
|
||||
@ -501,7 +499,7 @@ internal class MXMegolmEncryption(
|
||||
// if so, warn the user so they can verify or ignore.
|
||||
if (unknownDevices.map.isNotEmpty()) {
|
||||
callback.onFailure(Failure.CryptoError(MXCryptoError(MXCryptoError.UNKNOWN_DEVICES_CODE,
|
||||
MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices)))
|
||||
MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices)))
|
||||
} else {
|
||||
callback.onSuccess(devicesInRoom)
|
||||
}
|
||||
|
@ -40,10 +40,9 @@ internal class MXMegolmEncryptionFactory(
|
||||
private val mMessageEncrypter: MessageEncrypter,
|
||||
private val mWarnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository) {
|
||||
|
||||
fun instantiate(roomId: String): MXMegolmEncryption {
|
||||
fun create(roomId: String): MXMegolmEncryption {
|
||||
return MXMegolmEncryption(
|
||||
roomId,
|
||||
|
||||
olmDevice,
|
||||
mKeysBackup,
|
||||
mCryptoStore,
|
||||
|
@ -18,7 +18,6 @@
|
||||
package im.vector.matrix.android.internal.crypto.algorithms.olm
|
||||
|
||||
import android.text.TextUtils
|
||||
import com.squareup.moshi.Json
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
@ -144,9 +143,9 @@ internal class MXOlmDecryption(
|
||||
}
|
||||
|
||||
val result = MXEventDecryptionResult()
|
||||
result.mClearEvent = payload
|
||||
result.mSenderCurve25519Key = olmEventContent.senderKey
|
||||
result.mClaimedEd25519Key = olmPayloadContent.keys!!.get("ed25519")
|
||||
result.clearEvent = payload
|
||||
result.senderCurve25519Key = olmEventContent.senderKey
|
||||
result.claimedEd25519Key = olmPayloadContent.keys!!.get("ed25519")
|
||||
|
||||
return result
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||
internal class MXOlmDecryptionFactory(private val mOlmDevice: MXOlmDevice,
|
||||
private val mCredentials: Credentials) {
|
||||
|
||||
fun instantiate(): MXOlmDecryption {
|
||||
fun create(): MXOlmDecryption {
|
||||
return MXOlmDecryption(
|
||||
mOlmDevice,
|
||||
mCredentials)
|
||||
|
@ -31,19 +31,21 @@ 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.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
internal class MXOlmEncryption(
|
||||
private var mRoomId: String,
|
||||
|
||||
private val mOlmDevice: MXOlmDevice,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mMessageEncrypter: MessageEncrypter,
|
||||
private val mDeviceListManager: DeviceListManager,
|
||||
private val mEnsureOlmSessionsForUsersAction: EnsureOlmSessionsForUsersAction)
|
||||
private var roomId: String,
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val messageEncrypter: MessageEncrypter,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val ensureOlmSessionsForUsersAction: EnsureOlmSessionsForUsersAction)
|
||||
: IMXEncrypting {
|
||||
|
||||
|
||||
override fun encryptEventContent(eventContent: Content,
|
||||
eventType: String,
|
||||
userIds: List<String>,
|
||||
@ -51,40 +53,42 @@ internal class MXOlmEncryption(
|
||||
// pick the list of recipients based on the membership list.
|
||||
//
|
||||
// TODO: there is a race condition here! What if a new user turns up
|
||||
ensureSession(userIds, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
val deviceInfos = ArrayList<MXDeviceInfo>()
|
||||
CoroutineScope(coroutineDispatchers.crypto).launch {
|
||||
ensureSession(userIds, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
val deviceInfos = ArrayList<MXDeviceInfo>()
|
||||
|
||||
for (userId in userIds) {
|
||||
val devices = mCryptoStore.getUserDevices(userId)?.values ?: emptyList()
|
||||
for (userId in userIds) {
|
||||
val devices = cryptoStore.getUserDevices(userId)?.values ?: emptyList()
|
||||
|
||||
for (device in devices) {
|
||||
val key = device.identityKey()
|
||||
for (device in devices) {
|
||||
val key = device.identityKey()
|
||||
|
||||
if (TextUtils.equals(key, mOlmDevice.deviceCurve25519Key)) {
|
||||
// Don't bother setting up session to ourself
|
||||
continue
|
||||
if (TextUtils.equals(key, olmDevice.deviceCurve25519Key)) {
|
||||
// Don't bother setting up session to ourself
|
||||
continue
|
||||
}
|
||||
|
||||
if (device.isBlocked) {
|
||||
// Don't bother setting up sessions with blocked users
|
||||
continue
|
||||
}
|
||||
|
||||
deviceInfos.add(device)
|
||||
}
|
||||
|
||||
if (device.isBlocked) {
|
||||
// Don't bother setting up sessions with blocked users
|
||||
continue
|
||||
}
|
||||
|
||||
deviceInfos.add(device)
|
||||
}
|
||||
|
||||
val messageMap = HashMap<String, Any>()
|
||||
messageMap["room_id"] = roomId
|
||||
messageMap["type"] = eventType
|
||||
messageMap["content"] = eventContent
|
||||
|
||||
messageEncrypter.encryptMessage(messageMap, deviceInfos)
|
||||
|
||||
callback.onSuccess(messageMap.toContent()!!)
|
||||
}
|
||||
|
||||
val messageMap = HashMap<String, Any>()
|
||||
messageMap["room_id"] = mRoomId
|
||||
messageMap["type"] = eventType
|
||||
messageMap["content"] = eventContent
|
||||
|
||||
mMessageEncrypter.encryptMessage(messageMap, deviceInfos)
|
||||
|
||||
callback.onSuccess(messageMap.toContent()!!)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,10 +98,10 @@ internal class MXOlmEncryption(
|
||||
* @param callback the asynchronous callback
|
||||
*/
|
||||
private fun ensureSession(users: List<String>, callback: MatrixCallback<Unit>?) {
|
||||
mDeviceListManager.downloadKeys(users, false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||
deviceListManager.downloadKeys(users, false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||
mEnsureOlmSessionsForUsersAction.handle(users, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
ensureOlmSessionsForUsersAction.handle(users, object : MatrixCallback<MXUsersDevicesMap<MXOlmSessionResult>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<MXOlmSessionResult>) {
|
||||
callback?.onSuccess(Unit)
|
||||
}
|
||||
|
@ -21,21 +21,23 @@ import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForUsersAction
|
||||
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
|
||||
internal class MXOlmEncryptionFactory(private val mOlmDevice: MXOlmDevice,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mMessageEncrypter: MessageEncrypter,
|
||||
private val mDeviceListManager: DeviceListManager,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val mEnsureOlmSessionsForUsersAction: EnsureOlmSessionsForUsersAction) {
|
||||
|
||||
fun instantiate(roomId: String): MXOlmEncryption {
|
||||
fun create(roomId: String): MXOlmEncryption {
|
||||
return MXOlmEncryption(
|
||||
roomId,
|
||||
|
||||
mOlmDevice,
|
||||
mCryptoStore,
|
||||
mMessageEncrypter,
|
||||
mDeviceListManager,
|
||||
coroutineDispatchers,
|
||||
mEnsureOlmSessionsForUsersAction)
|
||||
}
|
||||
}
|
@ -64,34 +64,34 @@ import kotlin.collections.HashMap
|
||||
* to the user's homeserver.
|
||||
*/
|
||||
internal class KeysBackup(
|
||||
private val mCredentials: Credentials,
|
||||
private val mCryptoStore: IMXCryptoStore,
|
||||
private val mOlmDevice: MXOlmDevice,
|
||||
private val mObjectSigner: ObjectSigner,
|
||||
private val credentials: Credentials,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val objectSigner: ObjectSigner,
|
||||
// Actions
|
||||
private val mMegolmSessionDataImporter: MegolmSessionDataImporter,
|
||||
private val megolmSessionDataImporter: MegolmSessionDataImporter,
|
||||
// Tasks
|
||||
private val mCreateKeysBackupVersionTask: CreateKeysBackupVersionTask,
|
||||
private val mDeleteBackupTask: DeleteBackupTask,
|
||||
private val mDeleteRoomSessionDataTask: DeleteRoomSessionDataTask,
|
||||
private val mDeleteRoomSessionsDataTask: DeleteRoomSessionsDataTask,
|
||||
private val mDeleteSessionDataTask: DeleteSessionsDataTask,
|
||||
private val mGetKeysBackupLastVersionTask: GetKeysBackupLastVersionTask,
|
||||
private val mGetKeysBackupVersionTask: GetKeysBackupVersionTask,
|
||||
private val mGetRoomSessionDataTask: GetRoomSessionDataTask,
|
||||
private val mGetRoomSessionsDataTask: GetRoomSessionsDataTask,
|
||||
private val mGetSessionsDataTask: GetSessionsDataTask,
|
||||
private val mStoreRoomSessionDataTask: StoreRoomSessionDataTask,
|
||||
private val mStoreSessionsDataTask: StoreRoomSessionsDataTask,
|
||||
private val mStoreSessionDataTask: StoreSessionsDataTask,
|
||||
private val mUpdateKeysBackupVersionTask: UpdateKeysBackupVersionTask,
|
||||
private val createKeysBackupVersionTask: CreateKeysBackupVersionTask,
|
||||
private val deleteBackupTask: DeleteBackupTask,
|
||||
private val deleteRoomSessionDataTask: DeleteRoomSessionDataTask,
|
||||
private val deleteRoomSessionsDataTask: DeleteRoomSessionsDataTask,
|
||||
private val deleteSessionDataTask: DeleteSessionsDataTask,
|
||||
private val getKeysBackupLastVersionTask: GetKeysBackupLastVersionTask,
|
||||
private val getKeysBackupVersionTask: GetKeysBackupVersionTask,
|
||||
private val getRoomSessionDataTask: GetRoomSessionDataTask,
|
||||
private val getRoomSessionsDataTask: GetRoomSessionsDataTask,
|
||||
private val getSessionsDataTask: GetSessionsDataTask,
|
||||
private val storeRoomSessionDataTask: StoreRoomSessionDataTask,
|
||||
private val storeSessionsDataTask: StoreRoomSessionsDataTask,
|
||||
private val storeSessionDataTask: StoreSessionsDataTask,
|
||||
private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask,
|
||||
// Task executor
|
||||
private val mTaskExecutor: TaskExecutor
|
||||
private val taskExecutor: TaskExecutor
|
||||
) : KeysBackupService {
|
||||
|
||||
private val mUIHandler = Handler(Looper.getMainLooper())
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
private val mKeysBackupStateManager = KeysBackupStateManager(mUIHandler)
|
||||
private val keysBackupStateManager = KeysBackupStateManager(uiHandler)
|
||||
|
||||
// The backup version
|
||||
override var mKeysBackupVersion: KeysVersionResult? = null
|
||||
@ -107,23 +107,23 @@ internal class KeysBackup(
|
||||
private var mKeysBackupStateListener: KeysBackupService.KeysBackupStateListener? = null
|
||||
|
||||
override val isEnabled: Boolean
|
||||
get() = mKeysBackupStateManager.isEnabled
|
||||
get() = keysBackupStateManager.isEnabled
|
||||
|
||||
override val isStucked: Boolean
|
||||
get() = mKeysBackupStateManager.isStucked
|
||||
get() = keysBackupStateManager.isStucked
|
||||
|
||||
override val state: KeysBackupState
|
||||
get() = mKeysBackupStateManager.state
|
||||
get() = keysBackupStateManager.state
|
||||
|
||||
override val currentBackupVersion: String?
|
||||
get() = mKeysBackupVersion?.version
|
||||
|
||||
override fun addListener(listener: KeysBackupService.KeysBackupStateListener) {
|
||||
mKeysBackupStateManager.addListener(listener)
|
||||
keysBackupStateManager.addListener(listener)
|
||||
}
|
||||
|
||||
override fun removeListener(listener: KeysBackupService.KeysBackupStateListener) {
|
||||
mKeysBackupStateManager.removeListener(listener)
|
||||
keysBackupStateManager.removeListener(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,7 +153,7 @@ internal class KeysBackup(
|
||||
} else {
|
||||
object : ProgressListener {
|
||||
override fun onProgress(progress: Int, total: Int) {
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
try {
|
||||
progressListener.onProgress(progress, total)
|
||||
} catch (e: Exception) {
|
||||
@ -176,7 +176,7 @@ internal class KeysBackup(
|
||||
|
||||
val canonicalJson = MoshiProvider.getCanonicalJson(Map::class.java, megolmBackupAuthData.signalableJSONDictionary())
|
||||
|
||||
megolmBackupAuthData.signatures = mObjectSigner.signObject(canonicalJson)
|
||||
megolmBackupAuthData.signatures = objectSigner.signObject(canonicalJson)
|
||||
|
||||
|
||||
val megolmBackupCreationInfo = MegolmBackupCreationInfo()
|
||||
@ -184,11 +184,11 @@ internal class KeysBackup(
|
||||
megolmBackupCreationInfo.authData = megolmBackupAuthData
|
||||
megolmBackupCreationInfo.recoveryKey = computeRecoveryKey(olmPkDecryption.privateKey())
|
||||
|
||||
mUIHandler.post { callback.onSuccess(megolmBackupCreationInfo) }
|
||||
uiHandler.post { callback.onSuccess(megolmBackupCreationInfo) }
|
||||
} catch (e: OlmException) {
|
||||
Timber.e(e, "OlmException")
|
||||
|
||||
mUIHandler.post { callback.onFailure(e) }
|
||||
uiHandler.post { callback.onFailure(e) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,14 +206,14 @@ internal class KeysBackup(
|
||||
createKeysBackupVersionBody.authData = MoshiProvider.providesMoshi().adapter(Map::class.java)
|
||||
.fromJson(keysBackupCreationInfo.authData?.toJsonString()) as Map<String, Any>?
|
||||
|
||||
mKeysBackupStateManager.state = KeysBackupState.Enabling
|
||||
keysBackupStateManager.state = KeysBackupState.Enabling
|
||||
|
||||
mCreateKeysBackupVersionTask
|
||||
createKeysBackupVersionTask
|
||||
.configureWith(createKeysBackupVersionBody)
|
||||
.dispatchTo(object : MatrixCallback<KeysVersion> {
|
||||
override fun onSuccess(info: KeysVersion) {
|
||||
// Reset backup markers.
|
||||
mCryptoStore.resetBackupMarkers()
|
||||
cryptoStore.resetBackupMarkers()
|
||||
|
||||
val keyBackupVersion = KeysVersionResult()
|
||||
keyBackupVersion.algorithm = createKeysBackupVersionBody.algorithm
|
||||
@ -230,11 +230,11 @@ internal class KeysBackup(
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
mKeysBackupStateManager.state = KeysBackupState.Disabled
|
||||
keysBackupStateManager.state = KeysBackupState.Disabled
|
||||
callback.onFailure(failure)
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,10 +251,10 @@ internal class KeysBackup(
|
||||
if (mKeysBackupVersion != null && version == mKeysBackupVersion!!.version) {
|
||||
resetKeysBackupData()
|
||||
mKeysBackupVersion = null
|
||||
mKeysBackupStateManager.state = KeysBackupState.Unknown
|
||||
keysBackupStateManager.state = KeysBackupState.Unknown
|
||||
}
|
||||
|
||||
mDeleteBackupTask.configureWith(DeleteBackupTask.Params(version))
|
||||
deleteBackupTask.configureWith(DeleteBackupTask.Params(version))
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
private fun eventuallyRestartBackup() {
|
||||
// Do not stay in KeysBackupState.Unknown but check what is available on the homeserver
|
||||
@ -266,16 +266,16 @@ internal class KeysBackup(
|
||||
override fun onSuccess(data: Unit) {
|
||||
eventuallyRestartBackup()
|
||||
|
||||
mUIHandler.post { callback?.onSuccess(Unit) }
|
||||
uiHandler.post { callback?.onSuccess(Unit) }
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
eventuallyRestartBackup()
|
||||
|
||||
mUIHandler.post { callback?.onFailure(failure) }
|
||||
uiHandler.post { callback?.onFailure(failure) }
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,7 +287,7 @@ internal class KeysBackup(
|
||||
// Server contains more keys than locally
|
||||
val totalNumberOfKeysLocally = getTotalNumbersOfKeys()
|
||||
|
||||
val keysBackupData = mCryptoStore.getKeysBackupData()
|
||||
val keysBackupData = cryptoStore.getKeysBackupData()
|
||||
|
||||
val totalNumberOfKeysServer = keysBackupData?.backupLastServerNumberOfKeys ?: -1
|
||||
val hashServer = keysBackupData?.backupLastServerHash
|
||||
@ -310,7 +310,7 @@ internal class KeysBackup(
|
||||
* Facility method to get the total number of locally stored keys
|
||||
*/
|
||||
override fun getTotalNumbersOfKeys(): Int {
|
||||
return mCryptoStore.inboundGroupSessionsCount(false)
|
||||
return cryptoStore.inboundGroupSessionsCount(false)
|
||||
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ internal class KeysBackup(
|
||||
* Facility method to get the number of backed up keys
|
||||
*/
|
||||
override fun getTotalNumbersOfBackedUpKeys(): Int {
|
||||
return mCryptoStore.inboundGroupSessionsCount(true)
|
||||
return cryptoStore.inboundGroupSessionsCount(true)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -370,7 +370,7 @@ internal class KeysBackup(
|
||||
}
|
||||
}
|
||||
|
||||
mKeysBackupStateManager.addListener(mKeysBackupStateListener!!)
|
||||
keysBackupStateManager.addListener(mKeysBackupStateListener!!)
|
||||
|
||||
backupKeys()
|
||||
}
|
||||
@ -396,7 +396,7 @@ internal class KeysBackup(
|
||||
.configureWith(keysBackupVersion)
|
||||
.dispatchTo(callback)
|
||||
.executeOn(TaskThread.COMPUTATION)
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -408,7 +408,7 @@ internal class KeysBackup(
|
||||
*/
|
||||
@WorkerThread
|
||||
private fun getKeysBackupTrustBg(keysBackupVersion: KeysVersionResult): KeysBackupVersionTrust {
|
||||
val myUserId = mCredentials.userId
|
||||
val myUserId = credentials.userId
|
||||
|
||||
val keysBackupVersionTrust = KeysBackupVersionTrust()
|
||||
val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData()
|
||||
@ -437,7 +437,7 @@ internal class KeysBackup(
|
||||
|
||||
var device: MXDeviceInfo? = null
|
||||
if (deviceId != null) {
|
||||
device = mCryptoStore.getUserDevice(deviceId, myUserId)
|
||||
device = cryptoStore.getUserDevice(deviceId, myUserId)
|
||||
|
||||
var isSignatureValid = false
|
||||
|
||||
@ -445,7 +445,7 @@ internal class KeysBackup(
|
||||
Timber.v("getKeysBackupTrust: Signature from unknown device $deviceId")
|
||||
} else {
|
||||
try {
|
||||
mOlmDevice.verifySignature(device.fingerprint()!!, authData.signalableJSONDictionary(), mySigs[keyId] as String)
|
||||
olmDevice.verifySignature(device.fingerprint()!!, authData.signalableJSONDictionary(), mySigs[keyId] as String)
|
||||
isSignatureValid = true
|
||||
} catch (e: OlmException) {
|
||||
Timber.v("getKeysBackupTrust: Bad signature from device " + device.deviceId + " " + e.localizedMessage)
|
||||
@ -481,7 +481,7 @@ internal class KeysBackup(
|
||||
Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}")
|
||||
|
||||
CryptoAsyncHelper.getDecryptBackgroundHandler().post {
|
||||
val myUserId = mCredentials.userId
|
||||
val myUserId = credentials.userId
|
||||
|
||||
// Get auth data to update it
|
||||
val authData = getMegolmBackupAuthData(keysBackupVersion)
|
||||
@ -489,7 +489,7 @@ internal class KeysBackup(
|
||||
if (authData == null) {
|
||||
Timber.w("trustKeyBackupVersion:trust: Key backup is missing required data")
|
||||
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
callback.onFailure(IllegalArgumentException("Missing element"))
|
||||
}
|
||||
|
||||
@ -503,14 +503,14 @@ internal class KeysBackup(
|
||||
// Add current device signature
|
||||
val canonicalJson = MoshiProvider.getCanonicalJson(Map::class.java, authData.signalableJSONDictionary())
|
||||
|
||||
val deviceSignatures = mObjectSigner.signObject(canonicalJson)
|
||||
val deviceSignatures = objectSigner.signObject(canonicalJson)
|
||||
|
||||
deviceSignatures[myUserId]?.forEach { entry ->
|
||||
myUserSignatures[entry.key] = entry.value
|
||||
}
|
||||
} else {
|
||||
// Remove current device signature
|
||||
myUserSignatures.remove("ed25519:${mCredentials.deviceId}")
|
||||
myUserSignatures.remove("ed25519:${credentials.deviceId}")
|
||||
}
|
||||
|
||||
// Create an updated version of KeysVersionResult
|
||||
@ -532,7 +532,7 @@ internal class KeysBackup(
|
||||
updateKeysBackupVersionBody.authData = adapter.fromJson(newMegolmBackupAuthData.toJsonString()) as Map<String, Any>?
|
||||
|
||||
// And send it to the homeserver
|
||||
mUpdateKeysBackupVersionTask
|
||||
updateKeysBackupVersionTask
|
||||
.configureWith(UpdateKeysBackupVersionTask.Params(keysBackupVersion.version!!, updateKeysBackupVersionBody))
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
@ -547,18 +547,18 @@ internal class KeysBackup(
|
||||
|
||||
checkAndStartWithKeysBackupVersion(newKeysBackupVersion)
|
||||
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
callback.onSuccess(data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
callback.onFailure(failure)
|
||||
}
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -578,7 +578,7 @@ internal class KeysBackup(
|
||||
if (!isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) {
|
||||
Timber.w("trustKeyBackupVersionWithRecoveryKey: Invalid recovery key.")
|
||||
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
callback.onFailure(IllegalArgumentException("Invalid recovery key or password"))
|
||||
}
|
||||
return@post
|
||||
@ -606,7 +606,7 @@ internal class KeysBackup(
|
||||
if (recoveryKey == null) {
|
||||
Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data")
|
||||
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
callback.onFailure(IllegalArgumentException("Missing element"))
|
||||
}
|
||||
|
||||
@ -652,7 +652,7 @@ internal class KeysBackup(
|
||||
backupAllGroupSessionsCallback = null
|
||||
|
||||
mKeysBackupStateListener?.let {
|
||||
mKeysBackupStateManager.removeListener(it)
|
||||
keysBackupStateManager.removeListener(it)
|
||||
}
|
||||
|
||||
mKeysBackupStateListener = null
|
||||
@ -663,10 +663,10 @@ internal class KeysBackup(
|
||||
*/
|
||||
override fun getBackupProgress(progressListener: ProgressListener) {
|
||||
CryptoAsyncHelper.getDecryptBackgroundHandler().post {
|
||||
val backedUpKeys = mCryptoStore.inboundGroupSessionsCount(true)
|
||||
val total = mCryptoStore.inboundGroupSessionsCount(false)
|
||||
val backedUpKeys = cryptoStore.inboundGroupSessionsCount(true)
|
||||
val total = cryptoStore.inboundGroupSessionsCount(false)
|
||||
|
||||
mUIHandler.post { progressListener.onProgress(backedUpKeys, total) }
|
||||
uiHandler.post { progressListener.onProgress(backedUpKeys, total) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -692,7 +692,7 @@ internal class KeysBackup(
|
||||
// Check if the recovery is valid before going any further
|
||||
if (!isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysVersionResult)) {
|
||||
Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key for this keys version")
|
||||
mUIHandler.post { callback.onFailure(InvalidParameterException("Invalid recovery key")) }
|
||||
uiHandler.post { callback.onFailure(InvalidParameterException("Invalid recovery key")) }
|
||||
return@Runnable
|
||||
}
|
||||
|
||||
@ -701,12 +701,12 @@ internal class KeysBackup(
|
||||
if (decryption == null) {
|
||||
// This should not happen anymore
|
||||
Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key. Error")
|
||||
mUIHandler.post { callback.onFailure(InvalidParameterException("Invalid recovery key")) }
|
||||
uiHandler.post { callback.onFailure(InvalidParameterException("Invalid recovery key")) }
|
||||
return@Runnable
|
||||
}
|
||||
|
||||
if (stepProgressListener != null) {
|
||||
mUIHandler.post { stepProgressListener.onStepProgress(StepProgressListener.Step.DownloadingKey) }
|
||||
uiHandler.post { stepProgressListener.onStepProgress(StepProgressListener.Step.DownloadingKey) }
|
||||
}
|
||||
|
||||
// Get backed up keys from the homeserver
|
||||
@ -749,7 +749,7 @@ internal class KeysBackup(
|
||||
null
|
||||
}
|
||||
|
||||
mMegolmSessionDataImporter.handle(sessionsData, !backUp, progressListener, object : MatrixCallback<ImportRoomKeysResult> {
|
||||
megolmSessionDataImporter.handle(sessionsData, !backUp, progressListener, object : MatrixCallback<ImportRoomKeysResult> {
|
||||
override fun onSuccess(data: ImportRoomKeysResult) {
|
||||
// Do not back up the key if it comes from a backup recovery
|
||||
if (backUp) {
|
||||
@ -766,7 +766,7 @@ internal class KeysBackup(
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
mUIHandler.post { callback.onFailure(failure) }
|
||||
uiHandler.post { callback.onFailure(failure) }
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -794,7 +794,7 @@ internal class KeysBackup(
|
||||
val progressListener = if (stepProgressListener != null) {
|
||||
object : ProgressListener {
|
||||
override fun onProgress(progress: Int, total: Int) {
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
stepProgressListener.onStepProgress(StepProgressListener.Step.ComputingKey(progress, total))
|
||||
}
|
||||
}
|
||||
@ -806,7 +806,7 @@ internal class KeysBackup(
|
||||
val recoveryKey = recoveryKeyFromPassword(password, keysBackupVersion, progressListener)
|
||||
|
||||
if (recoveryKey == null) {
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
Timber.v("backupKeys: Invalid configuration")
|
||||
callback.onFailure(IllegalStateException("Invalid configuration"))
|
||||
}
|
||||
@ -828,7 +828,7 @@ internal class KeysBackup(
|
||||
callback: MatrixCallback<KeysBackupData>) {
|
||||
if (roomId != null && sessionId != null) {
|
||||
// Get key for the room and for the session
|
||||
mGetRoomSessionDataTask
|
||||
getRoomSessionDataTask
|
||||
.configureWith(GetRoomSessionDataTask.Params(roomId, sessionId, version))
|
||||
.dispatchTo(object : MatrixCallback<KeyBackupData> {
|
||||
override fun onSuccess(data: KeyBackupData) {
|
||||
@ -847,10 +847,10 @@ internal class KeysBackup(
|
||||
callback.onFailure(failure)
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
} else if (roomId != null) {
|
||||
// Get all keys for the room
|
||||
mGetRoomSessionsDataTask
|
||||
getRoomSessionsDataTask
|
||||
.configureWith(GetRoomSessionsDataTask.Params(roomId, version))
|
||||
.dispatchTo(object : MatrixCallback<RoomKeysBackupData> {
|
||||
override fun onSuccess(data: RoomKeysBackupData) {
|
||||
@ -866,13 +866,13 @@ internal class KeysBackup(
|
||||
callback.onFailure(failure)
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
} else {
|
||||
// Get all keys
|
||||
mGetSessionsDataTask
|
||||
getSessionsDataTask
|
||||
.configureWith(GetSessionsDataTask.Params(version))
|
||||
.dispatchTo(callback)
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -908,14 +908,14 @@ internal class KeysBackup(
|
||||
checkAndStartKeysBackup()
|
||||
}
|
||||
state == KeysBackupState.ReadyToBackUp -> {
|
||||
mKeysBackupStateManager.state = KeysBackupState.WillBackUp
|
||||
keysBackupStateManager.state = KeysBackupState.WillBackUp
|
||||
|
||||
// Wait between 0 and 10 seconds, to avoid backup requests from
|
||||
// different clients hitting the server all at the same time when a
|
||||
// new key is sent
|
||||
val delayInMs = mRandom.nextInt(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS).toLong()
|
||||
|
||||
mUIHandler.postDelayed({ backupKeys() }, delayInMs)
|
||||
uiHandler.postDelayed({ backupKeys() }, delayInMs)
|
||||
}
|
||||
else -> {
|
||||
Timber.v("maybeBackupKeys: Skip it because state: $state")
|
||||
@ -932,7 +932,7 @@ internal class KeysBackup(
|
||||
*/
|
||||
override fun getVersion(version: String,
|
||||
callback: MatrixCallback<KeysVersionResult?>) {
|
||||
mGetKeysBackupVersionTask
|
||||
getKeysBackupVersionTask
|
||||
.configureWith(version)
|
||||
.dispatchTo(object : MatrixCallback<KeysVersionResult> {
|
||||
override fun onSuccess(data: KeysVersionResult) {
|
||||
@ -950,7 +950,7 @@ internal class KeysBackup(
|
||||
}
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -960,7 +960,7 @@ internal class KeysBackup(
|
||||
* @param callback onSuccess(null) will be called if there is no backup on the server
|
||||
*/
|
||||
override fun getCurrentVersion(callback: MatrixCallback<KeysVersionResult?>) {
|
||||
mGetKeysBackupLastVersionTask
|
||||
getKeysBackupLastVersionTask
|
||||
.configureWith(Unit)
|
||||
.dispatchTo(object : MatrixCallback<KeysVersionResult> {
|
||||
override fun onSuccess(data: KeysVersionResult) {
|
||||
@ -978,7 +978,7 @@ internal class KeysBackup(
|
||||
}
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1002,7 +1002,7 @@ internal class KeysBackup(
|
||||
callback.onSuccess(false)
|
||||
resetKeysBackupData()
|
||||
mKeysBackupVersion = null
|
||||
mKeysBackupStateManager.state = KeysBackupState.Disabled
|
||||
keysBackupStateManager.state = KeysBackupState.Disabled
|
||||
}
|
||||
} else {
|
||||
if (localBackupVersion == null) {
|
||||
@ -1047,7 +1047,7 @@ internal class KeysBackup(
|
||||
}
|
||||
|
||||
mKeysBackupVersion = null
|
||||
mKeysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver
|
||||
keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver
|
||||
|
||||
getCurrentVersion(object : MatrixCallback<KeysVersionResult?> {
|
||||
override fun onSuccess(data: KeysVersionResult?) {
|
||||
@ -1056,7 +1056,7 @@ internal class KeysBackup(
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version")
|
||||
mKeysBackupStateManager.state = KeysBackupState.Unknown
|
||||
keysBackupStateManager.state = KeysBackupState.Unknown
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -1069,12 +1069,12 @@ internal class KeysBackup(
|
||||
if (keyBackupVersion == null) {
|
||||
Timber.v("checkAndStartWithKeysBackupVersion: Found no key backup version on the homeserver")
|
||||
resetKeysBackupData()
|
||||
mKeysBackupStateManager.state = KeysBackupState.Disabled
|
||||
keysBackupStateManager.state = KeysBackupState.Disabled
|
||||
} else {
|
||||
getKeysBackupTrust(keyBackupVersion, object : MatrixCallback<KeysBackupVersionTrust> {
|
||||
|
||||
override fun onSuccess(data: KeysBackupVersionTrust) {
|
||||
val versionInStore = mCryptoStore.getKeyBackupVersion()
|
||||
val versionInStore = cryptoStore.getKeyBackupVersion()
|
||||
|
||||
if (data.usable) {
|
||||
Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: " + keyBackupVersion.version)
|
||||
@ -1093,7 +1093,7 @@ internal class KeysBackup(
|
||||
resetKeysBackupData()
|
||||
}
|
||||
|
||||
mKeysBackupStateManager.state = KeysBackupState.NotTrusted
|
||||
keysBackupStateManager.state = KeysBackupState.NotTrusted
|
||||
}
|
||||
}
|
||||
|
||||
@ -1213,7 +1213,7 @@ internal class KeysBackup(
|
||||
|
||||
if (retrievedMegolmBackupAuthData != null) {
|
||||
mKeysBackupVersion = keysVersionResult
|
||||
mCryptoStore.setKeyBackupVersion(keysVersionResult.version)
|
||||
cryptoStore.setKeyBackupVersion(keysVersionResult.version)
|
||||
|
||||
onServerDataRetrieved(keysVersionResult.count, keysVersionResult.hash)
|
||||
|
||||
@ -1223,20 +1223,20 @@ internal class KeysBackup(
|
||||
}
|
||||
} catch (e: OlmException) {
|
||||
Timber.e(e, "OlmException")
|
||||
mKeysBackupStateManager.state = KeysBackupState.Disabled
|
||||
keysBackupStateManager.state = KeysBackupState.Disabled
|
||||
return
|
||||
}
|
||||
|
||||
mKeysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
|
||||
maybeBackupKeys()
|
||||
} else {
|
||||
Timber.e("Invalid authentication data")
|
||||
mKeysBackupStateManager.state = KeysBackupState.Disabled
|
||||
keysBackupStateManager.state = KeysBackupState.Disabled
|
||||
}
|
||||
} else {
|
||||
Timber.e("Invalid authentication data")
|
||||
mKeysBackupStateManager.state = KeysBackupState.Disabled
|
||||
keysBackupStateManager.state = KeysBackupState.Disabled
|
||||
}
|
||||
}
|
||||
|
||||
@ -1244,7 +1244,7 @@ internal class KeysBackup(
|
||||
* Update the DB with data fetch from the server
|
||||
*/
|
||||
private fun onServerDataRetrieved(count: Int?, hash: String?) {
|
||||
mCryptoStore.setKeysBackupData(KeysBackupDataEntity()
|
||||
cryptoStore.setKeysBackupData(KeysBackupDataEntity()
|
||||
.apply {
|
||||
backupLastServerNumberOfKeys = count
|
||||
backupLastServerHash = hash
|
||||
@ -1260,12 +1260,12 @@ internal class KeysBackup(
|
||||
private fun resetKeysBackupData() {
|
||||
resetBackupAllGroupSessionsListeners()
|
||||
|
||||
mCryptoStore.setKeyBackupVersion(null)
|
||||
mCryptoStore.setKeysBackupData(null)
|
||||
cryptoStore.setKeyBackupVersion(null)
|
||||
cryptoStore.setKeysBackupData(null)
|
||||
mBackupKey = null
|
||||
|
||||
// Reset backup markers
|
||||
mCryptoStore.resetBackupMarkers()
|
||||
cryptoStore.resetBackupMarkers()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1291,20 +1291,20 @@ internal class KeysBackup(
|
||||
}
|
||||
|
||||
// Get a chunk of keys to backup
|
||||
val sessions = mCryptoStore.inboundGroupSessionsToBackup(KEY_BACKUP_SEND_KEYS_MAX_COUNT)
|
||||
val sessions = cryptoStore.inboundGroupSessionsToBackup(KEY_BACKUP_SEND_KEYS_MAX_COUNT)
|
||||
|
||||
Timber.v("backupKeys: 1 - " + sessions.size + " sessions to back up")
|
||||
|
||||
if (sessions.isEmpty()) {
|
||||
// Backup is up to date
|
||||
mKeysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
|
||||
backupAllGroupSessionsCallback?.onSuccess(Unit)
|
||||
resetBackupAllGroupSessionsListeners()
|
||||
return
|
||||
}
|
||||
|
||||
mKeysBackupStateManager.state = KeysBackupState.BackingUp
|
||||
keysBackupStateManager.state = KeysBackupState.BackingUp
|
||||
|
||||
CryptoAsyncHelper.getEncryptBackgroundHandler().post {
|
||||
Timber.v("backupKeys: 2 - Encrypting keys")
|
||||
@ -1332,25 +1332,25 @@ internal class KeysBackup(
|
||||
Timber.v("backupKeys: 4 - Sending request")
|
||||
|
||||
// Make the request
|
||||
mStoreSessionDataTask
|
||||
storeSessionDataTask
|
||||
.configureWith(StoreSessionsDataTask.Params(mKeysBackupVersion!!.version!!, keysBackupData))
|
||||
.dispatchTo(object : MatrixCallback<BackupKeysResult> {
|
||||
override fun onSuccess(data: BackupKeysResult) {
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
Timber.v("backupKeys: 5a - Request complete")
|
||||
|
||||
// Mark keys as backed up
|
||||
mCryptoStore.markBackupDoneForInboundGroupSessions(sessions)
|
||||
cryptoStore.markBackupDoneForInboundGroupSessions(sessions)
|
||||
|
||||
if (sessions.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) {
|
||||
Timber.v("backupKeys: All keys have been backed up")
|
||||
onServerDataRetrieved(data.count, data.hash)
|
||||
|
||||
// Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess()
|
||||
mKeysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
} else {
|
||||
Timber.v("backupKeys: Continue to back up keys")
|
||||
mKeysBackupStateManager.state = KeysBackupState.WillBackUp
|
||||
keysBackupStateManager.state = KeysBackupState.WillBackUp
|
||||
|
||||
backupKeys()
|
||||
}
|
||||
@ -1359,14 +1359,14 @@ internal class KeysBackup(
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
if (failure is Failure.ServerError) {
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
Timber.e(failure, "backupKeys: backupKeys failed.")
|
||||
|
||||
when (failure.error.code) {
|
||||
MatrixError.NOT_FOUND,
|
||||
MatrixError.WRONG_ROOM_KEYS_VERSION -> {
|
||||
// Backup has been deleted on the server, or we are not using the last backup version
|
||||
mKeysBackupStateManager.state = KeysBackupState.WrongBackUpVersion
|
||||
keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion
|
||||
backupAllGroupSessionsCallback?.onFailure(failure)
|
||||
resetBackupAllGroupSessionsListeners()
|
||||
resetKeysBackupData()
|
||||
@ -1376,24 +1376,24 @@ internal class KeysBackup(
|
||||
checkAndStartKeysBackup()
|
||||
}
|
||||
else -> // Come back to the ready state so that we will retry on the next received key
|
||||
mKeysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mUIHandler.post {
|
||||
uiHandler.post {
|
||||
backupAllGroupSessionsCallback?.onFailure(failure)
|
||||
resetBackupAllGroupSessionsListeners()
|
||||
|
||||
Timber.e("backupKeys: backupKeys failed.")
|
||||
|
||||
// Retry a bit later
|
||||
mKeysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
keysBackupStateManager.state = KeysBackupState.ReadyToBackUp
|
||||
maybeBackupKeys()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.executeBy(mTaskExecutor)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1401,7 +1401,7 @@ internal class KeysBackup(
|
||||
@WorkerThread
|
||||
fun encryptGroupSession(session: MXOlmInboundGroupSession2): KeyBackupData {
|
||||
// Gather information for each key
|
||||
val device = mCryptoStore.deviceWithIdentityKey(session.mSenderKey!!)
|
||||
val device = cryptoStore.deviceWithIdentityKey(session.mSenderKey!!)
|
||||
|
||||
// Build the m.megolm_backup.v1.curve25519-aes-sha2 data as defined at
|
||||
// https://github.com/uhoreg/matrix-doc/blob/e2e_backup/proposals/1219-storing-megolm-keys-serverside.md#mmegolm_backupv1curve25519-aes-sha2-key-format
|
||||
@ -1496,5 +1496,5 @@ internal class KeysBackup(
|
||||
* DEBUG INFO
|
||||
* ========================================================================================== */
|
||||
|
||||
override fun toString() = "KeysBackup for ${mCredentials.userId}"
|
||||
override fun toString() = "KeysBackup for ${credentials.userId}"
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ class MXQueuedEncryption {
|
||||
/**
|
||||
* The data to encrypt.
|
||||
*/
|
||||
var mEventContent: Content? = null
|
||||
var mEventType: String? = null
|
||||
var eventContent: Content? = null
|
||||
var eventType: String? = null
|
||||
|
||||
/**
|
||||
* the asynchronous callback
|
||||
*/
|
||||
var mApiCallback: MatrixCallback<Content>? = null
|
||||
var apiCallback: MatrixCallback<Content>? = null
|
||||
}
|
@ -666,18 +666,18 @@ internal class RealmCryptoStore(private val enableFileEncryption: Boolean = fals
|
||||
doRealmTransaction(realmConfiguration) {
|
||||
// Delete any previous store request with the same parameters
|
||||
it.where<IncomingRoomKeyRequestEntity>()
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.USER_ID, incomingRoomKeyRequest.mUserId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.DEVICE_ID, incomingRoomKeyRequest.mDeviceId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.REQUEST_ID, incomingRoomKeyRequest.mRequestId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.USER_ID, incomingRoomKeyRequest.userId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.DEVICE_ID, incomingRoomKeyRequest.deviceId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.REQUEST_ID, incomingRoomKeyRequest.requestId)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
|
||||
// Then store it
|
||||
it.createObject(IncomingRoomKeyRequestEntity::class.java).apply {
|
||||
userId = incomingRoomKeyRequest.mUserId
|
||||
deviceId = incomingRoomKeyRequest.mDeviceId
|
||||
requestId = incomingRoomKeyRequest.mRequestId
|
||||
putRequestBody(incomingRoomKeyRequest.mRequestBody)
|
||||
userId = incomingRoomKeyRequest.userId
|
||||
deviceId = incomingRoomKeyRequest.deviceId
|
||||
requestId = incomingRoomKeyRequest.requestId
|
||||
putRequestBody(incomingRoomKeyRequest.requestBody)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -685,9 +685,9 @@ internal class RealmCryptoStore(private val enableFileEncryption: Boolean = fals
|
||||
override fun deleteIncomingRoomKeyRequest(incomingRoomKeyRequest: IncomingRoomKeyRequest) {
|
||||
doRealmTransaction(realmConfiguration) {
|
||||
it.where<IncomingRoomKeyRequestEntity>()
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.USER_ID, incomingRoomKeyRequest.mUserId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.DEVICE_ID, incomingRoomKeyRequest.mDeviceId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.REQUEST_ID, incomingRoomKeyRequest.mRequestId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.USER_ID, incomingRoomKeyRequest.userId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.DEVICE_ID, incomingRoomKeyRequest.deviceId)
|
||||
.equalTo(IncomingRoomKeyRequestEntityFields.REQUEST_ID, incomingRoomKeyRequest.requestId)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
}
|
||||
|
@ -33,10 +33,10 @@ internal open class IncomingRoomKeyRequestEntity(
|
||||
|
||||
fun toIncomingRoomKeyRequest(): IncomingRoomKeyRequest {
|
||||
return IncomingRoomKeyRequest().apply {
|
||||
mRequestId = requestId
|
||||
mUserId = userId
|
||||
mDeviceId = deviceId
|
||||
mRequestBody = RoomKeyRequestBody().apply {
|
||||
requestId = requestId
|
||||
userId = userId
|
||||
deviceId = deviceId
|
||||
requestBody = RoomKeyRequestBody().apply {
|
||||
algorithm = requestBodyAlgorithm
|
||||
roomId = requestBodyRoomId
|
||||
senderKey = requestBodySenderKey
|
||||
|
@ -38,8 +38,7 @@ class MatrixModule(private val context: Context) {
|
||||
MatrixCoroutineDispatchers(io = Dispatchers.IO,
|
||||
computation = Dispatchers.IO,
|
||||
main = Dispatchers.Main,
|
||||
encryption = Executors.newSingleThreadExecutor().asCoroutineDispatcher(),
|
||||
decryption = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
crypto = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,8 @@ internal class TaskExecutor(private val coroutineDispatchers: MatrixCoroutineDis
|
||||
TaskThread.COMPUTATION -> coroutineDispatchers.computation
|
||||
TaskThread.IO -> coroutineDispatchers.io
|
||||
TaskThread.CALLER -> EmptyCoroutineContext
|
||||
TaskThread.ENCRYPTION -> coroutineDispatchers.encryption
|
||||
TaskThread.DECRYPTION -> coroutineDispatchers.decryption
|
||||
TaskThread.ENCRYPTION -> coroutineDispatchers.crypto
|
||||
TaskThread.DECRYPTION -> coroutineDispatchers.crypto
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,6 +22,5 @@ internal data class MatrixCoroutineDispatchers(
|
||||
val io: CoroutineDispatcher,
|
||||
val computation: CoroutineDispatcher,
|
||||
val main: CoroutineDispatcher,
|
||||
val decryption: CoroutineDispatcher,
|
||||
val encryption: CoroutineDispatcher
|
||||
val crypto: CoroutineDispatcher
|
||||
)
|
@ -70,11 +70,11 @@ class EncryptedItemFactory(
|
||||
if (decrypted == null) {
|
||||
return null
|
||||
}
|
||||
if (decrypted.mClearEvent == null) {
|
||||
if (decrypted.clearEvent == null) {
|
||||
return null
|
||||
}
|
||||
val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java)
|
||||
val clearEvent = adapter.fromJsonValue(decrypted.mClearEvent) ?: return null
|
||||
val clearEvent = adapter.fromJsonValue(decrypted.clearEvent) ?: return null
|
||||
val decryptedTimelineEvent = timelineEvent.copy(root = clearEvent)
|
||||
|
||||
// Success
|
||||
|
Loading…
Reference in New Issue
Block a user