Merge pull request #297 from vector-im/feature/crypto_stabilization

Safely remove all usage of `!![`
This commit is contained in:
Benoit Marty 2019-07-04 15:17:26 +02:00 committed by GitHub
commit f2a52f0253
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 127 additions and 121 deletions

View File

@ -78,6 +78,8 @@ class MXCryptoError(var code: String,

companion object {

// TODO Create sealed class

/**
* Error codes
*/
@ -88,7 +90,10 @@ class MXCryptoError(var code: String,
const val UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE = "UNKNOWN_INBOUND_SESSION_ID"
const val INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE = "INBOUND_SESSION_MISMATCH_ROOM_ID"
const val MISSING_FIELDS_ERROR_CODE = "MISSING_FIELDS"
const val BAD_EVENT_FORMAT_ERROR_CODE = "BAD_EVENT_FORMAT_ERROR_CODE"
const val MISSING_SENDER_KEY_ERROR_CODE = "MISSING_SENDER_KEY_ERROR_CODE"
const val MISSING_CIPHER_TEXT_ERROR_CODE = "MISSING_CIPHER_TEXT"
const val BAD_DECRYPTED_FORMAT_ERROR_CODE = "BAD_DECRYPTED_FORMAT_ERROR_CODE"
const val NOT_INCLUDE_IN_RECIPIENTS_ERROR_CODE = "NOT_INCLUDE_IN_RECIPIENTS"
const val BAD_RECIPIENT_ERROR_CODE = "BAD_RECIPIENT"
const val BAD_RECIPIENT_KEY_ERROR_CODE = "BAD_RECIPIENT_KEY"
@ -118,7 +123,10 @@ class MXCryptoError(var code: String,
const val UNKNOWN_INBOUND_SESSION_ID_REASON = "Unknown inbound session id"
const val INBOUND_SESSION_MISMATCH_ROOM_ID_REASON = "Mismatched room_id for inbound group session (expected %1\$s, was %2\$s)"
const val MISSING_FIELDS_REASON = "Missing fields in input"
const val BAD_EVENT_FORMAT_TEXT_REASON = "Bad event format"
const val MISSING_SENDER_KEY_TEXT_REASON = "Missing senderKey"
const val MISSING_CIPHER_TEXT_REASON = "Missing ciphertext"
const val BAD_DECRYPTED_FORMAT_TEXT_REASON = "Bad decrypted event format"
const val NOT_INCLUDED_IN_RECIPIENT_REASON = "Not included in recipients"
const val BAD_RECIPIENT_REASON = "Message was intended for %1\$s"
const val BAD_RECIPIENT_KEY_REASON = "Message not intended for this device"

View File

@ -210,13 +210,7 @@ class CreateRoomParams {
* @return the first invited user id
*/
fun getFirstInvitedUserId(): String? {
if (0 != getInviteCount()) {
return invitedUserIds!![0]
}

return if (0 != getInvite3PidCount()) {
invite3pids!![0].address
} else null
return invitedUserIds?.firstOrNull() ?: invite3pids?.firstOrNull()?.address
}

/**

View File

@ -21,11 +21,11 @@ import android.text.TextUtils
import arrow.core.Try
import im.vector.matrix.android.api.MatrixPatterns
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.extensions.onError
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.DownloadKeysForUsersTask
import im.vector.matrix.android.internal.extensions.onError
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import timber.log.Timber
@ -380,14 +380,14 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
}

val signKeyId = "ed25519:" + deviceKeys.deviceId
val signKey = deviceKeys.keys!![signKeyId]
val signKey = deviceKeys.keys?.get(signKeyId)

if (null == signKey) {
Timber.e("## validateDeviceKeys() : Device " + userId + ":" + deviceKeys.deviceId + " has no ed25519 key")
return false
}

val signatureMap = deviceKeys.signatures!![userId]
val signatureMap = deviceKeys.signatures?.get(userId)

if (null == signatureMap) {
Timber.e("## validateDeviceKeys() : Device " + userId + ":" + deviceKeys.deviceId + " has no map for " + userId)
@ -413,7 +413,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM

if (!isVerified) {
Timber.e("## validateDeviceKeys() : Unable to verify signature on device " + userId + ":"
+ deviceKeys.deviceId + " with error " + errorMessage)
+ deviceKeys.deviceId + " with error " + errorMessage)
return false
}

@ -424,8 +424,8 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
//
// Should we warn the user about it somehow?
Timber.e("## validateDeviceKeys() : WARNING:Ed25519 key for device " + userId + ":"
+ deviceKeys.deviceId + " has changed : "
+ previouslyStoredDeviceKeys.fingerprint() + " -> " + signKey)
+ deviceKeys.deviceId + " has changed : "
+ previouslyStoredDeviceKeys.fingerprint() + " -> " + signKey)

Timber.e("## validateDeviceKeys() : $previouslyStoredDeviceKeys -> $deviceKeys")
Timber.e("## validateDeviceKeys() : " + previouslyStoredDeviceKeys.keys + " -> " + deviceKeys.keys)

View File

@ -667,7 +667,7 @@ internal class MXOlmDevice @Inject constructor(

val messageIndexKey = senderKey + "|" + sessionId + "|" + decryptResult.mIndex

if (null != inboundGroupSessionMessageIndexes[timeline]!![messageIndexKey]) {
if (inboundGroupSessionMessageIndexes[timeline]?.get(messageIndexKey) != null) {
val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex)
Timber.e("## decryptGroupMessage() : $reason")
throw MXDecryptionException(MXCryptoError(MXCryptoError.DUPLICATED_MESSAGE_INDEX_ERROR_CODE,

View File

@ -150,7 +150,7 @@ internal class OneTimeKeysUploader @Inject constructor(
val oneTimeKeys = olmDevice.getOneTimeKeys()
val oneTimeJson = HashMap<String, Any>()

val curve25519Map = oneTimeKeys!![OlmAccount.JSON_KEY_ONE_TIME_KEY]
val curve25519Map = oneTimeKeys?.get(OlmAccount.JSON_KEY_ONE_TIME_KEY)

if (null != curve25519Map) {
for (key_id in curve25519Map.keys) {

View File

@ -179,13 +179,13 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
pendingEvents[pendingEventsKey] = HashMap()
}

if (!pendingEvents[pendingEventsKey]!!.containsKey(timelineId)) {
pendingEvents[pendingEventsKey]!![timelineId] = ArrayList()
if (pendingEvents[pendingEventsKey]?.containsKey(timelineId) == false) {
pendingEvents[pendingEventsKey]?.put(timelineId, ArrayList())
}

if (pendingEvents[pendingEventsKey]!![timelineId]!!.indexOf(event) < 0) {
if (pendingEvents[pendingEventsKey]?.get(timelineId)?.contains(event) == false) {
Timber.v("## addEventToPendingList() : add Event " + event.eventId + " in room id " + event.roomId)
pendingEvents[pendingEventsKey]!![timelineId]!!.add(event)
pendingEvents[pendingEventsKey]?.get(timelineId)?.add(event)
}
}


View File

@ -17,7 +17,6 @@

package im.vector.matrix.android.internal.crypto.algorithms.olm

import android.text.TextUtils
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
@ -44,36 +43,47 @@ internal class MXOlmDecryption(

@Throws(MXDecryptionException::class)
override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
val olmEventContent = event.content.toModel<OlmEventContent>()!!
val olmEventContent = event.content.toModel<OlmEventContent>() ?: run {
Timber.e("## decryptEvent() : bad event format")
throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_EVENT_FORMAT_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_EVENT_FORMAT_TEXT_REASON))
}

if (null == olmEventContent.ciphertext) {
val cipherText = olmEventContent.ciphertext ?: run {
Timber.e("## decryptEvent() : missing cipher text")
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_CIPHER_TEXT_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON))
}

if (!olmEventContent.ciphertext!!.containsKey(olmDevice.deviceCurve25519Key)) {
Timber.e("## decryptEvent() : our device " + olmDevice.deviceCurve25519Key
+ " is not included in recipients. Event")
val senderKey = olmEventContent.senderKey ?: run {
Timber.e("## decryptEvent() : missing sender key")
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_SENDER_KEY_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_SENDER_KEY_TEXT_REASON))
}

val messageAny = cipherText[olmDevice.deviceCurve25519Key] ?: run {
Timber.e("## decryptEvent() : our device ${olmDevice.deviceCurve25519Key} is not included in recipients")
throw MXDecryptionException(MXCryptoError(MXCryptoError.NOT_INCLUDE_IN_RECIPIENTS_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.NOT_INCLUDED_IN_RECIPIENT_REASON))
}

// The message for myUser
val message = olmEventContent.ciphertext!![olmDevice.deviceCurve25519Key] as JsonDict
val decryptedPayload = decryptMessage(message, olmEventContent.senderKey!!)
val message = messageAny as JsonDict

val decryptedPayload = decryptMessage(message, senderKey)

if (decryptedPayload == null) {
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= " + event.eventId + " ) from " + olmEventContent.senderKey)
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= ${event.eventId} from $senderKey")
throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
}
val payloadString = convertFromUTF8(decryptedPayload)
if (payloadString == null) {
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= " + event.eventId + " ) from " + olmEventContent.senderKey)
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= ${event.eventId} from $senderKey")
throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
}

val adapter = MoshiProvider.providesMoshi().adapter<JsonDict>(JSON_DICT_PARAMETERIZED_TYPE)
val payload = adapter.fromJson(payloadString)

@ -83,59 +93,58 @@ internal class MXOlmDecryption(
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON))
}

val olmPayloadContent = OlmPayloadContent.fromJsonString(payloadString)
val olmPayloadContent = OlmPayloadContent.fromJsonString(payloadString) ?: run {
Timber.e("## decryptEvent() : bad olmPayloadContent format")
throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_DECRYPTED_FORMAT_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON))
}

if (TextUtils.isEmpty(olmPayloadContent.recipient)) {
if (olmPayloadContent.recipient.isNullOrBlank()) {
val reason = String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient")
Timber.e("## decryptEvent() : $reason")
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_PROPERTY_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, reason))
}

if (!TextUtils.equals(olmPayloadContent.recipient, credentials.userId)) {
Timber.e("## decryptEvent() : Event " + event.eventId + ": Intended recipient " + olmPayloadContent.recipient
+ " does not match our id " + credentials.userId)
if (olmPayloadContent.recipient != credentials.userId) {
Timber.e("## decryptEvent() : Event ${event.eventId}: Intended recipient ${olmPayloadContent.recipient} does not match our id ${credentials.userId}")
throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_RECIPIENT_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)))
}

if (null == olmPayloadContent.recipient_keys) {
Timber.e("## decryptEvent() : Olm event (id=" + event.eventId
+ ") contains no " + "'recipient_keys' property; cannot prevent unknown-key attack")
val recipientKeys = olmPayloadContent.recipient_keys ?: run {
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys' property; cannot prevent unknown-key attack")
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_PROPERTY_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys")))
}

val ed25519 = olmPayloadContent.recipient_keys!!.get("ed25519")
val ed25519 = recipientKeys["ed25519"]

if (!TextUtils.equals(ed25519, olmDevice.deviceEd25519Key)) {
Timber.e("## decryptEvent() : Event " + event.eventId + ": Intended recipient ed25519 key " + ed25519 + " did not match ours")
if (ed25519 != olmDevice.deviceEd25519Key) {
Timber.e("## decryptEvent() : Event ${event.eventId}: Intended recipient ed25519 key $ed25519 did not match ours")
throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_RECIPIENT_KEY_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_RECIPIENT_KEY_REASON))
}

if (TextUtils.isEmpty(olmPayloadContent.sender)) {
Timber.e("## decryptEvent() : Olm event (id=" + event.eventId
+ ") contains no 'sender' property; cannot prevent unknown-key attack")
if (olmPayloadContent.sender.isNullOrBlank()) {
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'sender' property; cannot prevent unknown-key attack")
throw MXDecryptionException(MXCryptoError(MXCryptoError.MISSING_PROPERTY_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender")))
}

if (!TextUtils.equals(olmPayloadContent.sender, event.senderId)) {
Timber.e("Event " + event.eventId + ": original sender " + olmPayloadContent.sender
+ " does not match reported sender " + event.senderId)
if (olmPayloadContent.sender != event.senderId) {
Timber.e("Event ${event.eventId}: original sender ${olmPayloadContent.sender} does not match reported sender ${event.senderId}")
throw MXDecryptionException(MXCryptoError(MXCryptoError.FORWARDED_MESSAGE_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)))
}

if (!TextUtils.equals(olmPayloadContent.room_id, event.roomId)) {
Timber.e("## decryptEvent() : Event " + event.eventId + ": original room " + olmPayloadContent.room_id
+ " does not match reported room " + event.roomId)
if (olmPayloadContent.room_id != event.roomId) {
Timber.e("## decryptEvent() : Event ${event.eventId}: original room ${olmPayloadContent.room_id} does not match reported room ${event.roomId}")
throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_ROOM_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.room_id)))
}

if (null == olmPayloadContent.keys) {
val keys = olmPayloadContent.keys ?: run {
Timber.e("## decryptEvent failed : null keys")
throw MXDecryptionException(MXCryptoError(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE,
MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON))
@ -143,8 +152,8 @@ internal class MXOlmDecryption(

val result = MXEventDecryptionResult()
result.clearEvent = payload
result.senderCurve25519Key = olmEventContent.senderKey
result.claimedEd25519Key = olmPayloadContent.keys!!.get("ed25519")
result.senderCurve25519Key = senderKey
result.claimedEd25519Key = keys["ed25519"]

return result
}
@ -167,7 +176,7 @@ internal class MXOlmDecryption(
sessionIds = ArrayList(sessionIdsSet)
}

val messageBody = message["body"] as String?
val messageBody = message["body"] as? String
var messageType: Int? = null

val typeAsVoid = message["type"]
@ -210,7 +219,7 @@ internal class MXOlmDecryption(
// not a prekey message, so it should have matched an existing session, but it
// didn't work.

if (sessionIds.size == 0) {
if (sessionIds.isEmpty()) {
Timber.e("## decryptMessage() : No existing sessions")
} else {
Timber.e("## decryptMessage() : Error decrypting non-prekey message with existing sessions")
@ -228,7 +237,7 @@ internal class MXOlmDecryption(
return null
}

Timber.v("## decryptMessage() : Created new inbound Olm session get id " + res["session_id"] + " with " + theirDeviceIdentityKey)
Timber.v("## decryptMessage() : Created new inbound Olm session get id ${res["session_id"]} with $theirDeviceIdentityKey")

return res["payload"]
}

View File

@ -24,10 +24,11 @@ import kotlinx.android.parcel.Parcelize
fun EncryptedFileInfo.toElementToDecrypt(): ElementToDecrypt? {
// Check the validity of some fields
if (isValid()) {
// It's valid so the data are here
return ElementToDecrypt(
iv = this.iv!!,
k = this.key!!.k!!,
sha256 = this.hashes!!["sha256"] ?: error("")
iv = this.iv ?: "",
k = this.key?.k ?: "",
sha256 = this.hashes?.get("sha256") ?: ""
)
}


View File

@ -45,7 +45,6 @@ import im.vector.matrix.android.internal.crypto.keysbackup.tasks.*
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.model.ImportRoomKeysResult
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.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.store.db.model.KeysBackupDataEntity
@ -388,8 +387,8 @@ internal class KeysBackup @Inject constructor(
return keysBackupVersionTrust
}

val mySigs: Map<String, *> = authData.signatures!![myUserId] as Map<String, *>
if (mySigs.isEmpty()) {
val mySigs = authData.signatures?.get(myUserId)
if (mySigs.isNullOrEmpty()) {
Timber.v("getKeysBackupTrust: Ignoring key backup because it lacks any signatures from this user")
return keysBackupVersionTrust
}
@ -402,20 +401,21 @@ internal class KeysBackup @Inject constructor(
deviceId = components[1]
}

var device: MXDeviceInfo? = null
if (deviceId != null) {
device = cryptoStore.getUserDevice(deviceId, myUserId)

val device = cryptoStore.getUserDevice(deviceId, myUserId)
var isSignatureValid = false

if (device == null) {
Timber.v("getKeysBackupTrust: Signature from unknown device $deviceId")
} else {
try {
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)
val fingerprint = device.fingerprint()
if (fingerprint != null) {
try {
olmDevice.verifySignature(fingerprint, authData.signalableJSONDictionary(), mySigs[keyId] as String)
isSignatureValid = true
} catch (e: OlmException) {
Timber.v("getKeysBackupTrust: Bad signature from device " + device.deviceId + " " + e.localizedMessage)
}
}

if (isSignatureValid && device.isVerified) {
@ -452,8 +452,7 @@ internal class KeysBackup @Inject constructor(
val myUserId = credentials.userId

// Get current signatures, or create an empty set
val myUserSignatures = (authData.signatures!![myUserId]?.toMutableMap()
?: HashMap())
val myUserSignatures = authData.signatures?.get(myUserId)?.toMutableMap() ?: HashMap()

if (trust) {
// Add current device signature
@ -1027,8 +1026,7 @@ internal class KeysBackup @Inject constructor(

val authData = keysBackupData.getAuthDataAsMegolmBackupAuthData()

if (authData.signatures == null
|| authData.publicKey.isBlank()) {
if (authData?.signatures == null || authData.publicKey.isBlank()) {
return null
}


View File

@ -54,9 +54,9 @@ open class KeysAlgorithmAndData {
/**
* Facility method to convert authData to a MegolmBackupAuthData object
*/
fun getAuthDataAsMegolmBackupAuthData(): MegolmBackupAuthData {
fun getAuthDataAsMegolmBackupAuthData(): MegolmBackupAuthData? {
return MoshiProvider.providesMoshi()
.adapter(MegolmBackupAuthData::class.java)
.fromJsonValue(authData)!!
.fromJsonValue(authData)
}
}

View File

@ -18,7 +18,6 @@

package im.vector.matrix.android.internal.crypto.model

import android.text.TextUtils
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.util.JsonDict
@ -107,30 +106,25 @@ data class MXDeviceInfo(
* @return the fingerprint
*/
fun fingerprint(): String? {
return if (null != keys && !TextUtils.isEmpty(deviceId)) {
keys!!["ed25519:$deviceId"]
} else null

return keys
?.takeIf { !deviceId.isBlank() }
?.get("ed25519:$deviceId")
}

/**
* @return the identity key
*/
fun identityKey(): String? {
return if (null != keys && !TextUtils.isEmpty(deviceId)) {
keys!!["curve25519:$deviceId"]
} else null

return keys
?.takeIf { !deviceId.isBlank() }
?.get("curve25519:$deviceId")
}

/**
* @return the display name
*/
fun displayName(): String? {
return if (null != unsigned) {
unsigned!!["device_display_name"] as String?
} else null

return unsigned?.get("device_display_name") as? String
}

/**
@ -141,9 +135,7 @@ data class MXDeviceInfo(

map["device_id"] = deviceId

if (null != userId) {
map["user_id"] = userId!!
}
map["user_id"] = userId

if (null != algorithms) {
map["algorithms"] = algorithms!!

View File

@ -54,7 +54,7 @@ class MXUsersDevicesMap<E> {
*/
fun getObject(userId: String?, deviceId: String?): E? {
return if (userId?.isNotBlank() == true && deviceId?.isNotBlank() == true && map.containsKey(userId)) {
map[userId]!![deviceId]
map[userId]?.get(deviceId)
} else null
}

@ -71,7 +71,7 @@ class MXUsersDevicesMap<E> {
map[userId] = HashMap()
}

map[userId]!![deviceId] = o
map[userId]?.put(deviceId, o)
}
}


View File

@ -111,27 +111,29 @@ class OlmInboundGroupSessionWrapper : Serializable {
* @return the inbound group session as MegolmSessionData if the operation succeeds
*/
fun exportKeys(): MegolmSessionData? {
var megolmSessionData: MegolmSessionData? = MegolmSessionData()

try {
return try {
if (null == forwardingCurve25519KeyChain) {
forwardingCurve25519KeyChain = ArrayList()
}

megolmSessionData!!.senderClaimedEd25519Key = keysClaimed!!["ed25519"]
megolmSessionData.forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!)
megolmSessionData.senderKey = senderKey
megolmSessionData.senderClaimedKeys = keysClaimed
megolmSessionData.roomId = roomId
megolmSessionData.sessionId = olmInboundGroupSession!!.sessionIdentifier()
megolmSessionData.sessionKey = olmInboundGroupSession!!.export(olmInboundGroupSession!!.firstKnownIndex)
megolmSessionData.algorithm = MXCRYPTO_ALGORITHM_MEGOLM
} catch (e: Exception) {
megolmSessionData = null
Timber.e(e, "## export() : senderKey " + senderKey + " failed")
}
if (keysClaimed == null) {
return null
}

return megolmSessionData
MegolmSessionData().also {
it.senderClaimedEd25519Key = keysClaimed?.get("ed25519")
it.forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!)
it.senderKey = senderKey
it.senderClaimedKeys = keysClaimed
it.roomId = roomId
it.sessionId = olmInboundGroupSession!!.sessionIdentifier()
it.sessionKey = olmInboundGroupSession!!.export(olmInboundGroupSession!!.firstKnownIndex)
it.algorithm = MXCRYPTO_ALGORITHM_MEGOLM
}
} catch (e: Exception) {
Timber.e(e, "## export() : senderKey $senderKey failed")
null
}
}

/**

View File

@ -53,8 +53,8 @@ data class OlmPayloadContent(
}

companion object {
fun fromJsonString(str: String): OlmPayloadContent {
return MoshiProvider.providesMoshi().adapter(OlmPayloadContent::class.java).fromJson(str)!!
fun fromJsonString(str: String): OlmPayloadContent? {
return MoshiProvider.providesMoshi().adapter(OlmPayloadContent::class.java).fromJson(str)
}
}
}

View File

@ -46,17 +46,19 @@ internal class DefaultClaimOneTimeKeysForUsersDevice @Inject constructor(private
Try {
val map = MXUsersDevicesMap<MXKey>()

if (null != keysClaimResponse.oneTimeKeys) {
for (userId in keysClaimResponse.oneTimeKeys!!.keys) {
val mapByUserId = keysClaimResponse.oneTimeKeys!![userId]
keysClaimResponse.oneTimeKeys?.let { oneTimeKeys ->
for (userId in oneTimeKeys.keys) {
val mapByUserId = oneTimeKeys[userId]

for (deviceId in mapByUserId!!.keys) {
val mxKey = MXKey.from(mapByUserId[deviceId])
if (mapByUserId != null) {
for (deviceId in mapByUserId.keys) {
val mxKey = MXKey.from(mapByUserId[deviceId])

if (mxKey != null) {
map.setObject(userId, deviceId, mxKey)
} else {
Timber.e("## claimOneTimeKeysForUsersDevices : fail to create a MXKey")
if (mxKey != null) {
map.setObject(userId, deviceId, mxKey)
} else {
Timber.e("## claimOneTimeKeysForUsersDevices : fail to create a MXKey")
}
}
}
}

View File

@ -47,7 +47,7 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
viewModel.keyVersionResult.observe(this, Observer { keyVersion ->

if (keyVersion != null && supportFragmentManager.fragments.isEmpty()) {
val isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData().privateKeySalt != null
val isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
if (isBackupCreatedFromPassphrase) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, KeysBackupRestoreFromPassphraseFragment.newInstance())