crypto: Move most of the getters of verification objecs into the olm machine
This commit is contained in:
		
							parent
							
								
									38ce3ebed7
								
							
						
					
					
						commit
						cbed5be810
					
				@ -392,7 +392,7 @@ internal class DefaultCryptoService @Inject constructor(
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            setRustLogger()
 | 
			
		||||
            val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver)
 | 
			
		||||
            val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver, sender)
 | 
			
		||||
            olmMachine = machine
 | 
			
		||||
            verificationService = RustVerificationService(machine, this.sender)
 | 
			
		||||
            Timber.v(
 | 
			
		||||
@ -482,7 +482,7 @@ internal class DefaultCryptoService @Inject constructor(
 | 
			
		||||
    override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
 | 
			
		||||
        return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) {
 | 
			
		||||
            runBlocking {
 | 
			
		||||
                this@DefaultCryptoService.olmMachine?.getDevice(userId, deviceId)
 | 
			
		||||
                this@DefaultCryptoService.olmMachine?.getCryptoDeviceInfo(userId, deviceId)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            null
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,8 @@ import kotlinx.coroutines.runBlocking
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import org.matrix.android.sdk.api.listeners.ProgressListener
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
 | 
			
		||||
import org.matrix.android.sdk.api.session.events.model.Content
 | 
			
		||||
import org.matrix.android.sdk.api.session.events.model.Event
 | 
			
		||||
import org.matrix.android.sdk.api.util.JsonDict
 | 
			
		||||
@ -49,8 +51,7 @@ import uniffi.olm.OlmMachine as InnerMachine
 | 
			
		||||
import uniffi.olm.ProgressListener as RustProgressListener
 | 
			
		||||
import uniffi.olm.Request
 | 
			
		||||
import uniffi.olm.RequestType
 | 
			
		||||
import uniffi.olm.Verification
 | 
			
		||||
import uniffi.olm.VerificationRequest
 | 
			
		||||
import uniffi.olm.Verification as InnerVerification
 | 
			
		||||
import uniffi.olm.setLogger
 | 
			
		||||
 | 
			
		||||
class CryptoLogger : Logger {
 | 
			
		||||
@ -122,10 +123,12 @@ internal class OlmMachine(
 | 
			
		||||
        user_id: String,
 | 
			
		||||
        device_id: String,
 | 
			
		||||
        path: File,
 | 
			
		||||
        deviceObserver: DeviceUpdateObserver
 | 
			
		||||
        deviceObserver: DeviceUpdateObserver,
 | 
			
		||||
        private val requestSender: RequestSender,
 | 
			
		||||
) {
 | 
			
		||||
    private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString())
 | 
			
		||||
    private val deviceUpdateObserver = deviceObserver
 | 
			
		||||
    internal val verificationListeners = ArrayList<VerificationService.Listener>()
 | 
			
		||||
 | 
			
		||||
    /** Get our own user ID. */
 | 
			
		||||
    fun userId(): String {
 | 
			
		||||
@ -429,17 +432,26 @@ internal class OlmMachine(
 | 
			
		||||
     * @return The Device if it found one.
 | 
			
		||||
     */
 | 
			
		||||
    @Throws(CryptoStoreErrorException::class)
 | 
			
		||||
    suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? =
 | 
			
		||||
            withContext(Dispatchers.IO) {
 | 
			
		||||
                // Our own device isn't part of our store on the rust side, return it
 | 
			
		||||
                // using our ownDevice method
 | 
			
		||||
                if (userId == userId() && deviceId == deviceId()) {
 | 
			
		||||
                    ownDevice()
 | 
			
		||||
                } else {
 | 
			
		||||
                    val device = inner.getDevice(userId, deviceId)
 | 
			
		||||
                    if (device != null) toCryptoDeviceInfo(device) else null
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
    suspend fun getCryptoDeviceInfo(userId: String, deviceId: String): CryptoDeviceInfo? {
 | 
			
		||||
        return if (userId == userId() && deviceId == deviceId()) {
 | 
			
		||||
            // Our own device isn't part of our store on the Rust side, return it
 | 
			
		||||
            // using our ownDevice method
 | 
			
		||||
            ownDevice()
 | 
			
		||||
        } else {
 | 
			
		||||
            val device = getRawDevice(userId, deviceId) ?: return null
 | 
			
		||||
            toCryptoDeviceInfo(device)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun getRawDevice(userId: String, deviceId: String): InnerDevice? =
 | 
			
		||||
        withContext(Dispatchers.IO) {
 | 
			
		||||
            inner.getDevice(userId, deviceId)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    suspend fun getDevice(userId: String, deviceId: String): Device? {
 | 
			
		||||
        val device = this.getRawDevice(userId, deviceId) ?: return null
 | 
			
		||||
        return Device(this.inner, device, this.requestSender, this.verificationListeners)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all devices of an user.
 | 
			
		||||
@ -546,19 +558,58 @@ internal class OlmMachine(
 | 
			
		||||
     * @return The list of VerificationRequests that we share with the given user
 | 
			
		||||
     */
 | 
			
		||||
    fun getVerificationRequests(userId: String): List<VerificationRequest> {
 | 
			
		||||
        return this.inner.getVerificationRequests(userId)
 | 
			
		||||
        return this.inner.getVerificationRequests(userId).map {
 | 
			
		||||
            VerificationRequest(
 | 
			
		||||
                    this.inner,
 | 
			
		||||
                    it,
 | 
			
		||||
                    this.requestSender,
 | 
			
		||||
                    this.verificationListeners,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Get a verification request for the given user with the given flow ID */
 | 
			
		||||
    fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? {
 | 
			
		||||
        return this.inner.getVerificationRequest(userId, flowId)
 | 
			
		||||
        val request = this.inner.getVerificationRequest(userId, flowId)
 | 
			
		||||
 | 
			
		||||
        return if (request != null) {
 | 
			
		||||
            VerificationRequest(
 | 
			
		||||
                    this.inner,
 | 
			
		||||
                    request,
 | 
			
		||||
                    requestSender,
 | 
			
		||||
                    this.verificationListeners,
 | 
			
		||||
            )
 | 
			
		||||
        } else {
 | 
			
		||||
            null
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Get an active verification for the given user and given flow ID
 | 
			
		||||
     *
 | 
			
		||||
     * This can return a SAS verification or a QR code verification
 | 
			
		||||
     */
 | 
			
		||||
    fun getVerification(userId: String, flowId: String): Verification? {
 | 
			
		||||
        return this.inner.getVerification(userId, flowId)
 | 
			
		||||
    fun getVerification(userId: String, flowId: String): VerificationTransaction? {
 | 
			
		||||
        return when (val verification = this.inner.getVerification(userId, flowId)) {
 | 
			
		||||
            is uniffi.olm.Verification.QrCodeV1 -> {
 | 
			
		||||
                val request = this.getVerificationRequest(userId, flowId) ?: return null
 | 
			
		||||
                QrCodeVerification(inner, request, verification.qrcode, requestSender, verificationListeners)
 | 
			
		||||
            }
 | 
			
		||||
            is uniffi.olm.Verification.SasV1    -> {
 | 
			
		||||
                SasVerification(inner, verification.sas, requestSender, verificationListeners)
 | 
			
		||||
            }
 | 
			
		||||
            null                                -> {
 | 
			
		||||
                // This branch exists because scanning a QR code is tied to the QrCodeVerification,
 | 
			
		||||
                // i.e. instead of branching into a scanned QR code verification from the verification request,
 | 
			
		||||
                // like it's done for SAS verifications, the public API expects us to create an empty dummy
 | 
			
		||||
                // QrCodeVerification object that gets populated once a QR code is scanned.
 | 
			
		||||
                val request = getVerificationRequest(userId, flowId) ?: return null
 | 
			
		||||
 | 
			
		||||
                if (request.canScanQrCodes()) {
 | 
			
		||||
                    QrCodeVerification(inner, request, null, requestSender, verificationListeners)
 | 
			
		||||
                } else {
 | 
			
		||||
                    null
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20,9 +20,7 @@ import android.os.Handler
 | 
			
		||||
import android.os.Looper
 | 
			
		||||
import com.squareup.moshi.Json
 | 
			
		||||
import com.squareup.moshi.JsonClass
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
 | 
			
		||||
@ -34,7 +32,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageRelationCont
 | 
			
		||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.Device
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.OlmMachine
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.QrCodeVerification
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.RequestSender
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.SasVerification
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.VerificationRequest
 | 
			
		||||
@ -43,14 +40,15 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
 | 
			
		||||
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uniffi.olm.Verification
 | 
			
		||||
 | 
			
		||||
/** A helper class to deserialize to-device `m.key.verification.*` events to fetch the transaction id out */
 | 
			
		||||
@JsonClass(generateAdapter = true)
 | 
			
		||||
internal data class ToDeviceVerificationEvent(
 | 
			
		||||
        @Json(name = "sender") val sender: String?,
 | 
			
		||||
        @Json(name = "transaction_id") val transactionId: String,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/** Helper method to fetch the unique ID of the verification event */
 | 
			
		||||
private fun getFlowId(event: Event): String? {
 | 
			
		||||
    return if (event.eventId != null) {
 | 
			
		||||
        val relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
 | 
			
		||||
@ -61,6 +59,7 @@ private fun getFlowId(event: Event): String? {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Convert a list of VerificationMethod into a list of strings that can be passed to the Rust side */
 | 
			
		||||
internal fun prepareMethods(methods: List<VerificationMethod>): List<String> {
 | 
			
		||||
    val stringMethods: MutableList<String> = methods.map { it.toValue() }.toMutableList()
 | 
			
		||||
 | 
			
		||||
@ -77,23 +76,22 @@ internal class RustVerificationService(
 | 
			
		||||
        private val requestSender: RequestSender,
 | 
			
		||||
) : VerificationService {
 | 
			
		||||
    private val uiHandler = Handler(Looper.getMainLooper())
 | 
			
		||||
    private var listeners = ArrayList<VerificationService.Listener>()
 | 
			
		||||
 | 
			
		||||
    override fun addListener(listener: VerificationService.Listener) {
 | 
			
		||||
        uiHandler.post {
 | 
			
		||||
            if (!listeners.contains(listener)) {
 | 
			
		||||
                listeners.add(listener)
 | 
			
		||||
            if (!this.olmMachine.verificationListeners.contains(listener)) {
 | 
			
		||||
                this.olmMachine.verificationListeners.add(listener)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun removeListener(listener: VerificationService.Listener) {
 | 
			
		||||
        uiHandler.post { listeners.remove(listener) }
 | 
			
		||||
        uiHandler.post { this.olmMachine.verificationListeners.remove(listener) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun dispatchTxAdded(tx: VerificationTransaction) {
 | 
			
		||||
        uiHandler.post {
 | 
			
		||||
            listeners.forEach {
 | 
			
		||||
            this.olmMachine.verificationListeners.forEach {
 | 
			
		||||
                try {
 | 
			
		||||
                    it.transactionCreated(tx)
 | 
			
		||||
                } catch (e: Throwable) {
 | 
			
		||||
@ -105,7 +103,7 @@ internal class RustVerificationService(
 | 
			
		||||
 | 
			
		||||
    private fun dispatchTxUpdated(tx: VerificationTransaction) {
 | 
			
		||||
        uiHandler.post {
 | 
			
		||||
            listeners.forEach {
 | 
			
		||||
            this.olmMachine.verificationListeners.forEach {
 | 
			
		||||
                try {
 | 
			
		||||
                    it.transactionUpdated(tx)
 | 
			
		||||
                } catch (e: Throwable) {
 | 
			
		||||
@ -118,7 +116,7 @@ internal class RustVerificationService(
 | 
			
		||||
    private fun dispatchRequestAdded(tx: PendingVerificationRequest) {
 | 
			
		||||
        Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx")
 | 
			
		||||
        uiHandler.post {
 | 
			
		||||
            listeners.forEach {
 | 
			
		||||
            this.olmMachine.verificationListeners.forEach {
 | 
			
		||||
                try {
 | 
			
		||||
                    it.verificationRequestCreated(tx)
 | 
			
		||||
                } catch (e: Throwable) {
 | 
			
		||||
@ -188,30 +186,11 @@ internal class RustVerificationService(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? {
 | 
			
		||||
        val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
 | 
			
		||||
 | 
			
		||||
        return if (request != null) {
 | 
			
		||||
            VerificationRequest(
 | 
			
		||||
                    this.olmMachine.inner(),
 | 
			
		||||
                    request,
 | 
			
		||||
                    requestSender,
 | 
			
		||||
                    listeners,
 | 
			
		||||
            )
 | 
			
		||||
        } else {
 | 
			
		||||
            null
 | 
			
		||||
        }
 | 
			
		||||
        return this.olmMachine.getVerificationRequest(otherUserId, transactionId)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun getDevice(userId: String, deviceID: String): Device? {
 | 
			
		||||
        val device = withContext(Dispatchers.IO) {
 | 
			
		||||
            olmMachine.inner().getDevice(userId, deviceID)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return if (device != null) {
 | 
			
		||||
            Device(this.olmMachine.inner(), device, this.requestSender, this.listeners)
 | 
			
		||||
        } else {
 | 
			
		||||
            null
 | 
			
		||||
        }
 | 
			
		||||
        return this.olmMachine.getDevice(userId, deviceID)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) {
 | 
			
		||||
@ -230,40 +209,14 @@ internal class RustVerificationService(
 | 
			
		||||
            otherUserId: String,
 | 
			
		||||
            tid: String,
 | 
			
		||||
    ): VerificationTransaction? {
 | 
			
		||||
        return when (val verification = this.olmMachine.getVerification(otherUserId, tid)) {
 | 
			
		||||
            is Verification.QrCodeV1 -> {
 | 
			
		||||
                val request = getVerificationRequest(otherUserId, tid) ?: return null
 | 
			
		||||
                QrCodeVerification(this.olmMachine.inner(), request, verification.qrcode, this.requestSender, this.listeners)
 | 
			
		||||
            }
 | 
			
		||||
            is Verification.SasV1    -> {
 | 
			
		||||
                SasVerification(this.olmMachine.inner(), verification.sas, this.requestSender, this.listeners)
 | 
			
		||||
            }
 | 
			
		||||
            null                     -> {
 | 
			
		||||
                // This branch exists because scanning a QR code is tied to the QrCodeVerification,
 | 
			
		||||
                // i.e. instead of branching into a scanned QR code verification from the verification request,
 | 
			
		||||
                // like it's done for SAS verifications, the public API expects us to create an empty dummy
 | 
			
		||||
                // QrCodeVerification object that gets populated once a QR code is scanned.
 | 
			
		||||
                val request = getVerificationRequest(otherUserId, tid) ?: return null
 | 
			
		||||
 | 
			
		||||
                if (request.canScanQrCodes()) {
 | 
			
		||||
                    QrCodeVerification(this.olmMachine.inner(), request, null, this.requestSender, this.listeners)
 | 
			
		||||
                } else {
 | 
			
		||||
                    null
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return this.olmMachine.getVerification(otherUserId, tid)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getExistingVerificationRequests(
 | 
			
		||||
            otherUserId: String
 | 
			
		||||
    ): List<PendingVerificationRequest> {
 | 
			
		||||
        return this.olmMachine.getVerificationRequests(otherUserId).map {
 | 
			
		||||
            VerificationRequest(
 | 
			
		||||
                    this.olmMachine.inner(),
 | 
			
		||||
                    it,
 | 
			
		||||
                    this.requestSender,
 | 
			
		||||
                    this.listeners,
 | 
			
		||||
            ).toPendingVerificationRequest()
 | 
			
		||||
            it.toPendingVerificationRequest()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -314,7 +267,12 @@ internal class RustVerificationService(
 | 
			
		||||
            requestSender.sendVerificationRequest(result!!.request)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return VerificationRequest(this.olmMachine.inner(), result!!.verification, this.requestSender, this.listeners).toPendingVerificationRequest()
 | 
			
		||||
        return VerificationRequest(
 | 
			
		||||
                this.olmMachine.inner(),
 | 
			
		||||
                result!!.verification,
 | 
			
		||||
                this.requestSender,
 | 
			
		||||
                this.olmMachine.verificationListeners
 | 
			
		||||
        ).toPendingVerificationRequest()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun requestKeyVerificationInDMs(
 | 
			
		||||
@ -332,7 +290,12 @@ internal class RustVerificationService(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val innerRequest = this.olmMachine.inner().requestVerification(otherUserId, roomId, eventID, stringMethods)!!
 | 
			
		||||
        return VerificationRequest(this.olmMachine.inner(), innerRequest, this.requestSender, this.listeners).toPendingVerificationRequest()
 | 
			
		||||
        return VerificationRequest(
 | 
			
		||||
                this.olmMachine.inner(),
 | 
			
		||||
                innerRequest,
 | 
			
		||||
                this.requestSender,
 | 
			
		||||
                this.olmMachine.verificationListeners
 | 
			
		||||
        ).toPendingVerificationRequest()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun readyPendingVerification(
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user