Create enum for errorType and fix a few issues
This commit is contained in:
parent
07f80f43bd
commit
4a512d2425
@ -98,6 +98,7 @@ interface CryptoService {
|
|||||||
roomId: String,
|
roomId: String,
|
||||||
callback: MatrixCallback<MXEncryptEventContentResult>)
|
callback: MatrixCallback<MXEncryptEventContentResult>)
|
||||||
|
|
||||||
|
@Throws(MXCryptoError::class)
|
||||||
fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
|
fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
|
||||||
|
|
||||||
fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>)
|
fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>)
|
||||||
|
@ -20,62 +20,56 @@ package im.vector.matrix.android.api.session.crypto
|
|||||||
|
|
||||||
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.MXUsersDevicesMap
|
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
|
||||||
|
import org.matrix.olm.OlmException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a crypto error response.
|
* Represents a crypto error response.
|
||||||
*/
|
*/
|
||||||
sealed class MXCryptoError : Throwable() {
|
sealed class MXCryptoError : Throwable() {
|
||||||
|
|
||||||
// TODO Create data class for all cases, and remove error code
|
data class Base(val errorType: ErrorType,
|
||||||
data class Base(val code: String,
|
val technicalMessage: String,
|
||||||
val _message: String,
|
|
||||||
/**
|
/**
|
||||||
* Describe the error with more details
|
* Describe the error with more details
|
||||||
*/
|
*/
|
||||||
val detailedErrorDescription: String? = null) : MXCryptoError()
|
val detailedErrorDescription: String? = null) : MXCryptoError()
|
||||||
|
|
||||||
|
data class OlmError(val olmException: OlmException) : MXCryptoError()
|
||||||
|
|
||||||
data class UnknownDevice(val deviceList: MXUsersDevicesMap<MXDeviceInfo>) : MXCryptoError()
|
data class UnknownDevice(val deviceList: MXUsersDevicesMap<MXDeviceInfo>) : MXCryptoError()
|
||||||
|
|
||||||
|
enum class ErrorType {
|
||||||
|
ENCRYPTING_NOT_ENABLED_ERROR_CODE,
|
||||||
|
UNABLE_TO_ENCRYPT_ERROR_CODE,
|
||||||
|
UNABLE_TO_DECRYPT_ERROR_CODE,
|
||||||
|
UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE,
|
||||||
|
INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE,
|
||||||
|
MISSING_FIELDS_ERROR_CODE,
|
||||||
|
BAD_EVENT_FORMAT_ERROR_CODE,
|
||||||
|
MISSING_SENDER_KEY_ERROR_CODE,
|
||||||
|
MISSING_CIPHER_TEXT_ERROR_CODE,
|
||||||
|
BAD_DECRYPTED_FORMAT_ERROR_CODE,
|
||||||
|
NOT_INCLUDE_IN_RECIPIENTS_ERROR_CODE,
|
||||||
|
BAD_RECIPIENT_ERROR_CODE,
|
||||||
|
BAD_RECIPIENT_KEY_ERROR_CODE,
|
||||||
|
FORWARDED_MESSAGE_ERROR_CODE,
|
||||||
|
BAD_ROOM_ERROR_CODE,
|
||||||
|
BAD_ENCRYPTED_MESSAGE_ERROR_CODE,
|
||||||
|
DUPLICATED_MESSAGE_INDEX_ERROR_CODE,
|
||||||
|
MISSING_PROPERTY_ERROR_CODE,
|
||||||
|
OLM_ERROR_CODE,
|
||||||
|
UNKNOWN_DEVICES_CODE,
|
||||||
|
UNKNOWN_MESSAGE_INDEX
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Error codes
|
* Resource for technicalMessage
|
||||||
*/
|
*/
|
||||||
const val ENCRYPTING_NOT_ENABLED_ERROR_CODE = "ENCRYPTING_NOT_ENABLED"
|
|
||||||
const val UNABLE_TO_ENCRYPT_ERROR_CODE = "UNABLE_TO_ENCRYPT"
|
|
||||||
const val UNABLE_TO_DECRYPT_ERROR_CODE = "UNABLE_TO_DECRYPT"
|
|
||||||
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"
|
|
||||||
const val FORWARDED_MESSAGE_ERROR_CODE = "FORWARDED_MESSAGE"
|
|
||||||
const val BAD_ROOM_ERROR_CODE = "BAD_ROOM"
|
|
||||||
const val BAD_ENCRYPTED_MESSAGE_ERROR_CODE = "BAD_ENCRYPTED_MESSAGE"
|
|
||||||
const val DUPLICATED_MESSAGE_INDEX_ERROR_CODE = "DUPLICATED_MESSAGE_INDEX"
|
|
||||||
const val MISSING_PROPERTY_ERROR_CODE = "MISSING_PROPERTY"
|
|
||||||
const val OLM_ERROR_CODE = "OLM_ERROR_CODE"
|
|
||||||
const val UNKNOWN_DEVICES_CODE = "UNKNOWN_DEVICES_CODE"
|
|
||||||
const val UNKNOWN_MESSAGE_INDEX = "UNKNOWN_MESSAGE_INDEX"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* short error reasons
|
|
||||||
*/
|
|
||||||
const val UNABLE_TO_DECRYPT = "Unable to decrypt"
|
|
||||||
const val UNABLE_TO_ENCRYPT = "Unable to encrypt"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detailed error reasons
|
|
||||||
*/
|
|
||||||
const val ENCRYPTING_NOT_ENABLED_REASON = "Encryption not enabled"
|
|
||||||
const val UNABLE_TO_ENCRYPT_REASON = "Unable to encrypt %s"
|
const val UNABLE_TO_ENCRYPT_REASON = "Unable to encrypt %s"
|
||||||
const val UNABLE_TO_DECRYPT_REASON = "Unable to decrypt %1\$s. Algorithm: %2\$s"
|
const val UNABLE_TO_DECRYPT_REASON = "Unable to decrypt %1\$s. Algorithm: %2\$s"
|
||||||
const val OLM_REASON = "OLM error: %1\$s"
|
const val OLM_REASON = "OLM error: %1\$s"
|
||||||
const val DETAILLED_OLM_REASON = "Unable to decrypt %1\$s. OLM error: %2\$s"
|
const val DETAILED_OLM_REASON = "Unable to decrypt %1\$s. OLM error: %2\$s"
|
||||||
const val UNKNOWN_INBOUND_SESSION_ID_REASON = "Unknown inbound session id"
|
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 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 MISSING_FIELDS_REASON = "Missing fields in input"
|
||||||
|
@ -569,7 +569,7 @@ internal class CryptoManager @Inject constructor(
|
|||||||
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
|
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
|
||||||
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON)
|
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON)
|
||||||
Timber.e("## encryptEventContent() : $reason")
|
Timber.e("## encryptEventContent() : $reason")
|
||||||
callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.UNABLE_TO_ENCRYPT_ERROR_CODE, reason)))
|
callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT_ERROR_CODE, reason)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,14 +618,14 @@ internal class CryptoManager @Inject constructor(
|
|||||||
val eventContent = event.content
|
val eventContent = event.content
|
||||||
return if (eventContent == null) {
|
return if (eventContent == null) {
|
||||||
Timber.e("## decryptEvent : empty event content")
|
Timber.e("## decryptEvent : empty event content")
|
||||||
Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
|
Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE_ERROR_CODE, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
|
||||||
} else {
|
} else {
|
||||||
val algorithm = eventContent["algorithm"]?.toString()
|
val algorithm = eventContent["algorithm"]?.toString()
|
||||||
val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(event.roomId, algorithm)
|
val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(event.roomId, algorithm)
|
||||||
if (alg == null) {
|
if (alg == null) {
|
||||||
val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, algorithm)
|
val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, algorithm)
|
||||||
Timber.e("## decryptEvent() : $reason")
|
Timber.e("## decryptEvent() : $reason")
|
||||||
Try.Failure(MXCryptoError.Base(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE, reason))
|
Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT_ERROR_CODE, reason))
|
||||||
} else {
|
} else {
|
||||||
alg.decryptEvent(event, timeline)
|
alg.decryptEvent(event, timeline)
|
||||||
}
|
}
|
||||||
|
@ -653,16 +653,14 @@ internal class MXOlmDevice @Inject constructor(
|
|||||||
// Check that the room id matches the original one for the session. This stops
|
// Check that the room id matches the original one for the session. This stops
|
||||||
// the HS pretending a message was targeting a different room.
|
// the HS pretending a message was targeting a different room.
|
||||||
if (roomId == session.roomId) {
|
if (roomId == session.roomId) {
|
||||||
var errorMessage = ""
|
|
||||||
var decryptResult: OlmInboundGroupSession.DecryptMessageResult? = null
|
var decryptResult: OlmInboundGroupSession.DecryptMessageResult? = null
|
||||||
try {
|
try {
|
||||||
decryptResult = session.olmInboundGroupSession!!.decryptMessage(body)
|
decryptResult = session.olmInboundGroupSession!!.decryptMessage(body)
|
||||||
} catch (e: Exception) {
|
} catch (e: OlmException) {
|
||||||
Timber.e(e, "## decryptGroupMessage () : decryptMessage failed")
|
Timber.e(e, "## decryptGroupMessage () : decryptMessage failed")
|
||||||
errorMessage = e.message ?: ""
|
return@flatMap Try.Failure(MXCryptoError.OlmError(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null != decryptResult) {
|
|
||||||
if (null != timeline) {
|
if (null != timeline) {
|
||||||
if (!inboundGroupSessionMessageIndexes.containsKey(timeline)) {
|
if (!inboundGroupSessionMessageIndexes.containsKey(timeline)) {
|
||||||
inboundGroupSessionMessageIndexes[timeline] = HashMap()
|
inboundGroupSessionMessageIndexes[timeline] = HashMap()
|
||||||
@ -673,7 +671,7 @@ internal class MXOlmDevice @Inject constructor(
|
|||||||
if (inboundGroupSessionMessageIndexes[timeline]?.get(messageIndexKey) != null) {
|
if (inboundGroupSessionMessageIndexes[timeline]?.get(messageIndexKey) != null) {
|
||||||
val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex)
|
val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex)
|
||||||
Timber.e("## decryptGroupMessage() : $reason")
|
Timber.e("## decryptGroupMessage() : $reason")
|
||||||
return@flatMap Try.Failure(MXCryptoError.Base(MXCryptoError.DUPLICATED_MESSAGE_INDEX_ERROR_CODE, reason))
|
return@flatMap Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX_ERROR_CODE, reason))
|
||||||
}
|
}
|
||||||
|
|
||||||
inboundGroupSessionMessageIndexes[timeline]!!.put(messageIndexKey, true)
|
inboundGroupSessionMessageIndexes[timeline]!!.put(messageIndexKey, true)
|
||||||
@ -686,7 +684,7 @@ internal class MXOlmDevice @Inject constructor(
|
|||||||
adapter.fromJson(payloadString)
|
adapter.fromJson(payloadString)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e("## decryptGroupMessage() : fails to parse the payload")
|
Timber.e("## decryptGroupMessage() : fails to parse the payload")
|
||||||
return@flatMap Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_DECRYPTED_FORMAT_ERROR_CODE, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON))
|
return@flatMap Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT_ERROR_CODE, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
return@flatMap Try.just(
|
return@flatMap Try.just(
|
||||||
@ -697,14 +695,10 @@ internal class MXOlmDevice @Inject constructor(
|
|||||||
session.forwardingCurve25519KeyChain
|
session.forwardingCurve25519KeyChain
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
Timber.e("## decryptGroupMessage() : failed to decode the message")
|
|
||||||
return@flatMap Try.Failure(MXCryptoError.Base(MXCryptoError.OLM_ERROR_CODE, errorMessage))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val reason = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, session.roomId)
|
val reason = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, session.roomId)
|
||||||
Timber.e("## decryptGroupMessage() : $reason")
|
Timber.e("## decryptGroupMessage() : $reason")
|
||||||
return@flatMap Try.Failure(MXCryptoError.Base(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE, reason))
|
return@flatMap Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE, reason))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -772,7 +766,7 @@ internal class MXOlmDevice @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): Try<OlmInboundGroupSessionWrapper> {
|
fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): Try<OlmInboundGroupSessionWrapper> {
|
||||||
if (sessionId.isNullOrBlank() || senderKey.isNullOrBlank()) {
|
if (sessionId.isNullOrBlank() || senderKey.isNullOrBlank()) {
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.MISSING_SENDER_KEY_ERROR_CODE, MXCryptoError.ERROR_MISSING_PROPERTY_REASON))
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_SENDER_KEY_ERROR_CODE, MXCryptoError.ERROR_MISSING_PROPERTY_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
val session = store.getInboundGroupSession(sessionId, senderKey)
|
val session = store.getInboundGroupSession(sessionId, senderKey)
|
||||||
@ -783,13 +777,13 @@ internal class MXOlmDevice @Inject constructor(
|
|||||||
if (!TextUtils.equals(roomId, session.roomId)) {
|
if (!TextUtils.equals(roomId, session.roomId)) {
|
||||||
val errorDescription = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, session.roomId)
|
val errorDescription = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, session.roomId)
|
||||||
Timber.e("## getInboundGroupSession() : $errorDescription")
|
Timber.e("## getInboundGroupSession() : $errorDescription")
|
||||||
Try.Failure(MXCryptoError.Base(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE, errorDescription))
|
Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.INBOUND_SESSION_MISMATCH_ROOM_ID_ERROR_CODE, errorDescription))
|
||||||
} else {
|
} else {
|
||||||
Try.just(session)
|
Try.just(session)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Timber.e("## getInboundGroupSession() : Cannot retrieve inbound group session $sessionId")
|
Timber.e("## getInboundGroupSession() : Cannot retrieve inbound group session $sessionId")
|
||||||
Try.Failure(MXCryptoError.Base(MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE, MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_REASON))
|
Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE, MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_REASON))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,34 +69,37 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
|
|||||||
|
|
||||||
private fun decryptEvent(event: Event, timeline: String, requestKeysOnFail: Boolean): Try<MXEventDecryptionResult> {
|
private fun decryptEvent(event: Event, timeline: String, requestKeysOnFail: Boolean): Try<MXEventDecryptionResult> {
|
||||||
val encryptedEventContent = event.content.toModel<EncryptedEventContent>()
|
val encryptedEventContent = event.content.toModel<EncryptedEventContent>()
|
||||||
?: throw MXCryptoError.Base(MXCryptoError.MISSING_FIELDS_ERROR_CODE, MXCryptoError.MISSING_FIELDS_REASON)
|
?: return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS_ERROR_CODE, MXCryptoError.MISSING_FIELDS_REASON))
|
||||||
|
|
||||||
if (TextUtils.isEmpty(encryptedEventContent.senderKey)
|
if (TextUtils.isEmpty(encryptedEventContent.senderKey)
|
||||||
|| TextUtils.isEmpty(encryptedEventContent.sessionId)
|
|| TextUtils.isEmpty(encryptedEventContent.sessionId)
|
||||||
|| TextUtils.isEmpty(encryptedEventContent.ciphertext)) {
|
|| TextUtils.isEmpty(encryptedEventContent.ciphertext)) {
|
||||||
throw MXCryptoError.Base(MXCryptoError.MISSING_FIELDS_ERROR_CODE, MXCryptoError.MISSING_FIELDS_REASON)
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS_ERROR_CODE, MXCryptoError.MISSING_FIELDS_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Why AS says this code is unreachable?
|
||||||
return olmDevice.decryptGroupMessage(encryptedEventContent.ciphertext!!, event.roomId!!, timeline, encryptedEventContent.sessionId!!, encryptedEventContent.senderKey!!)
|
return olmDevice.decryptGroupMessage(encryptedEventContent.ciphertext!!, event.roomId!!, timeline, encryptedEventContent.sessionId!!, encryptedEventContent.senderKey!!)
|
||||||
.fold(
|
.fold(
|
||||||
{ throwable ->
|
{ throwable ->
|
||||||
if (throwable is MXCryptoError.Base) {
|
if (throwable is MXCryptoError.OlmError) {
|
||||||
if (throwable.code == MXCryptoError.OLM_ERROR_CODE) {
|
// TODO Check the value of .message
|
||||||
if (MXCryptoError.UNKNOWN_MESSAGE_INDEX == throwable._message) {
|
if (throwable.olmException.message == "UNKNOWN_MESSAGE_INDEX") {
|
||||||
addEventToPendingList(event, timeline)
|
addEventToPendingList(event, timeline)
|
||||||
if (requestKeysOnFail) {
|
if (requestKeysOnFail) {
|
||||||
requestKeysForEvent(event)
|
requestKeysForEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val reason = String.format(MXCryptoError.OLM_REASON, throwable._message)
|
val reason = String.format(MXCryptoError.OLM_REASON, throwable.olmException.message)
|
||||||
val detailedReason = String.format(MXCryptoError.DETAILLED_OLM_REASON, encryptedEventContent.ciphertext, throwable._message)
|
val detailedReason = String.format(MXCryptoError.DETAILED_OLM_REASON, encryptedEventContent.ciphertext, reason)
|
||||||
|
|
||||||
throw MXCryptoError.Base(
|
return Try.Failure(MXCryptoError.Base(
|
||||||
MXCryptoError.OLM_ERROR_CODE,
|
MXCryptoError.ErrorType.OLM_ERROR_CODE,
|
||||||
reason,
|
reason,
|
||||||
detailedReason)
|
detailedReason))
|
||||||
} else if (throwable.code == MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE) {
|
}
|
||||||
|
if (throwable is MXCryptoError.Base) {
|
||||||
|
if (throwable.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE) {
|
||||||
addEventToPendingList(event, timeline)
|
addEventToPendingList(event, timeline)
|
||||||
if (requestKeysOnFail) {
|
if (requestKeysOnFail) {
|
||||||
requestKeysForEvent(event)
|
requestKeysForEvent(event)
|
||||||
@ -104,12 +107,12 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw throwable
|
return Try.Failure(throwable)
|
||||||
},
|
},
|
||||||
{ decryptionResult ->
|
{ decryptionResult ->
|
||||||
// the decryption succeeds
|
// the decryption succeeds
|
||||||
if (decryptionResult.payload != null) {
|
return if (decryptionResult.payload != null) {
|
||||||
return Try.just(
|
Try.just(
|
||||||
MXEventDecryptionResult(
|
MXEventDecryptionResult(
|
||||||
clearEvent = decryptionResult.payload,
|
clearEvent = decryptionResult.payload,
|
||||||
senderCurve25519Key = decryptionResult.senderKey,
|
senderCurve25519Key = decryptionResult.senderKey,
|
||||||
@ -118,7 +121,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
throw MXCryptoError.Base(MXCryptoError.MISSING_FIELDS_ERROR_CODE, MXCryptoError.MISSING_FIELDS_REASON)
|
Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS_ERROR_CODE, MXCryptoError.MISSING_FIELDS_REASON))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -44,25 +44,25 @@ internal class MXOlmDecryption(
|
|||||||
override suspend fun decryptEvent(event: Event, timeline: String): Try<MXEventDecryptionResult> {
|
override suspend fun decryptEvent(event: Event, timeline: String): Try<MXEventDecryptionResult> {
|
||||||
val olmEventContent = event.content.toModel<OlmEventContent>() ?: run {
|
val olmEventContent = event.content.toModel<OlmEventContent>() ?: run {
|
||||||
Timber.e("## decryptEvent() : bad event format")
|
Timber.e("## decryptEvent() : bad event format")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_EVENT_FORMAT_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_EVENT_FORMAT_ERROR_CODE,
|
||||||
MXCryptoError.BAD_EVENT_FORMAT_TEXT_REASON))
|
MXCryptoError.BAD_EVENT_FORMAT_TEXT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
val cipherText = olmEventContent.ciphertext ?: run {
|
val cipherText = olmEventContent.ciphertext ?: run {
|
||||||
Timber.e("## decryptEvent() : missing cipher text")
|
Timber.e("## decryptEvent() : missing cipher text")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.MISSING_CIPHER_TEXT_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_CIPHER_TEXT_ERROR_CODE,
|
||||||
MXCryptoError.MISSING_CIPHER_TEXT_REASON))
|
MXCryptoError.MISSING_CIPHER_TEXT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
val senderKey = olmEventContent.senderKey ?: run {
|
val senderKey = olmEventContent.senderKey ?: run {
|
||||||
Timber.e("## decryptEvent() : missing sender key")
|
Timber.e("## decryptEvent() : missing sender key")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.MISSING_SENDER_KEY_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_SENDER_KEY_ERROR_CODE,
|
||||||
MXCryptoError.MISSING_SENDER_KEY_TEXT_REASON))
|
MXCryptoError.MISSING_SENDER_KEY_TEXT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
val messageAny = cipherText[olmDevice.deviceCurve25519Key] ?: run {
|
val messageAny = cipherText[olmDevice.deviceCurve25519Key] ?: run {
|
||||||
Timber.e("## decryptEvent() : our device ${olmDevice.deviceCurve25519Key} is not included in recipients")
|
Timber.e("## decryptEvent() : our device ${olmDevice.deviceCurve25519Key} is not included in recipients")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.NOT_INCLUDE_IN_RECIPIENTS_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.NOT_INCLUDE_IN_RECIPIENTS_ERROR_CODE,
|
||||||
MXCryptoError.NOT_INCLUDED_IN_RECIPIENT_REASON))
|
MXCryptoError.NOT_INCLUDED_IN_RECIPIENT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,13 +73,13 @@ internal class MXOlmDecryption(
|
|||||||
|
|
||||||
if (decryptedPayload == null) {
|
if (decryptedPayload == null) {
|
||||||
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= ${event.eventId} from $senderKey")
|
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= ${event.eventId} from $senderKey")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE_ERROR_CODE,
|
||||||
MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
|
MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
|
||||||
}
|
}
|
||||||
val payloadString = convertFromUTF8(decryptedPayload)
|
val payloadString = convertFromUTF8(decryptedPayload)
|
||||||
if (payloadString == null) {
|
if (payloadString == null) {
|
||||||
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= ${event.eventId} from $senderKey")
|
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= ${event.eventId} from $senderKey")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE_ERROR_CODE,
|
||||||
MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
|
MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,32 +88,32 @@ internal class MXOlmDecryption(
|
|||||||
|
|
||||||
if (payload == null) {
|
if (payload == null) {
|
||||||
Timber.e("## decryptEvent failed : null payload")
|
Timber.e("## decryptEvent failed : null payload")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT_ERROR_CODE,
|
||||||
MXCryptoError.MISSING_CIPHER_TEXT_REASON))
|
MXCryptoError.MISSING_CIPHER_TEXT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
val olmPayloadContent = OlmPayloadContent.fromJsonString(payloadString) ?: run {
|
val olmPayloadContent = OlmPayloadContent.fromJsonString(payloadString) ?: run {
|
||||||
Timber.e("## decryptEvent() : bad olmPayloadContent format")
|
Timber.e("## decryptEvent() : bad olmPayloadContent format")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_DECRYPTED_FORMAT_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT_ERROR_CODE,
|
||||||
MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON))
|
MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.recipient.isNullOrBlank()) {
|
if (olmPayloadContent.recipient.isNullOrBlank()) {
|
||||||
val reason = String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient")
|
val reason = String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient")
|
||||||
Timber.e("## decryptEvent() : $reason")
|
Timber.e("## decryptEvent() : $reason")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.MISSING_PROPERTY_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY_ERROR_CODE,
|
||||||
reason))
|
reason))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.recipient != credentials.userId) {
|
if (olmPayloadContent.recipient != credentials.userId) {
|
||||||
Timber.e("## decryptEvent() : Event ${event.eventId}: Intended recipient ${olmPayloadContent.recipient} does not match our id ${credentials.userId}")
|
Timber.e("## decryptEvent() : Event ${event.eventId}: Intended recipient ${olmPayloadContent.recipient} does not match our id ${credentials.userId}")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_RECIPIENT_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_RECIPIENT_ERROR_CODE,
|
||||||
String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)))
|
String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val recipientKeys = olmPayloadContent.recipient_keys ?: run {
|
val recipientKeys = olmPayloadContent.recipient_keys ?: run {
|
||||||
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys' property; cannot prevent unknown-key attack")
|
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys' property; cannot prevent unknown-key attack")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.MISSING_PROPERTY_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY_ERROR_CODE,
|
||||||
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys")))
|
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys")))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,31 +121,31 @@ internal class MXOlmDecryption(
|
|||||||
|
|
||||||
if (ed25519 != olmDevice.deviceEd25519Key) {
|
if (ed25519 != olmDevice.deviceEd25519Key) {
|
||||||
Timber.e("## decryptEvent() : Event ${event.eventId}: Intended recipient ed25519 key $ed25519 did not match ours")
|
Timber.e("## decryptEvent() : Event ${event.eventId}: Intended recipient ed25519 key $ed25519 did not match ours")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_RECIPIENT_KEY_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_RECIPIENT_KEY_ERROR_CODE,
|
||||||
MXCryptoError.BAD_RECIPIENT_KEY_REASON))
|
MXCryptoError.BAD_RECIPIENT_KEY_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.sender.isNullOrBlank()) {
|
if (olmPayloadContent.sender.isNullOrBlank()) {
|
||||||
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'sender' property; cannot prevent unknown-key attack")
|
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'sender' property; cannot prevent unknown-key attack")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.MISSING_PROPERTY_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY_ERROR_CODE,
|
||||||
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender")))
|
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender")))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.sender != event.senderId) {
|
if (olmPayloadContent.sender != event.senderId) {
|
||||||
Timber.e("Event ${event.eventId}: original sender ${olmPayloadContent.sender} does not match reported sender ${event.senderId}")
|
Timber.e("Event ${event.eventId}: original sender ${olmPayloadContent.sender} does not match reported sender ${event.senderId}")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.FORWARDED_MESSAGE_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.FORWARDED_MESSAGE_ERROR_CODE,
|
||||||
String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)))
|
String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.room_id != 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}")
|
Timber.e("## decryptEvent() : Event ${event.eventId}: original room ${olmPayloadContent.room_id} does not match reported room ${event.roomId}")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.BAD_ROOM_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ROOM_ERROR_CODE,
|
||||||
String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.room_id)))
|
String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.room_id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val keys = olmPayloadContent.keys ?: run {
|
val keys = olmPayloadContent.keys ?: run {
|
||||||
Timber.e("## decryptEvent failed : null keys")
|
Timber.e("## decryptEvent failed : null keys")
|
||||||
return Try.Failure(MXCryptoError.Base(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE,
|
return Try.Failure(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT_ERROR_CODE,
|
||||||
MXCryptoError.MISSING_CIPHER_TEXT_REASON))
|
MXCryptoError.MISSING_CIPHER_TEXT_REASON))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.internal.session.room.timeline
|
package im.vector.matrix.android.internal.session.room.timeline
|
||||||
|
|
||||||
import im.vector.matrix.android.api.failure.Failure
|
|
||||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||||
|
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.Event
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
@ -81,8 +81,8 @@ internal class SimpleTimelineEventFactory @Inject constructor(private val roomMe
|
|||||||
event.setClearData(result)
|
event.setClearData(result)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
Timber.e("Encrypted event: decryption failed")
|
Timber.e("Encrypted event: decryption failed")
|
||||||
if (failure is Failure.CryptoError) {
|
if (failure is MXCryptoError) {
|
||||||
event.setCryptoError(failure.error)
|
event.setCryptoError(failure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,9 +138,9 @@ internal class InMemoryTimelineEventFactory @Inject constructor(private val room
|
|||||||
decryptionCache[cacheKey] = result
|
decryptionCache[cacheKey] = result
|
||||||
event.setClearData(result)
|
event.setClearData(result)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
Timber.e("Encrypted event: decryption failed ${failure.localizedMessage}")
|
Timber.e("Encrypted event: decryption failed: $failure")
|
||||||
if (failure is Failure.CryptoError) {
|
if (failure is MXCryptoError) {
|
||||||
event.setCryptoError(failure.error)
|
event.setCryptoError(failure)
|
||||||
} else {
|
} else {
|
||||||
// Other error
|
// Other error
|
||||||
Timber.e("Other error, should be handled")
|
Timber.e("Other error, should be handled")
|
||||||
|
@ -49,11 +49,11 @@ class EncryptedItemFactory @Inject constructor(private val messageInformationDat
|
|||||||
val cryptoError = event.root.mCryptoError
|
val cryptoError = event.root.mCryptoError
|
||||||
val errorDescription =
|
val errorDescription =
|
||||||
if (cryptoError is MXCryptoError.Base) {
|
if (cryptoError is MXCryptoError.Base) {
|
||||||
if (cryptoError.code == MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE) {
|
if (cryptoError.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE) {
|
||||||
stringProvider.getString(R.string.notice_crypto_error_unkwown_inbound_session_id)
|
stringProvider.getString(R.string.notice_crypto_error_unkwown_inbound_session_id)
|
||||||
} else {
|
} else {
|
||||||
// TODO i18n
|
// TODO i18n
|
||||||
cryptoError._message
|
cryptoError.technicalMessage
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Cannot happen (for now)
|
// Cannot happen (for now)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user