mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-01-01 13:58:32 +03:00
crypto: Move most of the getters of verification objecs into the olm machine
This commit is contained in:
parent
38ce3ebed7
commit
cbed5be810
3 changed files with 96 additions and 82 deletions
|
@ -392,7 +392,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setRustLogger()
|
setRustLogger()
|
||||||
val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver)
|
val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver, sender)
|
||||||
olmMachine = machine
|
olmMachine = machine
|
||||||
verificationService = RustVerificationService(machine, this.sender)
|
verificationService = RustVerificationService(machine, this.sender)
|
||||||
Timber.v(
|
Timber.v(
|
||||||
|
@ -482,7 +482,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
|
override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
|
||||||
return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) {
|
return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
this@DefaultCryptoService.olmMachine?.getDevice(userId, deviceId)
|
this@DefaultCryptoService.olmMachine?.getCryptoDeviceInfo(userId, deviceId)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
|
|
|
@ -26,6 +26,8 @@ import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.matrix.android.sdk.api.listeners.ProgressListener
|
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.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.Content
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
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.ProgressListener as RustProgressListener
|
||||||
import uniffi.olm.Request
|
import uniffi.olm.Request
|
||||||
import uniffi.olm.RequestType
|
import uniffi.olm.RequestType
|
||||||
import uniffi.olm.Verification
|
import uniffi.olm.Verification as InnerVerification
|
||||||
import uniffi.olm.VerificationRequest
|
|
||||||
import uniffi.olm.setLogger
|
import uniffi.olm.setLogger
|
||||||
|
|
||||||
class CryptoLogger : Logger {
|
class CryptoLogger : Logger {
|
||||||
|
@ -122,10 +123,12 @@ internal class OlmMachine(
|
||||||
user_id: String,
|
user_id: String,
|
||||||
device_id: String,
|
device_id: String,
|
||||||
path: File,
|
path: File,
|
||||||
deviceObserver: DeviceUpdateObserver
|
deviceObserver: DeviceUpdateObserver,
|
||||||
|
private val requestSender: RequestSender,
|
||||||
) {
|
) {
|
||||||
private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString())
|
private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString())
|
||||||
private val deviceUpdateObserver = deviceObserver
|
private val deviceUpdateObserver = deviceObserver
|
||||||
|
internal val verificationListeners = ArrayList<VerificationService.Listener>()
|
||||||
|
|
||||||
/** Get our own user ID. */
|
/** Get our own user ID. */
|
||||||
fun userId(): String {
|
fun userId(): String {
|
||||||
|
@ -429,17 +432,26 @@ internal class OlmMachine(
|
||||||
* @return The Device if it found one.
|
* @return The Device if it found one.
|
||||||
*/
|
*/
|
||||||
@Throws(CryptoStoreErrorException::class)
|
@Throws(CryptoStoreErrorException::class)
|
||||||
suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? =
|
suspend fun getCryptoDeviceInfo(userId: String, deviceId: String): CryptoDeviceInfo? {
|
||||||
withContext(Dispatchers.IO) {
|
return if (userId == userId() && deviceId == deviceId()) {
|
||||||
// Our own device isn't part of our store on the rust side, return it
|
// Our own device isn't part of our store on the Rust side, return it
|
||||||
// using our ownDevice method
|
// using our ownDevice method
|
||||||
if (userId == userId() && deviceId == deviceId()) {
|
ownDevice()
|
||||||
ownDevice()
|
} else {
|
||||||
} else {
|
val device = getRawDevice(userId, deviceId) ?: return null
|
||||||
val device = inner.getDevice(userId, deviceId)
|
toCryptoDeviceInfo(device)
|
||||||
if (device != null) toCryptoDeviceInfo(device) else null
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
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.
|
* 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
|
* @return The list of VerificationRequests that we share with the given user
|
||||||
*/
|
*/
|
||||||
fun getVerificationRequests(userId: String): List<VerificationRequest> {
|
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 */
|
/** Get a verification request for the given user with the given flow ID */
|
||||||
fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? {
|
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
|
/** Get an active verification for the given user and given flow ID
|
||||||
*
|
*
|
||||||
* This can return a SAS verification or a QR code verification
|
* This can return a SAS verification or a QR code verification
|
||||||
*/
|
*/
|
||||||
fun getVerification(userId: String, flowId: String): Verification? {
|
fun getVerification(userId: String, flowId: String): VerificationTransaction? {
|
||||||
return this.inner.getVerification(userId, flowId)
|
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 android.os.Looper
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.runBlocking
|
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.PendingVerificationRequest
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
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.api.session.room.model.message.MessageType
|
||||||
import org.matrix.android.sdk.internal.crypto.Device
|
import org.matrix.android.sdk.internal.crypto.Device
|
||||||
import org.matrix.android.sdk.internal.crypto.OlmMachine
|
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.RequestSender
|
||||||
import org.matrix.android.sdk.internal.crypto.SasVerification
|
import org.matrix.android.sdk.internal.crypto.SasVerification
|
||||||
import org.matrix.android.sdk.internal.crypto.VerificationRequest
|
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.VERIFICATION_METHOD_RECIPROCATE
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
|
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
|
||||||
import timber.log.Timber
|
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)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class ToDeviceVerificationEvent(
|
internal data class ToDeviceVerificationEvent(
|
||||||
@Json(name = "sender") val sender: String?,
|
@Json(name = "sender") val sender: String?,
|
||||||
@Json(name = "transaction_id") val transactionId: 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? {
|
private fun getFlowId(event: Event): String? {
|
||||||
return if (event.eventId != null) {
|
return if (event.eventId != null) {
|
||||||
val relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
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> {
|
internal fun prepareMethods(methods: List<VerificationMethod>): List<String> {
|
||||||
val stringMethods: MutableList<String> = methods.map { it.toValue() }.toMutableList()
|
val stringMethods: MutableList<String> = methods.map { it.toValue() }.toMutableList()
|
||||||
|
|
||||||
|
@ -77,23 +76,22 @@ internal class RustVerificationService(
|
||||||
private val requestSender: RequestSender,
|
private val requestSender: RequestSender,
|
||||||
) : VerificationService {
|
) : VerificationService {
|
||||||
private val uiHandler = Handler(Looper.getMainLooper())
|
private val uiHandler = Handler(Looper.getMainLooper())
|
||||||
private var listeners = ArrayList<VerificationService.Listener>()
|
|
||||||
|
|
||||||
override fun addListener(listener: VerificationService.Listener) {
|
override fun addListener(listener: VerificationService.Listener) {
|
||||||
uiHandler.post {
|
uiHandler.post {
|
||||||
if (!listeners.contains(listener)) {
|
if (!this.olmMachine.verificationListeners.contains(listener)) {
|
||||||
listeners.add(listener)
|
this.olmMachine.verificationListeners.add(listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeListener(listener: VerificationService.Listener) {
|
override fun removeListener(listener: VerificationService.Listener) {
|
||||||
uiHandler.post { listeners.remove(listener) }
|
uiHandler.post { this.olmMachine.verificationListeners.remove(listener) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dispatchTxAdded(tx: VerificationTransaction) {
|
private fun dispatchTxAdded(tx: VerificationTransaction) {
|
||||||
uiHandler.post {
|
uiHandler.post {
|
||||||
listeners.forEach {
|
this.olmMachine.verificationListeners.forEach {
|
||||||
try {
|
try {
|
||||||
it.transactionCreated(tx)
|
it.transactionCreated(tx)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
@ -105,7 +103,7 @@ internal class RustVerificationService(
|
||||||
|
|
||||||
private fun dispatchTxUpdated(tx: VerificationTransaction) {
|
private fun dispatchTxUpdated(tx: VerificationTransaction) {
|
||||||
uiHandler.post {
|
uiHandler.post {
|
||||||
listeners.forEach {
|
this.olmMachine.verificationListeners.forEach {
|
||||||
try {
|
try {
|
||||||
it.transactionUpdated(tx)
|
it.transactionUpdated(tx)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
@ -118,7 +116,7 @@ internal class RustVerificationService(
|
||||||
private fun dispatchRequestAdded(tx: PendingVerificationRequest) {
|
private fun dispatchRequestAdded(tx: PendingVerificationRequest) {
|
||||||
Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx")
|
Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx")
|
||||||
uiHandler.post {
|
uiHandler.post {
|
||||||
listeners.forEach {
|
this.olmMachine.verificationListeners.forEach {
|
||||||
try {
|
try {
|
||||||
it.verificationRequestCreated(tx)
|
it.verificationRequestCreated(tx)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
@ -188,30 +186,11 @@ internal class RustVerificationService(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? {
|
private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? {
|
||||||
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
return this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||||
|
|
||||||
return if (request != null) {
|
|
||||||
VerificationRequest(
|
|
||||||
this.olmMachine.inner(),
|
|
||||||
request,
|
|
||||||
requestSender,
|
|
||||||
listeners,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getDevice(userId: String, deviceID: String): Device? {
|
private suspend fun getDevice(userId: String, deviceID: String): Device? {
|
||||||
val device = withContext(Dispatchers.IO) {
|
return this.olmMachine.getDevice(userId, deviceID)
|
||||||
olmMachine.inner().getDevice(userId, deviceID)
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (device != null) {
|
|
||||||
Device(this.olmMachine.inner(), device, this.requestSender, this.listeners)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) {
|
override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) {
|
||||||
|
@ -230,40 +209,14 @@ internal class RustVerificationService(
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
tid: String,
|
tid: String,
|
||||||
): VerificationTransaction? {
|
): VerificationTransaction? {
|
||||||
return when (val verification = this.olmMachine.getVerification(otherUserId, tid)) {
|
return 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getExistingVerificationRequests(
|
override fun getExistingVerificationRequests(
|
||||||
otherUserId: String
|
otherUserId: String
|
||||||
): List<PendingVerificationRequest> {
|
): List<PendingVerificationRequest> {
|
||||||
return this.olmMachine.getVerificationRequests(otherUserId).map {
|
return this.olmMachine.getVerificationRequests(otherUserId).map {
|
||||||
VerificationRequest(
|
it.toPendingVerificationRequest()
|
||||||
this.olmMachine.inner(),
|
|
||||||
it,
|
|
||||||
this.requestSender,
|
|
||||||
this.listeners,
|
|
||||||
).toPendingVerificationRequest()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +267,12 @@ internal class RustVerificationService(
|
||||||
requestSender.sendVerificationRequest(result!!.request)
|
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(
|
override fun requestKeyVerificationInDMs(
|
||||||
|
@ -332,7 +290,12 @@ internal class RustVerificationService(
|
||||||
}
|
}
|
||||||
|
|
||||||
val innerRequest = this.olmMachine.inner().requestVerification(otherUserId, roomId, eventID, stringMethods)!!
|
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(
|
override fun readyPendingVerification(
|
||||||
|
|
Loading…
Reference in a new issue