mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Create asValidObject method - make it compiles.
This commit is contained in:
parent
7b5a50ec6e
commit
a3f8a53a52
@ -37,8 +37,12 @@ internal data class MessageVerificationDoneContent(
|
||||
return null
|
||||
}
|
||||
|
||||
return ValidVerificationDone
|
||||
return ValidVerificationDone(
|
||||
transactionID!!
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal object ValidVerificationDone
|
||||
internal data class ValidVerificationDone(
|
||||
val transactionID: String
|
||||
)
|
||||
|
@ -34,7 +34,7 @@ internal data class MessageVerificationStartContent(
|
||||
@Json(name = "secret") override val sharedSecret: String?
|
||||
) : VerificationInfoStart {
|
||||
|
||||
override fun toCanonicalJson(): String? {
|
||||
override fun toCanonicalJson(): String {
|
||||
return JsonCanonicalizer.getCanonicalJson(MessageVerificationStartContent::class.java, this)
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ internal data class KeyVerificationStart(
|
||||
@Json(name = "secret") override val sharedSecret: String? = null
|
||||
) : SendToDeviceObject, VerificationInfoStart {
|
||||
|
||||
override fun toCanonicalJson(): String? {
|
||||
override fun toCanonicalJson(): String {
|
||||
return JsonCanonicalizer.getCanonicalJson(KeyVerificationStart::class.java, this)
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ internal class DefaultIncomingSASDefaultVerificationTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVerificationStart(startReq: VerificationInfoStart) {
|
||||
override fun onVerificationStart(startReq: ValidVerificationInfoStart.SasVerificationInfoStart) {
|
||||
Timber.v("## SAS I: received verification request from state $state")
|
||||
if (state != VerificationTxState.None) {
|
||||
Timber.e("## SAS I: received verification request from invalid state")
|
||||
@ -100,10 +100,10 @@ internal class DefaultIncomingSASDefaultVerificationTransaction(
|
||||
|
||||
// Select a key agreement protocol, a hash algorithm, a message authentication code,
|
||||
// and short authentication string methods out of the lists given in requester's message.
|
||||
val agreedProtocol = startReq!!.keyAgreementProtocols?.firstOrNull { KNOWN_AGREEMENT_PROTOCOLS.contains(it) }
|
||||
val agreedHash = startReq!!.hashes?.firstOrNull { KNOWN_HASHES.contains(it) }
|
||||
val agreedMac = startReq!!.messageAuthenticationCodes?.firstOrNull { KNOWN_MACS.contains(it) }
|
||||
val agreedShortCode = startReq!!.shortAuthenticationStrings?.filter { KNOWN_SHORT_CODES.contains(it) }
|
||||
val agreedProtocol = startReq!!.keyAgreementProtocols.firstOrNull { KNOWN_AGREEMENT_PROTOCOLS.contains(it) }
|
||||
val agreedHash = startReq!!.hashes.firstOrNull { KNOWN_HASHES.contains(it) }
|
||||
val agreedMac = startReq!!.messageAuthenticationCodes.firstOrNull { KNOWN_MACS.contains(it) }
|
||||
val agreedShortCode = startReq!!.shortAuthenticationStrings.filter { KNOWN_SHORT_CODES.contains(it) }
|
||||
|
||||
// No common key sharing/hashing/hmac/SAS methods.
|
||||
// If a device is unable to complete the verification because the devices are unable to find a common key sharing,
|
||||
@ -141,12 +141,12 @@ internal class DefaultIncomingSASDefaultVerificationTransaction(
|
||||
}
|
||||
|
||||
private fun doAccept(accept: VerificationInfoAccept) {
|
||||
this.accepted = accept
|
||||
this.accepted = accept.asValidObject()
|
||||
Timber.v("## SAS incoming accept request id:$transactionId")
|
||||
|
||||
// The hash commitment is the hash (using the selected hash algorithm) of the unpadded base64 representation of QB,
|
||||
// concatenated with the canonical JSON representation of the content of the m.key.verification.start message
|
||||
val concat = getSAS().publicKey + startReq!!.toCanonicalJson()
|
||||
val concat = getSAS().publicKey + startReq!!.canonicalJson
|
||||
accept.commitment = hashUsingAgreedHashMethod(concat) ?: ""
|
||||
// we need to send this to other device now
|
||||
state = VerificationTxState.SendingAccept
|
||||
@ -158,12 +158,12 @@ internal class DefaultIncomingSASDefaultVerificationTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVerificationAccept(accept: VerificationInfoAccept) {
|
||||
override fun onVerificationAccept(accept: ValidVerificationInfoAccept) {
|
||||
Timber.v("## SAS invalid message for incoming request id:$transactionId")
|
||||
cancel(CancelCode.UnexpectedMessage)
|
||||
}
|
||||
|
||||
override fun onKeyVerificationKey(vKey: VerificationInfoKey) {
|
||||
override fun onKeyVerificationKey(vKey: ValidVerificationInfoKey) {
|
||||
Timber.v("## SAS received key for request id:$transactionId")
|
||||
if (state != VerificationTxState.SendingAccept && state != VerificationTxState.Accepted) {
|
||||
Timber.e("## SAS received key from invalid state $state")
|
||||
@ -213,7 +213,7 @@ internal class DefaultIncomingSASDefaultVerificationTransaction(
|
||||
state = VerificationTxState.ShortCodeReady
|
||||
}
|
||||
|
||||
override fun onKeyVerificationMac(vKey: VerificationInfoMac) {
|
||||
override fun onKeyVerificationMac(vKey: ValidVerificationInfoMac) {
|
||||
Timber.v("## SAS I: received mac for request id:$transactionId")
|
||||
// Check for state?
|
||||
if (state != VerificationTxState.SendingKey
|
||||
|
@ -74,7 +74,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVerificationStart(startReq: VerificationInfoStart) {
|
||||
override fun onVerificationStart(startReq: ValidVerificationInfoStart.SasVerificationInfoStart) {
|
||||
Timber.e("## SAS O: onVerificationStart - unexpected id:$transactionId")
|
||||
cancel(CancelCode.UnexpectedMessage)
|
||||
}
|
||||
@ -94,8 +94,8 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||
KNOWN_MACS,
|
||||
KNOWN_SHORT_CODES
|
||||
)
|
||||
|
||||
startReq = startMessage
|
||||
kk
|
||||
startReq = startMessage.asValidObject() as? ValidVerificationInfoStart.SasVerificationInfoStart
|
||||
state = VerificationTxState.SendingStart
|
||||
|
||||
sendToOther(
|
||||
@ -130,7 +130,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||
// )
|
||||
// }
|
||||
|
||||
override fun onVerificationAccept(accept: VerificationInfoAccept) {
|
||||
override fun onVerificationAccept(accept: ValidVerificationInfoAccept) {
|
||||
Timber.v("## SAS O: onVerificationAccept id:$transactionId")
|
||||
if (state != VerificationTxState.Started) {
|
||||
Timber.e("## SAS O: received accept request from invalid state $state")
|
||||
@ -141,7 +141,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||
if (!KNOWN_AGREEMENT_PROTOCOLS.contains(accept.keyAgreementProtocol)
|
||||
|| !KNOWN_HASHES.contains(accept.hash)
|
||||
|| !KNOWN_MACS.contains(accept.messageAuthenticationCode)
|
||||
|| accept.shortAuthenticationStrings!!.intersect(KNOWN_SHORT_CODES).isEmpty()) {
|
||||
|| accept.shortAuthenticationStrings.intersect(KNOWN_SHORT_CODES).isEmpty()) {
|
||||
Timber.e("## SAS O: received accept request from invalid state")
|
||||
cancel(CancelCode.UnknownMethod)
|
||||
return
|
||||
@ -167,7 +167,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyVerificationKey(vKey: VerificationInfoKey) {
|
||||
override fun onKeyVerificationKey(vKey: ValidVerificationInfoKey) {
|
||||
Timber.v("## SAS O: onKeyVerificationKey id:$transactionId")
|
||||
if (state != VerificationTxState.SendingKey && state != VerificationTxState.KeySent) {
|
||||
Timber.e("## received key from invalid state $state")
|
||||
@ -182,7 +182,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||
// in Bob’s m.key.verification.key and the content of Alice’s m.key.verification.start message.
|
||||
|
||||
// check commitment
|
||||
val concat = vKey.key + startReq!!.toCanonicalJson()
|
||||
val concat = vKey.key + startReq!!.canonicalJson
|
||||
val otherCommitment = hashUsingAgreedHashMethod(concat) ?: ""
|
||||
|
||||
if (accepted!!.commitment.equals(otherCommitment)) {
|
||||
@ -206,7 +206,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyVerificationMac(vKey: VerificationInfoMac) {
|
||||
override fun onKeyVerificationMac(vKey: ValidVerificationInfoMac) {
|
||||
Timber.v("## SAS O: onKeyVerificationMac id:$transactionId")
|
||||
if (state != VerificationTxState.OnKeyReceived
|
||||
&& state != VerificationTxState.ShortCodeReady
|
||||
|
@ -45,6 +45,7 @@ import im.vector.matrix.android.api.session.room.model.message.MessageVerificati
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationReadyContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationStartContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.ValidVerificationDone
|
||||
import im.vector.matrix.android.internal.crypto.DeviceListManager
|
||||
import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
|
||||
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
||||
@ -268,9 +269,9 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
}
|
||||
|
||||
private fun onRequestReceived(event: Event) {
|
||||
val requestInfo = event.getClearContent().toModel<KeyVerificationRequest>()!!
|
||||
val validRequestInfo = event.getClearContent().toModel<KeyVerificationRequest>()?.asValidObject()
|
||||
|
||||
if (!requestInfo.isValid()) {
|
||||
if (validRequestInfo == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid key request")
|
||||
return
|
||||
@ -278,7 +279,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
val senderId = event.senderId ?: return
|
||||
|
||||
// We don't want to block here
|
||||
val otherDeviceId = requestInfo.fromDevice ?: return
|
||||
val otherDeviceId = validRequestInfo.fromDevice
|
||||
|
||||
GlobalScope.launch {
|
||||
if (checkKeysAreDownloaded(senderId, otherDeviceId) == null) {
|
||||
@ -297,9 +298,9 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
isIncoming = true,
|
||||
otherUserId = senderId, // requestInfo.toUserId,
|
||||
roomId = null,
|
||||
transactionId = requestInfo.transactionID,
|
||||
localID = requestInfo.transactionID!!,
|
||||
requestInfo = requestInfo
|
||||
transactionId = validRequestInfo.transactionID,
|
||||
localID = validRequestInfo.transactionID,
|
||||
requestInfo = validRequestInfo
|
||||
)
|
||||
requestsForUser.add(pendingVerificationRequest)
|
||||
dispatchRequestAdded(pendingVerificationRequest)
|
||||
@ -307,10 +308,10 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
|
||||
suspend fun onRoomRequestReceived(event: Event) {
|
||||
Timber.v("## SAS Verification request from ${event.senderId} in room ${event.roomId}")
|
||||
val requestInfo = event.getClearContent().toModel<MessageVerificationRequestContent>()
|
||||
?: return
|
||||
val requestInfo = event.getClearContent().toModel<MessageVerificationRequestContent>() ?: return
|
||||
val validRequestInfo = requestInfo.asValidObject() ?: return
|
||||
|
||||
val senderId = event.senderId ?: return
|
||||
val fromDevice = requestInfo.fromDevice ?: return
|
||||
|
||||
if (requestInfo.toUserId != userId) {
|
||||
// I should ignore this, it's not for me
|
||||
@ -320,8 +321,8 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
|
||||
// We don't want to block here
|
||||
GlobalScope.launch {
|
||||
if (checkKeysAreDownloaded(senderId, fromDevice) == null) {
|
||||
Timber.e("## SAS Verification device $fromDevice is not known")
|
||||
if (checkKeysAreDownloaded(senderId, validRequestInfo.fromDevice) == null) {
|
||||
Timber.e("## SAS Verification device ${validRequestInfo.fromDevice} is not known")
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,7 +339,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
roomId = event.roomId,
|
||||
transactionId = event.eventId,
|
||||
localID = event.eventId!!,
|
||||
requestInfo = requestInfo
|
||||
requestInfo = validRequestInfo
|
||||
)
|
||||
requestsForUser.add(pendingVerificationRequest)
|
||||
dispatchRequestAdded(pendingVerificationRequest)
|
||||
@ -362,10 +363,12 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
|
||||
val validStartReq = startReq?.asValidObject()
|
||||
|
||||
val otherUserId = event.senderId
|
||||
if (startReq?.isValid()?.not() == true) {
|
||||
if (validStartReq == null) {
|
||||
Timber.e("## received invalid verification request")
|
||||
if (startReq.transactionID != null) {
|
||||
if (startReq?.transactionID != null) {
|
||||
verificationTransportRoomMessageFactory.createTransport(event.roomId ?: "", null)
|
||||
.cancelTransaction(
|
||||
startReq.transactionID ?: "",
|
||||
@ -377,14 +380,14 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
handleStart(otherUserId, startReq as VerificationInfoStart) {
|
||||
handleStart(otherUserId, validStartReq) {
|
||||
it.transport = verificationTransportRoomMessageFactory.createTransport(event.roomId ?: "", it)
|
||||
}?.let {
|
||||
verificationTransportRoomMessageFactory.createTransport(event.roomId ?: "", null)
|
||||
.cancelTransaction(
|
||||
startReq.transactionID ?: "",
|
||||
validStartReq.transactionID,
|
||||
otherUserId!!,
|
||||
startReq.fromDevice ?: event.getSenderKey()!!,
|
||||
validStartReq.fromDevice,
|
||||
it
|
||||
)
|
||||
}
|
||||
@ -392,16 +395,17 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
|
||||
private suspend fun onStartRequestReceived(event: Event) {
|
||||
Timber.e("## SAS received Start request ${event.eventId}")
|
||||
val startReq = event.getClearContent().toModel<KeyVerificationStart>()!!
|
||||
val startReq = event.getClearContent().toModel<KeyVerificationStart>()
|
||||
val validStartReq = startReq?.asValidObject()
|
||||
Timber.v("## SAS received Start request $startReq")
|
||||
|
||||
val otherUserId = event.senderId
|
||||
if (!startReq.isValid()) {
|
||||
val otherUserId = event.senderId!!
|
||||
if (validStartReq == null) {
|
||||
Timber.e("## SAS received invalid verification request")
|
||||
if (startReq.transactionID != null) {
|
||||
if (startReq?.transactionID != null) {
|
||||
verificationTransportToDeviceFactory.createTransport(null).cancelTransaction(
|
||||
startReq.transactionID,
|
||||
otherUserId!!,
|
||||
otherUserId,
|
||||
startReq.fromDevice ?: event.getSenderKey()!!,
|
||||
CancelCode.UnknownMethod
|
||||
)
|
||||
@ -409,13 +413,13 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
return
|
||||
}
|
||||
// Download device keys prior to everything
|
||||
handleStart(otherUserId, startReq) {
|
||||
handleStart(otherUserId, validStartReq) {
|
||||
it.transport = verificationTransportToDeviceFactory.createTransport(it)
|
||||
}?.let {
|
||||
verificationTransportToDeviceFactory.createTransport(null).cancelTransaction(
|
||||
startReq.transactionID ?: "",
|
||||
otherUserId!!,
|
||||
startReq.fromDevice ?: event.getSenderKey()!!,
|
||||
validStartReq.transactionID,
|
||||
otherUserId,
|
||||
validStartReq.fromDevice,
|
||||
it
|
||||
)
|
||||
}
|
||||
@ -424,14 +428,14 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
/**
|
||||
* Return a CancelCode to make the caller cancel the verification. Else return null
|
||||
*/
|
||||
private suspend fun handleStart(otherUserId: String?, startReq: VerificationInfoStart, txConfigure: (DefaultVerificationTransaction) -> Unit): CancelCode? {
|
||||
private suspend fun handleStart(otherUserId: String?, startReq: ValidVerificationInfoStart, txConfigure: (DefaultVerificationTransaction) -> Unit): CancelCode? {
|
||||
Timber.d("## SAS onStartRequestReceived ${startReq.transactionID}")
|
||||
if (checkKeysAreDownloaded(otherUserId!!, startReq.fromDevice ?: "") != null) {
|
||||
val tid = startReq.transactionID!!
|
||||
if (checkKeysAreDownloaded(otherUserId!!, startReq.fromDevice) != null) {
|
||||
val tid = startReq.transactionID
|
||||
val existing = getExistingTransaction(otherUserId, tid)
|
||||
|
||||
when (startReq.method) {
|
||||
VERIFICATION_METHOD_SAS -> {
|
||||
when (startReq) {
|
||||
is ValidVerificationInfoStart.SasVerificationInfoStart -> {
|
||||
when (existing) {
|
||||
is SasVerificationTransaction -> {
|
||||
// should cancel both!
|
||||
@ -462,7 +466,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
}
|
||||
|
||||
// Ok we can create a SAS transaction
|
||||
Timber.v("## SAS onStartRequestReceived - request accepted ${startReq.transactionID!!}")
|
||||
Timber.v("## SAS onStartRequestReceived - request accepted ${startReq.transactionID}")
|
||||
// If there is a corresponding request, we can auto accept
|
||||
// as we are the one requesting in first place (or we accepted the request)
|
||||
// I need to check if the pending request was related to this device also
|
||||
@ -479,14 +483,14 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
cryptoStore,
|
||||
crossSigningService,
|
||||
myDeviceInfoHolder.get().myDevice.fingerprint()!!,
|
||||
startReq.transactionID!!,
|
||||
startReq.transactionID,
|
||||
otherUserId,
|
||||
autoAccept).also { txConfigure(it) }
|
||||
addTransaction(tx)
|
||||
tx.acceptVerificationEvent(otherUserId, startReq)
|
||||
tx.onVerificationStart(startReq)
|
||||
return null
|
||||
}
|
||||
VERIFICATION_METHOD_RECIPROCATE -> {
|
||||
is ValidVerificationInfoStart.ReciprocateVerificationInfoStart -> {
|
||||
// Other user has scanned my QR code
|
||||
if (existing is DefaultQrCodeVerificationTransaction) {
|
||||
existing.onStartReceived(startReq)
|
||||
@ -496,10 +500,6 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
return CancelCode.UnexpectedMessage
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Timber.e("## SAS onStartRequestReceived - unknown method ${startReq.method}")
|
||||
return CancelCode.UnknownMethod
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return CancelCode.UnexpectedMessage
|
||||
@ -529,24 +529,27 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
// relates_to is in clear in encrypted payload
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
if (cancelReq == null || cancelReq.isValid().not()) {
|
||||
|
||||
val validCancelReq = cancelReq?.asValidObject()
|
||||
|
||||
if (validCancelReq == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid key request")
|
||||
// TODO should we cancel?
|
||||
return
|
||||
}
|
||||
getExistingVerificationRequest(event.senderId ?: "", cancelReq.transactionID)?.let {
|
||||
updatePendingRequest(it.copy(cancelConclusion = safeValueOf(cancelReq.code)))
|
||||
getExistingVerificationRequest(event.senderId ?: "", validCancelReq.transactionID)?.let {
|
||||
updatePendingRequest(it.copy(cancelConclusion = safeValueOf(validCancelReq.code)))
|
||||
// Should we remove it from the list?
|
||||
}
|
||||
handleOnCancel(event.senderId!!, cancelReq)
|
||||
handleOnCancel(event.senderId!!, validCancelReq)
|
||||
}
|
||||
|
||||
private fun onCancelReceived(event: Event) {
|
||||
Timber.v("## SAS onCancelReceived")
|
||||
val cancelReq = event.getClearContent().toModel<KeyVerificationCancel>()!!
|
||||
val cancelReq = event.getClearContent().toModel<KeyVerificationCancel>()?.asValidObject()
|
||||
|
||||
if (!cancelReq.isValid()) {
|
||||
if (cancelReq == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid cancel request")
|
||||
return
|
||||
@ -556,11 +559,11 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
handleOnCancel(otherUserId, cancelReq)
|
||||
}
|
||||
|
||||
private fun handleOnCancel(otherUserId: String, cancelReq: VerificationInfoCancel) {
|
||||
private fun handleOnCancel(otherUserId: String, cancelReq: ValidVerificationInfoCancel) {
|
||||
Timber.v("## SAS onCancelReceived otherUser:$otherUserId reason:${cancelReq.reason}")
|
||||
|
||||
val existingTransaction = getExistingTransaction(otherUserId, cancelReq.transactionID!!)
|
||||
val existingRequest = getExistingVerificationRequest(otherUserId, cancelReq.transactionID!!)
|
||||
val existingTransaction = getExistingTransaction(otherUserId, cancelReq.transactionID)
|
||||
val existingRequest = getExistingVerificationRequest(otherUserId, cancelReq.transactionID)
|
||||
|
||||
if (existingRequest != null) {
|
||||
// Mark this request as cancelled
|
||||
@ -582,30 +585,28 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
?: return
|
||||
handleAccept(accept, event.senderId!!)
|
||||
|
||||
val validAccept = accept.asValidObject() ?: return
|
||||
|
||||
handleAccept(validAccept, event.senderId!!)
|
||||
}
|
||||
|
||||
private fun onAcceptReceived(event: Event) {
|
||||
Timber.d("## SAS Received Accept $event")
|
||||
val acceptReq = event.getClearContent().toModel<KeyVerificationAccept>() ?: return
|
||||
val acceptReq = event.getClearContent().toModel<KeyVerificationAccept>()?.asValidObject() ?: return
|
||||
handleAccept(acceptReq, event.senderId!!)
|
||||
}
|
||||
|
||||
private fun handleAccept(acceptReq: VerificationInfoAccept, senderId: String) {
|
||||
if (!acceptReq.isValid()) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid accept request")
|
||||
return
|
||||
}
|
||||
private fun handleAccept(acceptReq: ValidVerificationInfoAccept, senderId: String) {
|
||||
val otherUserId = senderId
|
||||
val existing = getExistingTransaction(otherUserId, acceptReq.transactionID!!)
|
||||
val existing = getExistingTransaction(otherUserId, acceptReq.transactionID)
|
||||
if (existing == null) {
|
||||
Timber.e("## SAS Received invalid accept request")
|
||||
return
|
||||
}
|
||||
|
||||
if (existing is SASDefaultVerificationTransaction) {
|
||||
existing.acceptVerificationEvent(otherUserId, acceptReq)
|
||||
existing.onVerificationAccept(acceptReq)
|
||||
} else {
|
||||
// not other types now
|
||||
}
|
||||
@ -617,7 +618,8 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
// relates_to is in clear in encrypted payload
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
if (keyReq == null || keyReq.isValid().not()) {
|
||||
?.asValidObject()
|
||||
if (keyReq == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid key request")
|
||||
// TODO should we cancel?
|
||||
@ -627,9 +629,9 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
}
|
||||
|
||||
private fun onKeyReceived(event: Event) {
|
||||
val keyReq = event.getClearContent().toModel<KeyVerificationKey>()!!
|
||||
val keyReq = event.getClearContent().toModel<KeyVerificationKey>()?.asValidObject()
|
||||
|
||||
if (!keyReq.isValid()) {
|
||||
if (keyReq == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid key request")
|
||||
return
|
||||
@ -637,16 +639,16 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
handleKeyReceived(event, keyReq)
|
||||
}
|
||||
|
||||
private fun handleKeyReceived(event: Event, keyReq: VerificationInfoKey) {
|
||||
private fun handleKeyReceived(event: Event, keyReq: ValidVerificationInfoKey) {
|
||||
Timber.d("## SAS Received Key from ${event.senderId} with info $keyReq")
|
||||
val otherUserId = event.senderId!!
|
||||
val existing = getExistingTransaction(otherUserId, keyReq.transactionID!!)
|
||||
val existing = getExistingTransaction(otherUserId, keyReq.transactionID)
|
||||
if (existing == null) {
|
||||
Timber.e("## SAS Received invalid key request")
|
||||
return
|
||||
}
|
||||
if (existing is SASDefaultVerificationTransaction) {
|
||||
existing.acceptVerificationEvent(otherUserId, keyReq)
|
||||
existing.onKeyVerificationKey(keyReq)
|
||||
} else {
|
||||
// not other types now
|
||||
}
|
||||
@ -658,7 +660,8 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
// relates_to is in clear in encrypted payload
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
if (macReq == null || macReq.isValid().not() || event.senderId == null) {
|
||||
?.asValidObject()
|
||||
if (macReq == null || event.senderId == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid mac request")
|
||||
// TODO should we cancel?
|
||||
@ -673,13 +676,14 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
// relates_to is in clear in encrypted payload
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
if (readyReq == null || readyReq.isValid().not() || event.senderId == null) {
|
||||
?.asValidObject()
|
||||
if (readyReq == null || event.senderId == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid ready request")
|
||||
// TODO should we cancel?
|
||||
return
|
||||
}
|
||||
if (checkKeysAreDownloaded(event.senderId, readyReq.fromDevice ?: "") == null) {
|
||||
if (checkKeysAreDownloaded(event.senderId, readyReq.fromDevice) == null) {
|
||||
Timber.e("## SAS Verification device ${readyReq.fromDevice} is not known")
|
||||
// TODO cancel?
|
||||
return
|
||||
@ -691,15 +695,15 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
}
|
||||
|
||||
private suspend fun onReadyReceived(event: Event) {
|
||||
val readyReq = event.getClearContent().toModel<KeyVerificationReady>()
|
||||
val readyReq = event.getClearContent().toModel<KeyVerificationReady>()?.asValidObject()
|
||||
|
||||
if (readyReq == null || readyReq.isValid().not() || event.senderId == null) {
|
||||
if (readyReq == null || event.senderId == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid ready request")
|
||||
// TODO should we cancel?
|
||||
return
|
||||
}
|
||||
if (checkKeysAreDownloaded(event.senderId, readyReq.fromDevice ?: "") == null) {
|
||||
if (checkKeysAreDownloaded(event.senderId, readyReq.fromDevice) == null) {
|
||||
Timber.e("## SAS Verification device ${readyReq.fromDevice} is not known")
|
||||
// TODO cancel?
|
||||
return
|
||||
@ -716,8 +720,9 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
// relates_to is in clear in encrypted payload
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
?.asValidObject()
|
||||
|
||||
if (doneReq == null || doneReq.isValid().not() || event.senderId == null) {
|
||||
if (doneReq == null || event.senderId == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid Done request")
|
||||
// TODO should we cancel?
|
||||
@ -728,9 +733,9 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
}
|
||||
|
||||
private fun onMacReceived(event: Event) {
|
||||
val macReq = event.getClearContent().toModel<KeyVerificationMac>()!!
|
||||
val macReq = event.getClearContent().toModel<KeyVerificationMac>()?.asValidObject()
|
||||
|
||||
if (!macReq.isValid() || event.senderId == null) {
|
||||
if (macReq == null || event.senderId == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid mac request")
|
||||
return
|
||||
@ -738,22 +743,22 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
handleMacReceived(event.senderId, macReq)
|
||||
}
|
||||
|
||||
private fun handleMacReceived(senderId: String, macReq: VerificationInfoMac) {
|
||||
private fun handleMacReceived(senderId: String, macReq: ValidVerificationInfoMac) {
|
||||
Timber.v("## SAS Received $macReq")
|
||||
val existing = getExistingTransaction(senderId, macReq.transactionID!!)
|
||||
val existing = getExistingTransaction(senderId, macReq.transactionID)
|
||||
if (existing == null) {
|
||||
Timber.e("## SAS Received invalid Mac request")
|
||||
return
|
||||
}
|
||||
if (existing is SASDefaultVerificationTransaction) {
|
||||
existing.acceptVerificationEvent(senderId, macReq)
|
||||
existing.onKeyVerificationMac(macReq)
|
||||
} else {
|
||||
// not other types known for now
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReadyReceived(senderId: String,
|
||||
readyReq: VerificationInfoReady,
|
||||
readyReq: ValidVerificationInfoReady,
|
||||
transportCreator: (DefaultVerificationTransaction) -> VerificationTransport) {
|
||||
val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == readyReq.transactionID }
|
||||
if (existingRequest == null) {
|
||||
@ -763,16 +768,16 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
|
||||
val qrCodeData = readyReq.methods
|
||||
// Check if other user is able to scan QR code
|
||||
?.takeIf { it.contains(VERIFICATION_METHOD_QR_CODE_SCAN) }
|
||||
.takeIf { it.contains(VERIFICATION_METHOD_QR_CODE_SCAN) }
|
||||
?.let {
|
||||
createQrCodeData(existingRequest.transactionId, existingRequest.otherUserId, readyReq.fromDevice)
|
||||
}
|
||||
|
||||
if (readyReq.methods.orEmpty().contains(VERIFICATION_METHOD_RECIPROCATE)) {
|
||||
if (readyReq.methods.contains(VERIFICATION_METHOD_RECIPROCATE)) {
|
||||
// Create the pending transaction
|
||||
val tx = DefaultQrCodeVerificationTransaction(
|
||||
setDeviceVerificationAction,
|
||||
readyReq.transactionID!!,
|
||||
readyReq.transactionID,
|
||||
senderId,
|
||||
readyReq.fromDevice,
|
||||
crossSigningService,
|
||||
@ -886,7 +891,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleDoneReceived(senderId: String, doneInfo: VerificationInfo) {
|
||||
private fun handleDoneReceived(senderId: String, doneInfo: ValidVerificationDone) {
|
||||
val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == doneInfo.transactionID }
|
||||
if (existingRequest == null) {
|
||||
Timber.e("## SAS Received Done for unknown request txId:${doneInfo.transactionID}")
|
||||
@ -1186,7 +1191,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
CancelCode.User,
|
||||
null // TODO handle error?
|
||||
)
|
||||
updatePendingRequest(existingRequest.copy(readyInfo = readyMsg))
|
||||
updatePendingRequest(existingRequest.copy(readyInfo = readyMsg.asValidObject()))
|
||||
return true
|
||||
} else {
|
||||
Timber.e("## SAS readyPendingVerificationInDMs Verification not found")
|
||||
@ -1214,7 +1219,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
}
|
||||
if (methods.isNullOrEmpty()) {
|
||||
Timber.i("Cannot ready this request, no common methods found txId:$transactionId")
|
||||
// TODO buttons should not be shown in this case?
|
||||
// TODO buttons should not be shown in this case?
|
||||
return false
|
||||
}
|
||||
// TODO this is not yet related to a transaction, maybe we should use another method like for cancel?
|
||||
@ -1225,7 +1230,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||
existingRequest.requestInfo?.fromDevice ?: "",
|
||||
null // TODO handle error?
|
||||
)
|
||||
updatePendingRequest(existingRequest.copy(readyInfo = readyMsg))
|
||||
updatePendingRequest(existingRequest.copy(readyInfo = readyMsg.asValidObject()))
|
||||
return true
|
||||
} else {
|
||||
Timber.e("## SAS readyPendingVerification Verification not found")
|
||||
|
@ -41,6 +41,4 @@ internal abstract class DefaultVerificationTransaction(
|
||||
fun removeListener(listener: Listener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
abstract fun acceptVerificationEvent(senderId: String, info: VerificationInfo)
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ data class PendingVerificationRequest(
|
||||
val otherUserId: String,
|
||||
val roomId: String?,
|
||||
val transactionId: String? = null,
|
||||
val requestInfo: VerificationInfoRequest? = null,
|
||||
val readyInfo: VerificationInfoReady? = null,
|
||||
val requestInfo: ValidVerificationInfoRequest? = null,
|
||||
val readyInfo: ValidVerificationInfoReady? = null,
|
||||
val cancelConclusion: CancelCode? = null,
|
||||
val isSuccessful: Boolean = false,
|
||||
val handledByOtherSession: Boolean = false,
|
||||
|
@ -89,13 +89,13 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||
|
||||
private var olmSas: OlmSAS? = null
|
||||
|
||||
var startReq: VerificationInfoStart? = null
|
||||
var accepted: VerificationInfoAccept? = null
|
||||
var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null
|
||||
var accepted: ValidVerificationInfoAccept? = null
|
||||
var otherKey: String? = null
|
||||
var shortCodeBytes: ByteArray? = null
|
||||
|
||||
var myMac: VerificationInfoMac? = null
|
||||
var theirMac: VerificationInfoMac? = null
|
||||
var theirMac: ValidVerificationInfoMac? = null
|
||||
|
||||
fun getSAS(): OlmSAS {
|
||||
if (olmSas == null) olmSas = OlmSAS()
|
||||
@ -201,25 +201,13 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||
return transport is VerificationTransportToDevice
|
||||
}
|
||||
|
||||
override fun acceptVerificationEvent(senderId: String, info: VerificationInfo) {
|
||||
when (info) {
|
||||
is VerificationInfoStart -> onVerificationStart(info)
|
||||
is VerificationInfoAccept -> onVerificationAccept(info)
|
||||
is VerificationInfoKey -> onKeyVerificationKey(info)
|
||||
is VerificationInfoMac -> onKeyVerificationMac(info)
|
||||
else -> {
|
||||
// nop
|
||||
}
|
||||
}
|
||||
}
|
||||
abstract fun onVerificationStart(startReq: ValidVerificationInfoStart.SasVerificationInfoStart)
|
||||
|
||||
abstract fun onVerificationStart(startReq: VerificationInfoStart)
|
||||
abstract fun onVerificationAccept(accept: ValidVerificationInfoAccept)
|
||||
|
||||
abstract fun onVerificationAccept(accept: VerificationInfoAccept)
|
||||
abstract fun onKeyVerificationKey(vKey: ValidVerificationInfoKey)
|
||||
|
||||
abstract fun onKeyVerificationKey(vKey: VerificationInfoKey)
|
||||
|
||||
abstract fun onKeyVerificationMac(vKey: VerificationInfoMac)
|
||||
abstract fun onKeyVerificationMac(vKey: ValidVerificationInfoMac)vMac
|
||||
|
||||
protected fun verifyMacs() {
|
||||
Timber.v("## SAS verifying macs for id:$transactionId")
|
||||
@ -238,7 +226,7 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||
userId + deviceId +
|
||||
transactionId
|
||||
|
||||
val commaSeparatedListOfKeyIds = theirMac!!.mac!!.keys.sorted().joinToString(",")
|
||||
val commaSeparatedListOfKeyIds = theirMac!!.mac.keys.sorted().joinToString(",")
|
||||
|
||||
val keyStrings = macUsingAgreedMethod(commaSeparatedListOfKeyIds, baseInfo + "KEY_IDS")
|
||||
if (theirMac!!.keys != keyStrings) {
|
||||
@ -250,7 +238,7 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||
val verifiedDevices = ArrayList<String>()
|
||||
|
||||
// cannot be empty because it has been validated
|
||||
theirMac!!.mac!!.keys.forEach {
|
||||
theirMac!!.mac.keys.forEach {
|
||||
val keyIDNoPrefix = it.withoutPrefix("ed25519:")
|
||||
val otherDeviceKey = otherUserKnownDevices?.get(keyIDNoPrefix)?.fingerprint()
|
||||
if (otherDeviceKey == null) {
|
||||
@ -273,7 +261,7 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||
val otherCrossSigningMasterKeyPublic = otherMasterKey?.unpaddedBase64PublicKey
|
||||
if (otherCrossSigningMasterKeyPublic != null) {
|
||||
// Did the user signed his master key
|
||||
theirMac!!.mac!!.keys.forEach {
|
||||
theirMac!!.mac.keys.forEach {
|
||||
val keyIDNoPrefix = it.withoutPrefix("ed25519:")
|
||||
if (keyIDNoPrefix == otherCrossSigningMasterKeyPublic) {
|
||||
// Check the signature
|
||||
@ -350,11 +338,11 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||
transport.cancelTransaction(transactionId, otherUserId, otherDeviceId ?: "", code)
|
||||
}
|
||||
|
||||
protected fun sendToOther(type: String,
|
||||
keyToDevice: VerificationInfo,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?) {
|
||||
protected fun <T> sendToOther(type: String,
|
||||
keyToDevice: VerificationInfo<T>,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?) {
|
||||
transport.sendToOther(type, keyToDevice, nextState, onErrorReason, onDone)
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ internal interface VerificationInfoCancel : VerificationInfo<ValidVerificationIn
|
||||
return null
|
||||
}
|
||||
return ValidVerificationInfoCancel(
|
||||
transactionID!!,
|
||||
code!!,
|
||||
reason
|
||||
)
|
||||
@ -38,6 +39,7 @@ internal interface VerificationInfoCancel : VerificationInfo<ValidVerificationIn
|
||||
}
|
||||
|
||||
internal data class ValidVerificationInfoCancel(
|
||||
val transactionID: String,
|
||||
val code: String,
|
||||
val reason: String?
|
||||
)
|
||||
|
@ -29,6 +29,7 @@ internal interface VerificationInfoKey : VerificationInfo<ValidVerificationInfoK
|
||||
return null
|
||||
}
|
||||
return ValidVerificationInfoKey(
|
||||
transactionID!!,
|
||||
key!!
|
||||
)
|
||||
}
|
||||
@ -39,5 +40,6 @@ internal interface VerificationInfoKeyFactory {
|
||||
}
|
||||
|
||||
internal data class ValidVerificationInfoKey(
|
||||
val transactionID: String,
|
||||
val key: String
|
||||
)
|
||||
|
@ -34,6 +34,7 @@ internal interface VerificationInfoMac : VerificationInfo<ValidVerificationInfoM
|
||||
return null
|
||||
}
|
||||
return ValidVerificationInfoMac(
|
||||
transactionID!!,
|
||||
mac!!,
|
||||
keys!!
|
||||
)
|
||||
@ -45,6 +46,7 @@ internal interface VerificationInfoMacFactory {
|
||||
}
|
||||
|
||||
internal data class ValidVerificationInfoMac(
|
||||
val transactionID: String,
|
||||
val mac: Map<String, String>,
|
||||
val keys: String
|
||||
)
|
||||
|
@ -42,6 +42,7 @@ internal interface VerificationInfoReady : VerificationInfo<ValidVerificationInf
|
||||
}
|
||||
|
||||
return ValidVerificationInfoReady(
|
||||
transactionID!!,
|
||||
fromDevice!!,
|
||||
methods!!
|
||||
)
|
||||
@ -53,6 +54,7 @@ internal interface MessageVerificationReadyFactory {
|
||||
}
|
||||
|
||||
internal data class ValidVerificationInfoReady(
|
||||
val transactionID: String,
|
||||
val fromDevice: String,
|
||||
val methods: List<String>
|
||||
)
|
||||
|
@ -40,6 +40,7 @@ internal interface VerificationInfoRequest : VerificationInfo<ValidVerificationI
|
||||
return null
|
||||
}
|
||||
return ValidVerificationInfoRequest(
|
||||
transactionID!!,
|
||||
fromDevice!!,
|
||||
methods!!,
|
||||
timestamp
|
||||
@ -48,6 +49,7 @@ internal interface VerificationInfoRequest : VerificationInfo<ValidVerificationI
|
||||
}
|
||||
|
||||
internal data class ValidVerificationInfoRequest(
|
||||
val transactionID: String,
|
||||
val fromDevice: String,
|
||||
val methods: List<String>,
|
||||
val timestamp: Long?
|
||||
|
@ -61,7 +61,7 @@ internal interface VerificationInfoStart : VerificationInfo<ValidVerificationInf
|
||||
*/
|
||||
val sharedSecret: String?
|
||||
|
||||
fun toCanonicalJson(): String?
|
||||
fun toCanonicalJson(): String
|
||||
|
||||
override fun asValidObject(): ValidVerificationInfoStart? {
|
||||
if (transactionID.isNullOrBlank()
|
||||
@ -81,10 +81,13 @@ internal interface VerificationInfoStart : VerificationInfo<ValidVerificationInf
|
||||
null
|
||||
} else {
|
||||
ValidVerificationInfoStart.SasVerificationInfoStart(
|
||||
transactionID!!,
|
||||
fromDevice!!,
|
||||
keyAgreementProtocols!!,
|
||||
hashes!!,
|
||||
messageAuthenticationCodes!!,
|
||||
shortAuthenticationStrings!!
|
||||
shortAuthenticationStrings!!,
|
||||
canonicalJson = toCanonicalJson()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -93,6 +96,8 @@ internal interface VerificationInfoStart : VerificationInfo<ValidVerificationInf
|
||||
null
|
||||
} else {
|
||||
ValidVerificationInfoStart.ReciprocateVerificationInfoStart(
|
||||
transactionID!!,
|
||||
fromDevice!!,
|
||||
sharedSecret!!
|
||||
)
|
||||
}
|
||||
@ -102,15 +107,22 @@ internal interface VerificationInfoStart : VerificationInfo<ValidVerificationInf
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ValidVerificationInfoStart {
|
||||
sealed class ValidVerificationInfoStart(
|
||||
open val transactionID: String,
|
||||
open val fromDevice: String) {
|
||||
data class SasVerificationInfoStart(
|
||||
override val transactionID: String,
|
||||
override val fromDevice: String,
|
||||
val keyAgreementProtocols: List<String>,
|
||||
val hashes: List<String>,
|
||||
val messageAuthenticationCodes: List<String>,
|
||||
val shortAuthenticationStrings: List<String>
|
||||
) : ValidVerificationInfoStart()
|
||||
val shortAuthenticationStrings: List<String>,
|
||||
val canonicalJson: String
|
||||
) : ValidVerificationInfoStart(transactionID, fromDevice)
|
||||
|
||||
data class ReciprocateVerificationInfoStart(
|
||||
override val transactionID: String,
|
||||
override val fromDevice: String,
|
||||
val sharedSecret: String
|
||||
) : ValidVerificationInfoStart()
|
||||
) : ValidVerificationInfoStart(transactionID, fromDevice)
|
||||
}
|
||||
|
@ -27,18 +27,18 @@ internal interface VerificationTransport {
|
||||
/**
|
||||
* Sends a message
|
||||
*/
|
||||
fun sendToOther(type: String,
|
||||
verificationInfo: VerificationInfo,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?)
|
||||
fun <T> sendToOther(type: String,
|
||||
verificationInfo: VerificationInfo<T>,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?)
|
||||
|
||||
fun sendVerificationRequest(supportedMethods: List<String>,
|
||||
localID: String,
|
||||
otherUserId: String,
|
||||
roomId: String?,
|
||||
toDevices: List<String>?,
|
||||
callback: (String?, VerificationInfoRequest?) -> Unit)
|
||||
callback: (String?, ValidVerificationInfoRequest?) -> Unit)
|
||||
|
||||
fun cancelTransaction(transactionId: String,
|
||||
otherUserId: String,
|
||||
|
@ -21,7 +21,6 @@ import androidx.work.Data
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.Operation
|
||||
import androidx.work.WorkInfo
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.R
|
||||
import im.vector.matrix.android.api.session.crypto.verification.CancelCode
|
||||
import im.vector.matrix.android.api.session.crypto.verification.VerificationTxState
|
||||
@ -65,16 +64,15 @@ internal class VerificationTransportRoomMessage(
|
||||
private val userId: String,
|
||||
private val userDeviceId: String?,
|
||||
private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val localEchoEventFactory: LocalEchoEventFactory,
|
||||
private val tx: DefaultVerificationTransaction?
|
||||
) : VerificationTransport {
|
||||
|
||||
override fun sendToOther(type: String,
|
||||
verificationInfo: VerificationInfo,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?) {
|
||||
override fun <T> sendToOther(type: String,
|
||||
verificationInfo: VerificationInfo<T>,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?) {
|
||||
Timber.d("## SAS sending msg type $type")
|
||||
Timber.v("## SAS sending msg info $verificationInfo")
|
||||
val event = createEventAndLocalEcho(
|
||||
@ -142,17 +140,24 @@ internal class VerificationTransportRoomMessage(
|
||||
otherUserId: String,
|
||||
roomId: String?,
|
||||
toDevices: List<String>?,
|
||||
callback: (String?, VerificationInfoRequest?) -> Unit) {
|
||||
callback: (String?, ValidVerificationInfoRequest?) -> Unit) {
|
||||
Timber.d("## SAS sending verification request with supported methods: $supportedMethods")
|
||||
// This transport requires a room
|
||||
requireNotNull(roomId)
|
||||
|
||||
val validInfo = ValidVerificationInfoRequest(
|
||||
transactionID = "",
|
||||
fromDevice = userDeviceId ?: "",
|
||||
methods = supportedMethods,
|
||||
timestamp = System.currentTimeMillis()
|
||||
)
|
||||
|
||||
val info = MessageVerificationRequestContent(
|
||||
body = stringProvider.getString(R.string.key_verification_request_fallback_message, userId),
|
||||
fromDevice = userDeviceId ?: "",
|
||||
fromDevice = validInfo.fromDevice,
|
||||
toUserId = otherUserId,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
methods = supportedMethods
|
||||
timestamp = validInfo.timestamp,
|
||||
methods = validInfo.methods
|
||||
)
|
||||
val content = info.toContent()
|
||||
|
||||
@ -193,7 +198,7 @@ internal class VerificationTransportRoomMessage(
|
||||
if (wInfo.outputData.getBoolean("failed", false)) {
|
||||
callback(null, null)
|
||||
} else if (wInfo.outputData.getString(localID) != null) {
|
||||
callback(wInfo.outputData.getString(localID), info)
|
||||
callback(wInfo.outputData.getString(localID), validInfo)
|
||||
} else {
|
||||
callback(null, null)
|
||||
}
|
||||
@ -347,7 +352,6 @@ internal class VerificationTransportRoomMessage(
|
||||
internal class VerificationTransportRoomMessageFactory @Inject constructor(
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val stringProvider: StringProvider,
|
||||
private val monarchy: Monarchy,
|
||||
@SessionId
|
||||
private val sessionId: String,
|
||||
@UserId
|
||||
@ -357,6 +361,6 @@ internal class VerificationTransportRoomMessageFactory @Inject constructor(
|
||||
private val localEchoEventFactory: LocalEchoEventFactory) {
|
||||
|
||||
fun createTransport(roomId: String, tx: DefaultVerificationTransaction?): VerificationTransportRoomMessage {
|
||||
return VerificationTransportRoomMessage(workManagerProvider, stringProvider, sessionId, userId, deviceId, roomId, monarchy, localEchoEventFactory, tx)
|
||||
return VerificationTransportRoomMessage(workManagerProvider, stringProvider, sessionId, userId, deviceId, roomId, localEchoEventFactory, tx)
|
||||
}
|
||||
}
|
||||
|
@ -50,14 +50,20 @@ internal class VerificationTransportToDevice(
|
||||
otherUserId: String,
|
||||
roomId: String?,
|
||||
toDevices: List<String>?,
|
||||
callback: (String?, VerificationInfoRequest?) -> Unit) {
|
||||
callback: (String?, ValidVerificationInfoRequest?) -> Unit) {
|
||||
Timber.d("## SAS sending verification request with supported methods: $supportedMethods")
|
||||
val contentMap = MXUsersDevicesMap<Any>()
|
||||
val keyReq = KeyVerificationRequest(
|
||||
fromDevice = myDeviceId,
|
||||
val validKeyReq = ValidVerificationInfoRequest(
|
||||
transactionID = localID,
|
||||
fromDevice = myDeviceId ?: "",
|
||||
methods = supportedMethods,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
transactionID = localID
|
||||
timestamp = System.currentTimeMillis()
|
||||
)
|
||||
val keyReq = KeyVerificationRequest(
|
||||
fromDevice = validKeyReq.fromDevice,
|
||||
methods = validKeyReq.methods,
|
||||
timestamp = validKeyReq.timestamp,
|
||||
transactionID = validKeyReq.transactionID
|
||||
)
|
||||
toDevices?.forEach {
|
||||
contentMap.setObject(otherUserId, it, keyReq)
|
||||
@ -67,7 +73,7 @@ internal class VerificationTransportToDevice(
|
||||
this.callback = object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.v("## verification [$tx.transactionId] send toDevice request success")
|
||||
callback.invoke(localID, keyReq)
|
||||
callback.invoke(localID, validKeyReq)
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
@ -103,11 +109,11 @@ internal class VerificationTransportToDevice(
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun sendToOther(type: String,
|
||||
verificationInfo: VerificationInfo,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?) {
|
||||
override fun <T> sendToOther(type: String,
|
||||
verificationInfo: VerificationInfo<T>,
|
||||
nextState: VerificationTxState,
|
||||
onErrorReason: CancelCode,
|
||||
onDone: (() -> Unit)?) {
|
||||
Timber.d("## SAS sending msg type $type")
|
||||
Timber.v("## SAS sending msg info $verificationInfo")
|
||||
val tx = tx ?: return
|
||||
|
@ -28,8 +28,7 @@ import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64Safe
|
||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||
import im.vector.matrix.android.internal.crypto.verification.DefaultVerificationTransaction
|
||||
import im.vector.matrix.android.internal.crypto.verification.VerificationInfo
|
||||
import im.vector.matrix.android.internal.crypto.verification.VerificationInfoStart
|
||||
import im.vector.matrix.android.internal.crypto.verification.ValidVerificationInfoStart
|
||||
import im.vector.matrix.android.internal.util.exhaustive
|
||||
import timber.log.Timber
|
||||
|
||||
@ -179,9 +178,6 @@ internal class DefaultQrCodeVerificationTransaction(
|
||||
)
|
||||
}
|
||||
|
||||
override fun acceptVerificationEvent(senderId: String, info: VerificationInfo) {
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
cancel(CancelCode.User)
|
||||
}
|
||||
@ -194,14 +190,14 @@ internal class DefaultQrCodeVerificationTransaction(
|
||||
override fun isToDeviceTransport() = false
|
||||
|
||||
// Other user has scanned our QR code. check that the secret matched, so we can trust him
|
||||
fun onStartReceived(startReq: VerificationInfoStart) {
|
||||
fun onStartReceived(startReq: ValidVerificationInfoStart.ReciprocateVerificationInfoStart) {
|
||||
if (qrCodeData == null) {
|
||||
// Should not happen
|
||||
cancel(CancelCode.UnexpectedMessage)
|
||||
return
|
||||
}
|
||||
|
||||
if (startReq.sharedSecret?.fromBase64Safe()?.contentEquals(qrCodeData.sharedSecret.fromBase64()) == true) {
|
||||
if (startReq.sharedSecret.fromBase64Safe()?.contentEquals(qrCodeData.sharedSecret.fromBase64()) == true) {
|
||||
// Ok, we can trust the other user
|
||||
// We can only trust the master key in this case
|
||||
// But first, ask the user for a confirmation
|
||||
|
Loading…
Reference in New Issue
Block a user