Merge branch 'hotfix/fix_crash_before_release' into develop
This commit is contained in:
commit
c7a7ad7b57
|
@ -21,7 +21,7 @@ import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||||
import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE
|
import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE
|
||||||
import im.vector.matrix.android.api.util.JsonDict
|
import im.vector.matrix.android.api.util.JsonDict
|
||||||
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
|
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||||
|
@ -488,7 +488,7 @@ internal class MXOlmDevice @Inject constructor(
|
||||||
forwardingCurve25519KeyChain: List<String>,
|
forwardingCurve25519KeyChain: List<String>,
|
||||||
keysClaimed: Map<String, String>,
|
keysClaimed: Map<String, String>,
|
||||||
exportFormat: Boolean): Boolean {
|
exportFormat: Boolean): Boolean {
|
||||||
val session = OlmInboundGroupSessionWrapper(sessionKey, exportFormat)
|
val session = OlmInboundGroupSessionWrapper2(sessionKey, exportFormat)
|
||||||
runCatching { getInboundGroupSession(sessionId, senderKey, roomId) }
|
runCatching { getInboundGroupSession(sessionId, senderKey, roomId) }
|
||||||
.fold(
|
.fold(
|
||||||
{
|
{
|
||||||
|
@ -543,18 +543,18 @@ internal class MXOlmDevice @Inject constructor(
|
||||||
* @param megolmSessionsData the megolm sessions data
|
* @param megolmSessionsData the megolm sessions data
|
||||||
* @return the successfully imported sessions.
|
* @return the successfully imported sessions.
|
||||||
*/
|
*/
|
||||||
fun importInboundGroupSessions(megolmSessionsData: List<MegolmSessionData>): List<OlmInboundGroupSessionWrapper> {
|
fun importInboundGroupSessions(megolmSessionsData: List<MegolmSessionData>): List<OlmInboundGroupSessionWrapper2> {
|
||||||
val sessions = ArrayList<OlmInboundGroupSessionWrapper>(megolmSessionsData.size)
|
val sessions = ArrayList<OlmInboundGroupSessionWrapper2>(megolmSessionsData.size)
|
||||||
|
|
||||||
for (megolmSessionData in megolmSessionsData) {
|
for (megolmSessionData in megolmSessionsData) {
|
||||||
val sessionId = megolmSessionData.sessionId
|
val sessionId = megolmSessionData.sessionId
|
||||||
val senderKey = megolmSessionData.senderKey
|
val senderKey = megolmSessionData.senderKey
|
||||||
val roomId = megolmSessionData.roomId
|
val roomId = megolmSessionData.roomId
|
||||||
|
|
||||||
var session: OlmInboundGroupSessionWrapper? = null
|
var session: OlmInboundGroupSessionWrapper2? = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
session = OlmInboundGroupSessionWrapper(megolmSessionData)
|
session = OlmInboundGroupSessionWrapper2(megolmSessionData)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "## importInboundGroupSession() : Update for megolm session $senderKey/$sessionId")
|
Timber.e(e, "## importInboundGroupSession() : Update for megolm session $senderKey/$sessionId")
|
||||||
}
|
}
|
||||||
|
@ -741,7 +741,7 @@ internal class MXOlmDevice @Inject constructor(
|
||||||
* @param senderKey the base64-encoded curve25519 key of the sender.
|
* @param senderKey the base64-encoded curve25519 key of the sender.
|
||||||
* @return the inbound group session.
|
* @return the inbound group session.
|
||||||
*/
|
*/
|
||||||
fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): OlmInboundGroupSessionWrapper {
|
fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): OlmInboundGroupSessionWrapper2 {
|
||||||
if (sessionId.isNullOrBlank() || senderKey.isNullOrBlank()) {
|
if (sessionId.isNullOrBlank() || senderKey.isNullOrBlank()) {
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_SENDER_KEY, MXCryptoError.ERROR_MISSING_PROPERTY_REASON)
|
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_SENDER_KEY, MXCryptoError.ERROR_MISSING_PROPERTY_REASON)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ import im.vector.matrix.android.internal.crypto.keysbackup.tasks.UpdateKeysBacku
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
|
import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
|
import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
|
||||||
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
import im.vector.matrix.android.internal.crypto.store.SavedKeyBackupKeyInfo
|
import im.vector.matrix.android.internal.crypto.store.SavedKeyBackupKeyInfo
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
|
import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
|
||||||
|
@ -1318,7 +1318,7 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper): KeyBackupData {
|
fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2): KeyBackupData {
|
||||||
// Gather information for each key
|
// Gather information for each key
|
||||||
val device = cryptoStore.deviceWithIdentityKey(olmInboundGroupSessionWrapper.senderKey!!)
|
val device = cryptoStore.deviceWithIdentityKey(olmInboundGroupSessionWrapper.senderKey!!)
|
||||||
|
|
||||||
|
|
|
@ -103,11 +103,10 @@ class OlmInboundGroupSessionWrapper : Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export the inbound group session keys
|
* Export the inbound group session keys
|
||||||
* @param index the index to export. If null, the first known index will be used
|
|
||||||
*
|
*
|
||||||
* @return the inbound group session as MegolmSessionData if the operation succeeds
|
* @return the inbound group session as MegolmSessionData if the operation succeeds
|
||||||
*/
|
*/
|
||||||
fun exportKeys(index: Long? = null): MegolmSessionData? {
|
fun exportKeys(): MegolmSessionData? {
|
||||||
return try {
|
return try {
|
||||||
if (null == forwardingCurve25519KeyChain) {
|
if (null == forwardingCurve25519KeyChain) {
|
||||||
forwardingCurve25519KeyChain = ArrayList()
|
forwardingCurve25519KeyChain = ArrayList()
|
||||||
|
@ -117,8 +116,6 @@ class OlmInboundGroupSessionWrapper : Serializable {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val wantedIndex = index ?: olmInboundGroupSession!!.firstKnownIndex
|
|
||||||
|
|
||||||
MegolmSessionData(
|
MegolmSessionData(
|
||||||
senderClaimedEd25519Key = keysClaimed?.get("ed25519"),
|
senderClaimedEd25519Key = keysClaimed?.get("ed25519"),
|
||||||
forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!),
|
forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!),
|
||||||
|
@ -126,7 +123,7 @@ class OlmInboundGroupSessionWrapper : Serializable {
|
||||||
senderClaimedKeys = keysClaimed,
|
senderClaimedKeys = keysClaimed,
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
sessionId = olmInboundGroupSession!!.sessionIdentifier(),
|
sessionId = olmInboundGroupSession!!.sessionIdentifier(),
|
||||||
sessionKey = olmInboundGroupSession!!.export(wantedIndex),
|
sessionKey = olmInboundGroupSession!!.export(olmInboundGroupSession!!.firstKnownIndex),
|
||||||
algorithm = MXCRYPTO_ALGORITHM_MEGOLM
|
algorithm = MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.internal.crypto.model
|
||||||
|
|
||||||
|
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
|
import im.vector.matrix.android.internal.crypto.MegolmSessionData
|
||||||
|
import org.matrix.olm.OlmInboundGroupSession
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class adds more context to a OlmInboundGroupSession object.
|
||||||
|
* This allows additional checks. The class implements Serializable so that the context can be stored.
|
||||||
|
*/
|
||||||
|
class OlmInboundGroupSessionWrapper2 : Serializable {
|
||||||
|
|
||||||
|
// The associated olm inbound group session.
|
||||||
|
var olmInboundGroupSession: OlmInboundGroupSession? = null
|
||||||
|
|
||||||
|
// The room in which this session is used.
|
||||||
|
var roomId: String? = null
|
||||||
|
|
||||||
|
// The base64-encoded curve25519 key of the sender.
|
||||||
|
var senderKey: String? = null
|
||||||
|
|
||||||
|
// Other keys the sender claims.
|
||||||
|
var keysClaimed: Map<String, String>? = null
|
||||||
|
|
||||||
|
// Devices which forwarded this session to us (normally empty).
|
||||||
|
var forwardingCurve25519KeyChain: List<String>? = ArrayList()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the first known message index
|
||||||
|
*/
|
||||||
|
val firstKnownIndex: Long?
|
||||||
|
get() {
|
||||||
|
if (null != olmInboundGroupSession) {
|
||||||
|
try {
|
||||||
|
return olmInboundGroupSession!!.firstKnownIndex
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "## getFirstKnownIndex() : getFirstKnownIndex failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param sessionKey the session key
|
||||||
|
* @param isImported true if it is an imported session key
|
||||||
|
*/
|
||||||
|
constructor(sessionKey: String, isImported: Boolean) {
|
||||||
|
try {
|
||||||
|
if (!isImported) {
|
||||||
|
olmInboundGroupSession = OlmInboundGroupSession(sessionKey)
|
||||||
|
} else {
|
||||||
|
olmInboundGroupSession = OlmInboundGroupSession.importSession(sessionKey)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "Cannot create")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a new instance from the provided keys map.
|
||||||
|
*
|
||||||
|
* @param megolmSessionData the megolm session data
|
||||||
|
* @throws Exception if the data are invalid
|
||||||
|
*/
|
||||||
|
@Throws(Exception::class)
|
||||||
|
constructor(megolmSessionData: MegolmSessionData) {
|
||||||
|
try {
|
||||||
|
olmInboundGroupSession = OlmInboundGroupSession.importSession(megolmSessionData.sessionKey!!)
|
||||||
|
|
||||||
|
if (olmInboundGroupSession!!.sessionIdentifier() != megolmSessionData.sessionId) {
|
||||||
|
throw Exception("Mismatched group session Id")
|
||||||
|
}
|
||||||
|
|
||||||
|
senderKey = megolmSessionData.senderKey
|
||||||
|
keysClaimed = megolmSessionData.senderClaimedKeys
|
||||||
|
roomId = megolmSessionData.roomId
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw Exception(e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the inbound group session keys
|
||||||
|
* @param index the index to export. If null, the first known index will be used
|
||||||
|
*
|
||||||
|
* @return the inbound group session as MegolmSessionData if the operation succeeds
|
||||||
|
*/
|
||||||
|
fun exportKeys(index: Long? = null): MegolmSessionData? {
|
||||||
|
return try {
|
||||||
|
if (null == forwardingCurve25519KeyChain) {
|
||||||
|
forwardingCurve25519KeyChain = ArrayList()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keysClaimed == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val wantedIndex = index ?: olmInboundGroupSession!!.firstKnownIndex
|
||||||
|
|
||||||
|
MegolmSessionData(
|
||||||
|
senderClaimedEd25519Key = keysClaimed?.get("ed25519"),
|
||||||
|
forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!),
|
||||||
|
senderKey = senderKey,
|
||||||
|
senderClaimedKeys = keysClaimed,
|
||||||
|
roomId = roomId,
|
||||||
|
sessionId = olmInboundGroupSession!!.sessionIdentifier(),
|
||||||
|
sessionKey = olmInboundGroupSession!!.export(wantedIndex),
|
||||||
|
algorithm = MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "## export() : senderKey $senderKey failed")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the session for a message index.
|
||||||
|
*
|
||||||
|
* @param messageIndex the message index
|
||||||
|
* @return the exported data
|
||||||
|
*/
|
||||||
|
fun exportSession(messageIndex: Long): String? {
|
||||||
|
if (null != olmInboundGroupSession) {
|
||||||
|
try {
|
||||||
|
return olmInboundGroupSession!!.export(messageIndex)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "## exportSession() : export failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequest
|
||||||
import im.vector.matrix.android.internal.crypto.OutgoingSecretRequest
|
import im.vector.matrix.android.internal.crypto.OutgoingSecretRequest
|
||||||
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
||||||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
||||||
|
@ -59,7 +59,7 @@ internal interface IMXCryptoStore {
|
||||||
*
|
*
|
||||||
* @return the list of all known group sessions, to export them.
|
* @return the list of all known group sessions, to export them.
|
||||||
*/
|
*/
|
||||||
fun getInboundGroupSessions(): List<OlmInboundGroupSessionWrapper>
|
fun getInboundGroupSessions(): List<OlmInboundGroupSessionWrapper2>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true to unilaterally blacklist all unverified devices.
|
* @return true to unilaterally blacklist all unverified devices.
|
||||||
|
@ -282,7 +282,7 @@ internal interface IMXCryptoStore {
|
||||||
*
|
*
|
||||||
* @param sessions the inbound group sessions to store.
|
* @param sessions the inbound group sessions to store.
|
||||||
*/
|
*/
|
||||||
fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper>)
|
fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper2>)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve an inbound group session.
|
* Retrieve an inbound group session.
|
||||||
|
@ -291,7 +291,7 @@ internal interface IMXCryptoStore {
|
||||||
* @param senderKey the base64-encoded curve25519 key of the sender.
|
* @param senderKey the base64-encoded curve25519 key of the sender.
|
||||||
* @return an inbound group session.
|
* @return an inbound group session.
|
||||||
*/
|
*/
|
||||||
fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper?
|
fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper2?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an inbound group session
|
* Remove an inbound group session
|
||||||
|
@ -315,7 +315,7 @@ internal interface IMXCryptoStore {
|
||||||
*
|
*
|
||||||
* @param sessions the sessions
|
* @param sessions the sessions
|
||||||
*/
|
*/
|
||||||
fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper>)
|
fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper2>)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve inbound group sessions that are not yet backed up.
|
* Retrieve inbound group sessions that are not yet backed up.
|
||||||
|
@ -323,7 +323,7 @@ internal interface IMXCryptoStore {
|
||||||
* @param limit the maximum number of sessions to return.
|
* @param limit the maximum number of sessions to return.
|
||||||
* @return an array of non backed up inbound group sessions.
|
* @return an array of non backed up inbound group sessions.
|
||||||
*/
|
*/
|
||||||
fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper>
|
fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper2>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of stored inbound group sessions.
|
* Number of stored inbound group sessions.
|
||||||
|
|
|
@ -38,7 +38,7 @@ import im.vector.matrix.android.internal.crypto.OutgoingSecretRequest
|
||||||
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
|
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||||
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
||||||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
|
||||||
|
@ -108,7 +108,7 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
private val olmSessionsToRelease = HashMap<String, OlmSessionWrapper>()
|
private val olmSessionsToRelease = HashMap<String, OlmSessionWrapper>()
|
||||||
|
|
||||||
// Cache for InboundGroupSession, to release them properly
|
// Cache for InboundGroupSession, to release them properly
|
||||||
private val inboundGroupSessionToRelease = HashMap<String, OlmInboundGroupSessionWrapper>()
|
private val inboundGroupSessionToRelease = HashMap<String, OlmInboundGroupSessionWrapper2>()
|
||||||
|
|
||||||
private val newSessionListeners = ArrayList<NewSessionListener>()
|
private val newSessionListeners = ArrayList<NewSessionListener>()
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
.toMutableSet()
|
.toMutableSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper>) {
|
override fun storeInboundGroupSessions(sessions: List<OlmInboundGroupSessionWrapper2>) {
|
||||||
if (sessions.isEmpty()) {
|
if (sessions.isEmpty()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -692,7 +692,7 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper? {
|
override fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper2? {
|
||||||
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey)
|
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey)
|
||||||
|
|
||||||
// If not in cache (or not found), try to read it from realm
|
// If not in cache (or not found), try to read it from realm
|
||||||
|
@ -712,10 +712,10 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: the result will be only use to export all the keys and not to use the OlmInboundGroupSessionWrapper,
|
* Note: the result will be only use to export all the keys and not to use the OlmInboundGroupSessionWrapper2,
|
||||||
* so there is no need to use or update `inboundGroupSessionToRelease` for native memory management
|
* so there is no need to use or update `inboundGroupSessionToRelease` for native memory management
|
||||||
*/
|
*/
|
||||||
override fun getInboundGroupSessions(): MutableList<OlmInboundGroupSessionWrapper> {
|
override fun getInboundGroupSessions(): MutableList<OlmInboundGroupSessionWrapper2> {
|
||||||
return doWithRealm(realmConfiguration) {
|
return doWithRealm(realmConfiguration) {
|
||||||
it.where<OlmInboundGroupSessionEntity>()
|
it.where<OlmInboundGroupSessionEntity>()
|
||||||
.findAll()
|
.findAll()
|
||||||
|
@ -787,7 +787,7 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper>) {
|
override fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List<OlmInboundGroupSessionWrapper2>) {
|
||||||
if (olmInboundGroupSessionWrappers.isEmpty()) {
|
if (olmInboundGroupSessionWrappers.isEmpty()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper> {
|
override fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper2> {
|
||||||
return doWithRealm(realmConfiguration) {
|
return doWithRealm(realmConfiguration) {
|
||||||
it.where<OlmInboundGroupSessionEntity>()
|
it.where<OlmInboundGroupSessionEntity>()
|
||||||
.equalTo(OlmInboundGroupSessionEntityFields.BACKED_UP, false)
|
.equalTo(OlmInboundGroupSessionEntityFields.BACKED_UP, false)
|
||||||
|
|
|
@ -21,6 +21,8 @@ import com.squareup.moshi.Types
|
||||||
import im.vector.matrix.android.api.extensions.tryThis
|
import im.vector.matrix.android.api.extensions.tryThis
|
||||||
import im.vector.matrix.android.api.util.JsonDict
|
import im.vector.matrix.android.api.util.JsonDict
|
||||||
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.mapper.CrossSigningKeysMapper
|
import im.vector.matrix.android.internal.crypto.store.db.mapper.CrossSigningKeysMapper
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.CrossSigningInfoEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.CrossSigningInfoEntityFields
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.CryptoMetadataEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.CryptoMetadataEntityFields
|
||||||
|
@ -29,6 +31,7 @@ import im.vector.matrix.android.internal.crypto.store.db.model.GossipingEventEnt
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.KeyInfoEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.KeyInfoEntityFields
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
|
||||||
|
import im.vector.matrix.android.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.TrustLevelEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.TrustLevelEntityFields
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.model.UserEntityFields
|
import im.vector.matrix.android.internal.crypto.store.db.model.UserEntityFields
|
||||||
|
@ -214,6 +217,23 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi
|
||||||
}
|
}
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate frozen classes
|
||||||
|
val inboundGroupSessions = realm.where("OlmInboundGroupSessionEntity").findAll()
|
||||||
|
inboundGroupSessions.forEach { dynamicObject ->
|
||||||
|
dynamicObject.getString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA)?.let { serializedObject ->
|
||||||
|
try {
|
||||||
|
deserializeFromRealm<OlmInboundGroupSessionWrapper?>(serializedObject)?.let { oldFormat ->
|
||||||
|
val newFormat = oldFormat.exportKeys()?.let {
|
||||||
|
OlmInboundGroupSessionWrapper2(it)
|
||||||
|
}
|
||||||
|
dynamicObject.setString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA, serializeForRealm(newFormat))
|
||||||
|
}
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
Timber.e(failure, "## OlmInboundGroupSessionEntity migration failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun migrateTo5(realm: DynamicRealm) {
|
private fun migrateTo5(realm: DynamicRealm) {
|
||||||
|
|
|
@ -16,12 +16,12 @@
|
||||||
|
|
||||||
package im.vector.matrix.android.internal.crypto.store.db.model
|
package im.vector.matrix.android.internal.crypto.store.db.model
|
||||||
|
|
||||||
import im.vector.matrix.android.api.extensions.tryThis
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.deserializeFromRealm
|
import im.vector.matrix.android.internal.crypto.store.db.deserializeFromRealm
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.serializeForRealm
|
import im.vector.matrix.android.internal.crypto.store.db.serializeForRealm
|
||||||
import io.realm.RealmObject
|
import io.realm.RealmObject
|
||||||
import io.realm.annotations.PrimaryKey
|
import io.realm.annotations.PrimaryKey
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
internal fun OlmInboundGroupSessionEntity.Companion.createPrimaryKey(sessionId: String?, senderKey: String?) = "$sessionId|$senderKey"
|
internal fun OlmInboundGroupSessionEntity.Companion.createPrimaryKey(sessionId: String?, senderKey: String?) = "$sessionId|$senderKey"
|
||||||
|
|
||||||
|
@ -36,11 +36,16 @@ internal open class OlmInboundGroupSessionEntity(
|
||||||
var backedUp: Boolean = false)
|
var backedUp: Boolean = false)
|
||||||
: RealmObject() {
|
: RealmObject() {
|
||||||
|
|
||||||
fun getInboundGroupSession(): OlmInboundGroupSessionWrapper? {
|
fun getInboundGroupSession(): OlmInboundGroupSessionWrapper2? {
|
||||||
return tryThis { deserializeFromRealm<OlmInboundGroupSessionWrapper?>(olmInboundGroupSessionData) }
|
return try {
|
||||||
|
deserializeFromRealm<OlmInboundGroupSessionWrapper2?>(olmInboundGroupSessionData)
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
Timber.e(failure, "## Deserialization failure")
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putInboundGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper?) {
|
fun putInboundGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2?) {
|
||||||
olmInboundGroupSessionData = serializeForRealm(olmInboundGroupSessionWrapper)
|
olmInboundGroupSessionData = serializeForRealm(olmInboundGroupSessionWrapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.riotx.features.crypto.keysbackup.restore
|
package im.vector.riotx.features.crypto.keysbackup.restore
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
|
@ -70,7 +69,7 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase
|
||||||
mPassphraseInputLayout.error = newValue
|
mPassphraseInputLayout.error = newValue
|
||||||
})
|
})
|
||||||
|
|
||||||
helperTextWithLink.text = spannableStringForHelperText(context!!)
|
helperTextWithLink.text = spannableStringForHelperText()
|
||||||
|
|
||||||
viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer {
|
viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer {
|
||||||
val shouldBeVisible = it ?: false
|
val shouldBeVisible = it ?: false
|
||||||
|
@ -87,9 +86,9 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun spannableStringForHelperText(context: Context): SpannableString {
|
private fun spannableStringForHelperText(): SpannableString {
|
||||||
val clickableText = context.getString(R.string.keys_backup_restore_use_recovery_key)
|
val clickableText = getString(R.string.keys_backup_restore_use_recovery_key)
|
||||||
val helperText = context.getString(R.string.keys_backup_restore_with_passphrase_helper_with_link, clickableText)
|
val helperText = getString(R.string.keys_backup_restore_with_passphrase_helper_with_link, clickableText)
|
||||||
|
|
||||||
val spanString = SpannableString(helperText)
|
val spanString = SpannableString(helperText)
|
||||||
|
|
||||||
|
@ -117,7 +116,7 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase
|
||||||
fun onRestoreBackup() {
|
fun onRestoreBackup() {
|
||||||
val value = viewModel.passphrase.value
|
val value = viewModel.passphrase.value
|
||||||
if (value.isNullOrBlank()) {
|
if (value.isNullOrBlank()) {
|
||||||
viewModel.passphraseErrorText.value = context?.getString(R.string.passphrase_empty_error_message)
|
viewModel.passphraseErrorText.value = getString(R.string.passphrase_empty_error_message)
|
||||||
} else {
|
} else {
|
||||||
viewModel.recoverKeys(sharedViewModel)
|
viewModel.recoverKeys(sharedViewModel)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ class KeysBackupRestoreFromPassphraseViewModel @Inject constructor(
|
||||||
try {
|
try {
|
||||||
sharedViewModel.recoverUsingBackupPass(passphrase.value!!)
|
sharedViewModel.recoverUsingBackupPass(passphrase.value!!)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
passphraseErrorText.value = stringProvider.getString(R.string.keys_backup_passphrase_error_decrypt)
|
passphraseErrorText.postValue(stringProvider.getString(R.string.keys_backup_passphrase_error_decrypt))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.Room
|
import im.vector.matrix.android.api.session.room.Room
|
||||||
import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
|
import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
|
||||||
|
import im.vector.matrix.android.api.session.room.send.SendState
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
|
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.hasBeenEdited
|
import im.vector.matrix.android.api.session.room.timeline.hasBeenEdited
|
||||||
|
@ -123,7 +124,9 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getE2EDecoration(room: Room?, event: TimelineEvent): E2EDecoration {
|
private fun getE2EDecoration(room: Room?, event: TimelineEvent): E2EDecoration {
|
||||||
return if (room?.isEncrypted() == true
|
return if (
|
||||||
|
event.root.sendState == SendState.SYNCED
|
||||||
|
&& room?.isEncrypted() == true
|
||||||
// is user verified
|
// is user verified
|
||||||
&& session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) {
|
&& session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) {
|
||||||
val ts = room.roomSummary()?.encryptionEventTs ?: 0
|
val ts = room.roomSummary()?.encryptionEventTs ?: 0
|
||||||
|
|
Loading…
Reference in New Issue