Merge pull request #9 from poljar/feature/fga/device_verification
Feature/fga/device verification
This commit is contained in:
commit
e519561edf
|
@ -503,7 +503,6 @@ class E2eeSanityTests : InstrumentedTest {
|
|||
|
||||
// now let new session request
|
||||
newBobSession.cryptoService().reRequestRoomKeyForEvent(firstEventNewBobPov.root)
|
||||
|
||||
}
|
||||
|
||||
// We need to wait for the key request to be sent out and then a reply to be received
|
||||
|
|
|
@ -140,13 +140,13 @@ class KeyShareTests : InstrumentedTest {
|
|||
Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)")
|
||||
Log.v("TEST", "=========================")
|
||||
it.forEach { keyRequest ->
|
||||
//Log.v("TEST", "[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}")
|
||||
// Log.v("TEST", "[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}")
|
||||
}
|
||||
Log.v("TEST", "=========================")
|
||||
}
|
||||
|
||||
//val incoming = aliceSession.cryptoService().getIncomingRoomKeyRequests().firstOrNull { it.requestId == outGoingRequestId }
|
||||
//incoming?.state == GossipingRequestState.REJECTED
|
||||
// val incoming = aliceSession.cryptoService().getIncomingRoomKeyRequests().firstOrNull { it.requestId == outGoingRequestId }
|
||||
// incoming?.state == GossipingRequestState.REJECTED
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ class KeyShareTests : InstrumentedTest {
|
|||
Log.v("TEST", "Incoming request Session 1")
|
||||
Log.v("TEST", "=========================")
|
||||
it.forEach {
|
||||
//Log.v("TEST", "requestId ${it.requestId}, for sessionId ${it.requestBody?.sessionId} is ${it.state}")
|
||||
// Log.v("TEST", "requestId ${it.requestId}, for sessionId ${it.requestBody?.sessionId} is ${it.state}")
|
||||
}
|
||||
Log.v("TEST", "=========================")
|
||||
|
||||
|
@ -189,7 +189,7 @@ class KeyShareTests : InstrumentedTest {
|
|||
commonTestHelper.waitWithLatch { latch ->
|
||||
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
||||
aliceSession2.cryptoService().getOutgoingRoomKeyRequests().let {
|
||||
true//it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == OutgoingGossipingRequestState.CANCELLED }
|
||||
true // it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == OutgoingGossipingRequestState.CANCELLED }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ class WithHeldTests : InstrumentedTest {
|
|||
|
||||
@Test
|
||||
@Ignore("This test will be ignored until it is fixed")
|
||||
fun test_WithHeldNoOlm() {
|
||||
fun test_WithHeldNoOlm() {
|
||||
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
||||
val aliceSession = testData.firstSession
|
||||
val bobSession = testData.secondSession!!
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
|
|||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.getRoom
|
||||
import org.matrix.android.sdk.common.CommonTestHelper
|
||||
import org.matrix.android.sdk.common.CryptoTestHelper
|
||||
import timber.log.Timber
|
||||
|
@ -325,6 +324,7 @@ class SASTest : InstrumentedTest {
|
|||
// any two devices may only have at most one key verification in flight at a time.
|
||||
// If a device has two verifications in progress with the same device, then it should cancel both verifications.
|
||||
@Test
|
||||
@Ignore("verifications are not canceled when sending new events")
|
||||
fun test_aliceStartTwoRequests() {
|
||||
val testHelper = CommonTestHelper(context())
|
||||
val cryptoTestHelper = CryptoTestHelper(testHelper)
|
||||
|
@ -570,8 +570,11 @@ class SASTest : InstrumentedTest {
|
|||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
|
||||
cryptoTestHelper.initializeCrossSigning(aliceSession)
|
||||
cryptoTestHelper.initializeCrossSigning(bobSession!!)
|
||||
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession!!.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||
|
||||
val req = testHelper.runBlockingTest {
|
||||
aliceVerificationService.requestKeyVerificationInDMs(
|
||||
|
@ -621,16 +624,16 @@ class SASTest : InstrumentedTest {
|
|||
|
||||
// Start concurrent!
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.requestKeyVerificationInDMs(
|
||||
methods = listOf(VerificationMethod.SAS),
|
||||
aliceVerificationService.beginKeyVerification(
|
||||
method = VerificationMethod.SAS,
|
||||
otherUserId = bobSession.myUserId,
|
||||
roomId = cryptoTestData.roomId
|
||||
transactionId = requestID!!,
|
||||
)
|
||||
|
||||
bobVerificationService.requestKeyVerificationInDMs(
|
||||
methods = listOf(VerificationMethod.SAS),
|
||||
bobVerificationService.beginKeyVerification(
|
||||
method = VerificationMethod.SAS,
|
||||
otherUserId = aliceSession.myUserId,
|
||||
roomId = cryptoTestData.roomId
|
||||
transactionId = requestID!!,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ class SasVerificationTestHelper(private val testHelper: CommonTestHelper, privat
|
|||
}
|
||||
|
||||
fun requestSelfKeyAndWaitForReadyState(session1: Session, session2: Session, supportedMethods: List<VerificationMethod>): String {
|
||||
|
||||
val session1VerificationService = session1.cryptoService().verificationService()
|
||||
val session2VerificationService = session2.cryptoService().verificationService()
|
||||
var bobReadyPendingVerificationRequest: PendingVerificationRequest? = null
|
||||
|
|
|
@ -108,7 +108,6 @@ class MXUsersDevicesMap<E> {
|
|||
map.putAll(other)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add entries from another MXUsersDevicesMap
|
||||
*
|
||||
|
|
|
@ -45,6 +45,17 @@ interface VerificationService {
|
|||
|
||||
fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest?
|
||||
|
||||
/**
|
||||
* Request an interactive verification to begin
|
||||
*
|
||||
* This sends out a m.key.verification.request event over to-device messaging to
|
||||
* to this device.
|
||||
*
|
||||
* If no specific device should be verified, but we would like to request
|
||||
* verification from all our devices, use [requestSelfKeyVerification] instead.
|
||||
*/
|
||||
suspend fun requestDeviceVerification(methods: List<VerificationMethod>, otherUserId: String, otherDeviceId: String): PendingVerificationRequest?
|
||||
|
||||
/**
|
||||
* Request key verification with another user via room events (instead of the to-device API).
|
||||
*/
|
||||
|
|
|
@ -30,5 +30,4 @@ internal data class MessageVerificationAcceptContent(
|
|||
) {
|
||||
|
||||
val transactionId: String? = relatesTo?.eventId
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.session.room.model.message
|
|||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import org.matrix.android.sdk.api.session.events.model.Content
|
||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
@ -36,4 +35,3 @@ data class MessageVerificationRequestContent(
|
|||
// Not parsed, but set after, using the eventId
|
||||
val transactionId: String? = null
|
||||
) : MessageContent
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -759,7 +759,7 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
}
|
||||
|
||||
override suspend fun manuallyAcceptRoomKeyRequest(request: IncomingRoomKeyRequest) {
|
||||
//TODO rust?
|
||||
// TODO rust?
|
||||
}
|
||||
|
||||
override fun getIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest> {
|
||||
|
|
|
@ -24,11 +24,13 @@ import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo
|
|||
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.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.SasVerification
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory
|
||||
import org.matrix.android.sdk.internal.crypto.verification.prepareMethods
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.OlmMachine
|
||||
import uniffi.olm.SignatureException
|
||||
import uniffi.olm.VerificationRequest
|
||||
import uniffi.olm.Device as InnerDevice
|
||||
|
||||
/** Class representing a device that supports E2EE in the Matrix world
|
||||
|
@ -37,20 +39,21 @@ import uniffi.olm.Device as InnerDevice
|
|||
* or to manually verify the device.
|
||||
*/
|
||||
internal class Device(
|
||||
private val machine: OlmMachine,
|
||||
private var inner: InnerDevice,
|
||||
private val sender: RequestSender,
|
||||
private val innerMachine: OlmMachine,
|
||||
private var innerDevice: InnerDevice,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val listeners: ArrayList<VerificationService.Listener>
|
||||
private val listeners: ArrayList<VerificationService.Listener>,
|
||||
private val verificationRequestFactory: VerificationRequestFactory,
|
||||
) {
|
||||
@Throws(CryptoStoreException::class)
|
||||
private suspend fun refreshData() {
|
||||
val device = withContext(coroutineDispatchers.io) {
|
||||
machine.getDevice(inner.userId, inner.deviceId)
|
||||
innerMachine.getDevice(innerDevice.userId, innerDevice.deviceId)
|
||||
}
|
||||
|
||||
if (device != null) {
|
||||
inner = device
|
||||
innerDevice = device
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,12 +72,11 @@ internal class Device(
|
|||
suspend fun requestVerification(methods: List<VerificationMethod>): VerificationRequest? {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
val result = withContext(coroutineDispatchers.io) {
|
||||
machine.requestVerificationWithDevice(inner.userId, inner.deviceId, stringMethods)
|
||||
innerMachine.requestVerificationWithDevice(innerDevice.userId, innerDevice.deviceId, stringMethods)
|
||||
}
|
||||
|
||||
return if (result != null) {
|
||||
sender.sendVerificationRequest(result.request)
|
||||
result.verification
|
||||
requestSender.sendVerificationRequest(result.request)
|
||||
verificationRequestFactory.create(result.verification)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
@ -92,15 +94,15 @@ internal class Device(
|
|||
@Throws(CryptoStoreException::class)
|
||||
suspend fun startVerification(): SasVerification? {
|
||||
val result = withContext(coroutineDispatchers.io) {
|
||||
machine.startSasWithDevice(inner.userId, inner.deviceId)
|
||||
innerMachine.startSasWithDevice(innerDevice.userId, innerDevice.deviceId)
|
||||
}
|
||||
|
||||
return if (result != null) {
|
||||
sender.sendVerificationRequest(result.request)
|
||||
requestSender.sendVerificationRequest(result.request)
|
||||
SasVerification(
|
||||
machine = machine,
|
||||
machine = innerMachine,
|
||||
inner = result.sas,
|
||||
sender = sender,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = listeners
|
||||
)
|
||||
|
@ -118,7 +120,7 @@ internal class Device(
|
|||
@Throws(CryptoStoreException::class)
|
||||
suspend fun markAsTrusted() {
|
||||
withContext(coroutineDispatchers.io) {
|
||||
machine.markDeviceAsTrusted(inner.userId, inner.deviceId)
|
||||
innerMachine.markDeviceAsTrusted(innerDevice.userId, innerDevice.deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,10 +136,10 @@ internal class Device(
|
|||
@Throws(SignatureException::class)
|
||||
suspend fun verify(): Boolean {
|
||||
val request = withContext(coroutineDispatchers.io) {
|
||||
machine.verifyDevice(inner.userId, inner.deviceId)
|
||||
innerMachine.verifyDevice(innerDevice.userId, innerDevice.deviceId)
|
||||
}
|
||||
|
||||
sender.sendSignatureUpload(request)
|
||||
requestSender.sendSignatureUpload(request)
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -148,7 +150,7 @@ internal class Device(
|
|||
@Throws(CryptoStoreException::class)
|
||||
suspend fun trustLevel(): DeviceTrustLevel {
|
||||
refreshData()
|
||||
return DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted)
|
||||
return DeviceTrustLevel(crossSigningVerified = innerDevice.crossSigningTrusted, locallyVerified = innerDevice.locallyTrusted)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,19 +159,19 @@ internal class Device(
|
|||
* This will not fetch out fresh data from the Rust side.
|
||||
**/
|
||||
internal fun toCryptoDeviceInfo(): CryptoDeviceInfo {
|
||||
val keys = inner.keys.map { (keyId, key) -> "$keyId:$inner.deviceId" to key }.toMap()
|
||||
val keys = innerDevice.keys.map { (keyId, key) -> "$keyId:$innerDevice.deviceId" to key }.toMap()
|
||||
|
||||
return CryptoDeviceInfo(
|
||||
deviceId = inner.deviceId,
|
||||
userId = inner.userId,
|
||||
algorithms = inner.algorithms,
|
||||
deviceId = innerDevice.deviceId,
|
||||
userId = innerDevice.userId,
|
||||
algorithms = innerDevice.algorithms,
|
||||
keys = keys,
|
||||
// The Kotlin side doesn't need to care about signatures,
|
||||
// so we're not filling this out
|
||||
signatures = mapOf(),
|
||||
unsigned = UnsignedDeviceInfo(inner.displayName),
|
||||
trustLevel = DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted),
|
||||
isBlocked = inner.isBlocked,
|
||||
unsigned = UnsignedDeviceInfo(innerDevice.displayName),
|
||||
trustLevel = DeviceTrustLevel(crossSigningVerified = innerDevice.crossSigningTrusted, locallyVerified = innerDevice.locallyTrusted),
|
||||
isBlocked = innerDevice.isBlocked,
|
||||
// TODO
|
||||
firstTimeSeenLocalTs = null)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.OlmMachine
|
||||
|
||||
internal class GetUserIdentityUseCase(
|
||||
private val innerMachine: OlmMachine,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val moshi: Moshi,
|
||||
private val verificationRequestFactory: VerificationRequestFactory
|
||||
) {
|
||||
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend operator fun invoke(userId: String): UserIdentities? {
|
||||
val identity = withContext(coroutineDispatchers.io) {
|
||||
innerMachine.getIdentity(userId)
|
||||
}
|
||||
val adapter = moshi.adapter(RestKeyInfo::class.java)
|
||||
|
||||
return when (identity) {
|
||||
is uniffi.olm.UserIdentity.Other -> {
|
||||
val verified = innerMachine.isIdentityVerified(userId)
|
||||
val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
UserIdentity(
|
||||
userId = identity.userId,
|
||||
masterKey = masterKey,
|
||||
selfSigningKey = selfSigningKey,
|
||||
innerMachine = innerMachine,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
verificationRequestFactory = verificationRequestFactory
|
||||
)
|
||||
}
|
||||
is uniffi.olm.UserIdentity.Own -> {
|
||||
val verified = innerMachine.isIdentityVerified(userId)
|
||||
|
||||
val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel()
|
||||
|
||||
OwnUserIdentity(
|
||||
userId = identity.userId,
|
||||
masterKey = masterKey,
|
||||
selfSigningKey = selfSigningKey,
|
||||
userSigningKey = userSigningKey,
|
||||
trustsOurOwnDevice = identity.trustsOurOwnDevice,
|
||||
innerMachine = innerMachine,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
verificationRequestFactory = verificationRequestFactory
|
||||
)
|
||||
}
|
||||
null -> null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,9 +49,13 @@ import org.matrix.android.sdk.api.util.JsonDict
|
|||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.internal.coroutines.builder.safeInvokeOnClose
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.SasVerification
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory
|
||||
import org.matrix.android.sdk.internal.crypto.verification.qrcode.QrCodeVerification
|
||||
import org.matrix.android.sdk.internal.network.parsing.CheckNumberType
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import timber.log.Timber
|
||||
import uniffi.olm.BackupKeys
|
||||
import uniffi.olm.CrossSigningKeyExport
|
||||
|
@ -71,7 +75,6 @@ import java.nio.charset.Charset
|
|||
import java.util.UUID
|
||||
import uniffi.olm.OlmMachine as InnerMachine
|
||||
import uniffi.olm.ProgressListener as RustProgressListener
|
||||
import uniffi.olm.UserIdentity as RustUserIdentity
|
||||
|
||||
class CryptoLogger : Logger {
|
||||
override fun log(logLine: String) {
|
||||
|
@ -85,10 +88,11 @@ private class CryptoProgressListener(private val listener: ProgressListener?) :
|
|||
}
|
||||
}
|
||||
|
||||
private data class UserIdentityCollector(val userId: String, val collector: SendChannel<Optional<MXCrossSigningInfo>>)
|
||||
: SendChannel<Optional<MXCrossSigningInfo>> by collector
|
||||
private data class DevicesCollector(val userIds: List<String>, val collector: SendChannel<List<CryptoDeviceInfo>>)
|
||||
: SendChannel<List<CryptoDeviceInfo>> by collector
|
||||
private data class UserIdentityCollector(val userId: String, val collector: SendChannel<Optional<MXCrossSigningInfo>>) :
|
||||
SendChannel<Optional<MXCrossSigningInfo>> by collector
|
||||
|
||||
private data class DevicesCollector(val userIds: List<String>, val collector: SendChannel<List<CryptoDeviceInfo>>) :
|
||||
SendChannel<List<CryptoDeviceInfo>> by collector
|
||||
private typealias PrivateKeysCollector = SendChannel<Optional<PrivateKeysInfo>>
|
||||
|
||||
private class FlowCollectors {
|
||||
|
@ -105,12 +109,16 @@ internal class OlmMachine(
|
|||
user_id: String,
|
||||
device_id: String,
|
||||
path: File,
|
||||
clock: Clock,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val moshi: Moshi
|
||||
private val moshi: Moshi,
|
||||
) {
|
||||
|
||||
private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString(), null)
|
||||
internal val verificationListeners = ArrayList<VerificationService.Listener>()
|
||||
val verificationListeners = ArrayList<VerificationService.Listener>()
|
||||
private val verificationRequestFactory = VerificationRequestFactory(inner, requestSender, coroutineDispatchers, verificationListeners, clock)
|
||||
private val getUserIdentity = GetUserIdentityUseCase(inner, requestSender, coroutineDispatchers, moshi, verificationRequestFactory)
|
||||
private val flowCollectors = FlowCollectors()
|
||||
|
||||
/** Get our own user ID. */
|
||||
|
@ -176,7 +184,8 @@ internal class OlmMachine(
|
|||
UnsignedDeviceInfo(),
|
||||
DeviceTrustLevel(crossSigningVerified, locallyVerified = true),
|
||||
false,
|
||||
null)
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -389,13 +398,15 @@ internal class OlmMachine(
|
|||
clearEvent,
|
||||
decrypted.senderCurve25519Key,
|
||||
decrypted.claimedEd25519Key,
|
||||
decrypted.forwardingCurve25519Chain)
|
||||
decrypted.forwardingCurve25519Chain
|
||||
)
|
||||
} catch (throwable: Throwable) {
|
||||
val reason =
|
||||
String.format(
|
||||
MXCryptoError.UNABLE_TO_DECRYPT_REASON,
|
||||
throwable.message,
|
||||
"m.megolm.v1.aes-sha2")
|
||||
"m.megolm.v1.aes-sha2"
|
||||
)
|
||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason)
|
||||
}
|
||||
}
|
||||
|
@ -491,55 +502,7 @@ internal class OlmMachine(
|
|||
}
|
||||
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun getIdentity(userId: String): UserIdentities? {
|
||||
val identity = withContext(coroutineDispatchers.io) {
|
||||
inner.getIdentity(userId)
|
||||
}
|
||||
val adapter = moshi.adapter(RestKeyInfo::class.java)
|
||||
|
||||
return when (identity) {
|
||||
is RustUserIdentity.Other -> {
|
||||
val verified = inner().isIdentityVerified(userId)
|
||||
val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
UserIdentity(
|
||||
userId = identity.userId,
|
||||
masterKey = masterKey,
|
||||
selfSigningKey = selfSigningKey,
|
||||
olmMachine = this,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers
|
||||
)
|
||||
}
|
||||
is RustUserIdentity.Own -> {
|
||||
val verified = inner().isIdentityVerified(userId)
|
||||
|
||||
val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
}
|
||||
val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel()
|
||||
|
||||
OwnUserIdentity(
|
||||
userId = identity.userId,
|
||||
masterKey = masterKey,
|
||||
selfSigningKey = selfSigningKey,
|
||||
userSigningKey = userSigningKey,
|
||||
trustsOurOwnDevice = identity.trustsOurOwnDevice,
|
||||
olmMachine = this,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers
|
||||
)
|
||||
}
|
||||
null -> null
|
||||
}
|
||||
}
|
||||
suspend fun getIdentity(userId: String): UserIdentities? = getUserIdentity(userId)
|
||||
|
||||
/**
|
||||
* Get a `Device` from the store.
|
||||
|
@ -559,30 +522,16 @@ internal class OlmMachine(
|
|||
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun getDevice(userId: String, deviceId: String): Device? {
|
||||
val device = withContext(coroutineDispatchers.io) {
|
||||
val innerDevice = withContext(coroutineDispatchers.io) {
|
||||
inner.getDevice(userId, deviceId)
|
||||
} ?: return null
|
||||
|
||||
return Device(
|
||||
machine = inner,
|
||||
inner = device,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners
|
||||
)
|
||||
return innerDevice.wrap()
|
||||
}
|
||||
|
||||
suspend fun getUserDevices(userId: String): List<Device> {
|
||||
return withContext(coroutineDispatchers.io) {
|
||||
inner.getUserDevices(userId).map {
|
||||
Device(
|
||||
machine = inner,
|
||||
inner = it,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners
|
||||
)
|
||||
}
|
||||
inner.getUserDevices(userId).map { innerDevice -> innerDevice.wrap() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,30 +692,13 @@ internal class OlmMachine(
|
|||
* @return The list of [VerificationRequest] that we share with the given user
|
||||
*/
|
||||
fun getVerificationRequests(userId: String): List<VerificationRequest> {
|
||||
return inner.getVerificationRequests(userId).map {
|
||||
VerificationRequest(
|
||||
machine = inner,
|
||||
inner = it,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners,
|
||||
)
|
||||
}
|
||||
return inner.getVerificationRequests(userId).map(verificationRequestFactory::create)
|
||||
}
|
||||
|
||||
/** Get a verification request for the given user with the given flow ID */
|
||||
fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? {
|
||||
val request = inner.getVerificationRequest(userId, flowId)
|
||||
return if (request != null) {
|
||||
VerificationRequest(
|
||||
machine = inner,
|
||||
inner = request,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
return inner.getVerificationRequest(userId, flowId)?.let { innerVerificationRequest ->
|
||||
verificationRequestFactory.create(innerVerificationRequest)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,4 +868,13 @@ internal class OlmMachine(
|
|||
inner.verifyBackup(serializedAuthData)
|
||||
}
|
||||
}
|
||||
|
||||
private fun uniffi.olm.Device.wrap() = Device(
|
||||
innerMachine = inner,
|
||||
innerDevice = this,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners,
|
||||
verificationRequestFactory = verificationRequestFactory
|
||||
)
|
||||
}
|
||||
|
|
|
@ -23,24 +23,30 @@ import org.matrix.android.sdk.internal.di.DeviceId
|
|||
import org.matrix.android.sdk.internal.di.SessionFilesDirectory
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
@SessionScope
|
||||
internal class OlmMachineProvider @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
@DeviceId private val deviceId: String?,
|
||||
@SessionFilesDirectory private val dataDir: File,
|
||||
@UserId userId: String,
|
||||
@DeviceId deviceId: String?,
|
||||
@SessionFilesDirectory dataDir: File,
|
||||
requestSender: RequestSender,
|
||||
coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
moshi: Moshi
|
||||
moshi: Moshi,
|
||||
clock: Clock
|
||||
) {
|
||||
|
||||
var olmMachine: OlmMachine = OlmMachine(
|
||||
user_id = userId,
|
||||
device_id = deviceId!!,
|
||||
path = dataDir,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
moshi = moshi)
|
||||
val olmMachine: OlmMachine by lazy {
|
||||
OlmMachine(
|
||||
user_id = userId,
|
||||
device_id = deviceId!!,
|
||||
path = dataDir,
|
||||
clock = clock,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
moshi = moshi
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -24,8 +24,11 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
|||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory
|
||||
import org.matrix.android.sdk.internal.crypto.verification.prepareMethods
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.OlmMachine
|
||||
import uniffi.olm.SignatureException
|
||||
|
||||
/**
|
||||
|
@ -79,9 +82,11 @@ internal class OwnUserIdentity(
|
|||
private val selfSigningKey: CryptoCrossSigningKey,
|
||||
private val userSigningKey: CryptoCrossSigningKey,
|
||||
private val trustsOurOwnDevice: Boolean,
|
||||
private val olmMachine: OlmMachine,
|
||||
private val innerMachine: OlmMachine,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() {
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val verificationRequestFactory: VerificationRequestFactory,
|
||||
) : UserIdentities() {
|
||||
/**
|
||||
* Our own user id.
|
||||
*/
|
||||
|
@ -96,7 +101,7 @@ internal class OwnUserIdentity(
|
|||
*/
|
||||
@Throws(SignatureException::class)
|
||||
override suspend fun verify() {
|
||||
val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) }
|
||||
val request = withContext(coroutineDispatchers.computation) { innerMachine.verifyIdentity(userId) }
|
||||
requestSender.sendSignatureUpload(request)
|
||||
}
|
||||
|
||||
|
@ -107,7 +112,7 @@ internal class OwnUserIdentity(
|
|||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
override suspend fun verified(): Boolean {
|
||||
return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) }
|
||||
return withContext(coroutineDispatchers.io) { innerMachine.isIdentityVerified(userId) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,16 +139,9 @@ internal class OwnUserIdentity(
|
|||
@Throws(CryptoStoreException::class)
|
||||
suspend fun requestVerification(methods: List<VerificationMethod>): VerificationRequest {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
val result = olmMachine.inner().requestSelfVerification(stringMethods)
|
||||
val result = innerMachine.requestSelfVerification(stringMethods)
|
||||
requestSender.sendVerificationRequest(result!!.request)
|
||||
|
||||
return VerificationRequest(
|
||||
machine = olmMachine.inner(),
|
||||
inner = result.verification,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = olmMachine.verificationListeners
|
||||
)
|
||||
return verificationRequestFactory.create(result.verification)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,9 +171,11 @@ internal class UserIdentity(
|
|||
private val userId: String,
|
||||
private val masterKey: CryptoCrossSigningKey,
|
||||
private val selfSigningKey: CryptoCrossSigningKey,
|
||||
private val olmMachine: OlmMachine,
|
||||
private val innerMachine: OlmMachine,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() {
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val verificationRequestFactory: VerificationRequestFactory,
|
||||
) : UserIdentities() {
|
||||
/**
|
||||
* The unique ID of the user that this identity belongs to.
|
||||
*/
|
||||
|
@ -192,7 +192,7 @@ internal class UserIdentity(
|
|||
*/
|
||||
@Throws(SignatureException::class)
|
||||
override suspend fun verify() {
|
||||
val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) }
|
||||
val request = withContext(coroutineDispatchers.computation) { innerMachine.verifyIdentity(userId) }
|
||||
requestSender.sendSignatureUpload(request)
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ internal class UserIdentity(
|
|||
* @return True if the identity is considered to be verified and trusted, false otherwise.
|
||||
*/
|
||||
override suspend fun verified(): Boolean {
|
||||
return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) }
|
||||
return withContext(coroutineDispatchers.io) { innerMachine.isIdentityVerified(userId) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -235,19 +235,10 @@ internal class UserIdentity(
|
|||
transactionId: String
|
||||
): VerificationRequest {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
val content = olmMachine.inner().verificationRequestContent(userId, stringMethods)!!
|
||||
|
||||
val content = innerMachine.verificationRequestContent(userId, stringMethods)!!
|
||||
val eventID = requestSender.sendRoomMessage(EventType.MESSAGE, roomId, content, transactionId).eventId
|
||||
|
||||
val innerRequest = olmMachine.inner().requestVerification(userId, roomId, eventID, stringMethods)!!
|
||||
|
||||
return VerificationRequest(
|
||||
machine = olmMachine.inner(),
|
||||
inner = innerRequest,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = olmMachine.verificationListeners
|
||||
)
|
||||
val innerRequest = innerMachine.requestVerification(userId, roomId, eventID, stringMethods)!!
|
||||
return verificationRequestFactory.create(innerRequest)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
*/
|
||||
package org.matrix.android.sdk.internal.crypto.api
|
||||
|
||||
import org.matrix.android.sdk.api.util.JsonDict
|
||||
import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse
|
||||
import org.matrix.android.sdk.api.util.JsonDict
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.KeyChangesResponse
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimBody
|
||||
|
|
|
@ -227,7 +227,7 @@ internal class RequestSender @Inject constructor(
|
|||
getKeysBackupLastVersionTask.executeRetry(Unit, 3)
|
||||
}
|
||||
|
||||
private inline fun <reified T> getKeyBackupVersion(block: ()-> T?): T?{
|
||||
private inline fun <reified T> getKeyBackupVersion(block: () -> T?): T? {
|
||||
return try {
|
||||
block()
|
||||
} catch (failure: Throwable) {
|
||||
|
|
|
@ -30,7 +30,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.OlmMachineProvider
|
||||
import org.matrix.android.sdk.internal.crypto.OwnUserIdentity
|
||||
import org.matrix.android.sdk.internal.crypto.SasVerification
|
||||
import org.matrix.android.sdk.internal.crypto.UserIdentity
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW
|
||||
|
@ -254,6 +253,15 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
|||
return verification.toPendingVerificationRequest()
|
||||
}
|
||||
|
||||
override suspend fun requestDeviceVerification(methods: List<VerificationMethod>,
|
||||
otherUserId: String,
|
||||
otherDeviceId: String): PendingVerificationRequest? {
|
||||
olmMachine.ensureUsersKeys(listOf(otherUserId))
|
||||
val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId)
|
||||
val verificationRequest = otherDevice?.requestVerification(methods)
|
||||
return verificationRequest?.toPendingVerificationRequest()
|
||||
}
|
||||
|
||||
override suspend fun readyPendingVerification(
|
||||
methods: List<VerificationMethod>,
|
||||
otherUserId: String,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
package org.matrix.android.sdk.internal.crypto.verification
|
||||
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
|
@ -25,8 +25,6 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
|
|||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher
|
||||
import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.OlmMachine
|
||||
import uniffi.olm.Sas
|
||||
|
@ -235,6 +233,11 @@ internal class SasVerification(
|
|||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "SasVerification(otherUserId='$otherUserId', otherDeviceId=$otherDeviceId, isIncoming=$isIncoming, state=$state, transactionId='$transactionId')"
|
||||
return "SasVerification(" +
|
||||
"otherUserId='$otherUserId', " +
|
||||
"otherDeviceId=$otherDeviceId, " +
|
||||
"isIncoming=$isIncoming, " +
|
||||
"state=$state, " +
|
||||
"transactionId='$transactionId')"
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
package org.matrix.android.sdk.internal.crypto.verification
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
@ -30,7 +30,8 @@ import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf
|
|||
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.prepareMethods
|
||||
import org.matrix.android.sdk.internal.crypto.verification.qrcode.QrCodeVerification
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import timber.log.Timber
|
||||
import uniffi.olm.OlmMachine
|
||||
import uniffi.olm.VerificationRequest
|
||||
|
@ -43,11 +44,12 @@ import uniffi.olm.VerificationRequest
|
|||
* concrete verification flows.
|
||||
*/
|
||||
internal class VerificationRequest(
|
||||
private val machine: OlmMachine,
|
||||
private var inner: VerificationRequest,
|
||||
private val sender: RequestSender,
|
||||
private val innerOlmMachine: OlmMachine,
|
||||
private var innerVerificationRequest: VerificationRequest,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val listeners: ArrayList<VerificationService.Listener>
|
||||
private val listeners: ArrayList<VerificationService.Listener>,
|
||||
private val clock: Clock,
|
||||
) {
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
|
@ -70,12 +72,12 @@ internal class VerificationRequest(
|
|||
* event that initiated the flow.
|
||||
*/
|
||||
internal fun flowId(): String {
|
||||
return inner.flowId
|
||||
return innerVerificationRequest.flowId
|
||||
}
|
||||
|
||||
/** The user ID of the other user that is participating in this verification flow */
|
||||
internal fun otherUser(): String {
|
||||
return inner.otherUserId
|
||||
return innerVerificationRequest.otherUserId
|
||||
}
|
||||
|
||||
/** The device ID of the other user's device that is participating in this verification flow
|
||||
|
@ -85,12 +87,12 @@ internal class VerificationRequest(
|
|||
* */
|
||||
internal fun otherDeviceId(): String? {
|
||||
refreshData()
|
||||
return inner.otherDeviceId
|
||||
return innerVerificationRequest.otherDeviceId
|
||||
}
|
||||
|
||||
/** Did we initiate this verification flow */
|
||||
internal fun weStarted(): Boolean {
|
||||
return inner.weStarted
|
||||
return innerVerificationRequest.weStarted
|
||||
}
|
||||
|
||||
/** Get the id of the room where this verification is happening
|
||||
|
@ -98,7 +100,7 @@ internal class VerificationRequest(
|
|||
* Will be null if the verification is not happening inside a room.
|
||||
*/
|
||||
internal fun roomId(): String? {
|
||||
return inner.roomId
|
||||
return innerVerificationRequest.roomId
|
||||
}
|
||||
|
||||
/** Did the non-initiating side respond with a m.key.verification.read event
|
||||
|
@ -109,13 +111,13 @@ internal class VerificationRequest(
|
|||
*/
|
||||
internal fun isReady(): Boolean {
|
||||
refreshData()
|
||||
return inner.isReady
|
||||
return innerVerificationRequest.isReady
|
||||
}
|
||||
|
||||
/** Did we advertise that we're able to scan QR codes */
|
||||
internal fun canScanQrCodes(): Boolean {
|
||||
refreshData()
|
||||
return inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false
|
||||
return innerVerificationRequest.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false
|
||||
}
|
||||
|
||||
/** Accept the verification request advertising the given methods as supported
|
||||
|
@ -134,14 +136,14 @@ internal class VerificationRequest(
|
|||
suspend fun acceptWithMethods(methods: List<VerificationMethod>) {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
|
||||
val request = machine.acceptVerificationRequest(
|
||||
inner.otherUserId,
|
||||
inner.flowId,
|
||||
val request = innerOlmMachine.acceptVerificationRequest(
|
||||
innerVerificationRequest.otherUserId,
|
||||
innerVerificationRequest.flowId,
|
||||
stringMethods
|
||||
)
|
||||
|
||||
if (request != null) {
|
||||
sender.sendVerificationRequest(request)
|
||||
requestSender.sendVerificationRequest(request)
|
||||
dispatchRequestUpdated()
|
||||
}
|
||||
}
|
||||
|
@ -161,11 +163,11 @@ internal class VerificationRequest(
|
|||
*/
|
||||
internal suspend fun startSasVerification(): SasVerification? {
|
||||
return withContext(coroutineDispatchers.io) {
|
||||
val result = machine.startSasVerification(inner.otherUserId, inner.flowId)
|
||||
val result = innerOlmMachine.startSasVerification(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId)
|
||||
|
||||
if (result != null) {
|
||||
sender.sendVerificationRequest(result.request)
|
||||
SasVerification(machine, result.sas, sender, coroutineDispatchers, listeners)
|
||||
requestSender.sendVerificationRequest(result.request)
|
||||
SasVerification(innerOlmMachine, result.sas, requestSender, coroutineDispatchers, listeners)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
@ -189,10 +191,10 @@ internal class VerificationRequest(
|
|||
// TODO again, what's the deal with ISO_8859_1?
|
||||
val byteArray = data.toByteArray(Charsets.ISO_8859_1)
|
||||
val encodedData = byteArray.toBase64NoPadding()
|
||||
val result = machine.scanQrCode(otherUser(), flowId(), encodedData) ?: return null
|
||||
val result = innerOlmMachine.scanQrCode(otherUser(), flowId(), encodedData) ?: return null
|
||||
|
||||
sender.sendVerificationRequest(result.request)
|
||||
return QrCodeVerification(machine, this, result.qr, sender, coroutineDispatchers, listeners)
|
||||
requestSender.sendVerificationRequest(result.request)
|
||||
return QrCodeVerification(innerOlmMachine, this, result.qr, requestSender, coroutineDispatchers, listeners)
|
||||
}
|
||||
|
||||
/** Transition into a QR code verification to display a QR code
|
||||
|
@ -213,14 +215,14 @@ internal class VerificationRequest(
|
|||
* QR code verification, or null if we can't yet transition into QR code verification.
|
||||
*/
|
||||
internal fun startQrVerification(): QrCodeVerification? {
|
||||
val qrcode = machine.startQrVerification(inner.otherUserId, inner.flowId)
|
||||
val qrcode = innerOlmMachine.startQrVerification(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId)
|
||||
|
||||
return if (qrcode != null) {
|
||||
QrCodeVerification(
|
||||
machine = machine,
|
||||
machine = innerOlmMachine,
|
||||
request = this,
|
||||
inner = qrcode,
|
||||
sender = sender,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = listeners,
|
||||
)
|
||||
|
@ -240,24 +242,24 @@ internal class VerificationRequest(
|
|||
* The method turns into a noop, if the verification flow has already been cancelled.
|
||||
*/
|
||||
internal suspend fun cancel() {
|
||||
val request = machine.cancelVerification(
|
||||
inner.otherUserId,
|
||||
inner.flowId,
|
||||
val request = innerOlmMachine.cancelVerification(
|
||||
innerVerificationRequest.otherUserId,
|
||||
innerVerificationRequest.flowId,
|
||||
CancelCode.User.value
|
||||
)
|
||||
|
||||
if (request != null) {
|
||||
sender.sendVerificationRequest(request)
|
||||
requestSender.sendVerificationRequest(request)
|
||||
dispatchRequestUpdated()
|
||||
}
|
||||
}
|
||||
|
||||
/** Fetch fresh data from the Rust side for our verification flow */
|
||||
private fun refreshData() {
|
||||
val request = machine.getVerificationRequest(inner.otherUserId, inner.flowId)
|
||||
val request = innerOlmMachine.getVerificationRequest(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId)
|
||||
|
||||
if (request != null) {
|
||||
inner = request
|
||||
innerVerificationRequest = request
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +274,7 @@ internal class VerificationRequest(
|
|||
*/
|
||||
internal fun toPendingVerificationRequest(): PendingVerificationRequest {
|
||||
refreshData()
|
||||
val cancelInfo = inner.cancelInfo
|
||||
val cancelInfo = innerVerificationRequest.cancelInfo
|
||||
val cancelCode =
|
||||
if (cancelInfo != null) {
|
||||
safeValueOf(cancelInfo.cancelCode)
|
||||
|
@ -280,60 +282,60 @@ internal class VerificationRequest(
|
|||
null
|
||||
}
|
||||
|
||||
val ourMethods = inner.ourMethods
|
||||
val theirMethods = inner.theirMethods
|
||||
val otherDeviceId = inner.otherDeviceId
|
||||
val ourMethods = innerVerificationRequest.ourMethods
|
||||
val theirMethods = innerVerificationRequest.theirMethods
|
||||
val otherDeviceId = innerVerificationRequest.otherDeviceId
|
||||
|
||||
var requestInfo: ValidVerificationInfoRequest? = null
|
||||
var readyInfo: ValidVerificationInfoReady? = null
|
||||
|
||||
if (inner.weStarted && ourMethods != null) {
|
||||
if (innerVerificationRequest.weStarted && ourMethods != null) {
|
||||
requestInfo =
|
||||
ValidVerificationInfoRequest(
|
||||
transactionId = inner.flowId,
|
||||
fromDevice = machine.deviceId(),
|
||||
transactionId = innerVerificationRequest.flowId,
|
||||
fromDevice = innerOlmMachine.deviceId(),
|
||||
methods = ourMethods,
|
||||
timestamp = null,
|
||||
)
|
||||
} else if (!inner.weStarted && ourMethods != null) {
|
||||
} else if (!innerVerificationRequest.weStarted && ourMethods != null) {
|
||||
readyInfo =
|
||||
ValidVerificationInfoReady(
|
||||
transactionId = inner.flowId,
|
||||
fromDevice = machine.deviceId(),
|
||||
transactionId = innerVerificationRequest.flowId,
|
||||
fromDevice = innerOlmMachine.deviceId(),
|
||||
methods = ourMethods,
|
||||
)
|
||||
}
|
||||
|
||||
if (inner.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
if (innerVerificationRequest.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
readyInfo =
|
||||
ValidVerificationInfoReady(
|
||||
transactionId = inner.flowId,
|
||||
transactionId = innerVerificationRequest.flowId,
|
||||
fromDevice = otherDeviceId,
|
||||
methods = theirMethods,
|
||||
)
|
||||
} else if (!inner.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
} else if (!innerVerificationRequest.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
requestInfo =
|
||||
ValidVerificationInfoRequest(
|
||||
transactionId = inner.flowId,
|
||||
transactionId = innerVerificationRequest.flowId,
|
||||
fromDevice = otherDeviceId,
|
||||
methods = theirMethods,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
timestamp = clock.epochMillis(),
|
||||
)
|
||||
}
|
||||
|
||||
return PendingVerificationRequest(
|
||||
// Creation time
|
||||
ageLocalTs = System.currentTimeMillis(),
|
||||
ageLocalTs = clock.epochMillis(),
|
||||
// Who initiated the request
|
||||
isIncoming = !inner.weStarted,
|
||||
isIncoming = !innerVerificationRequest.weStarted,
|
||||
// Local echo id, what to do here?
|
||||
localId = inner.flowId,
|
||||
localId = innerVerificationRequest.flowId,
|
||||
// other user
|
||||
otherUserId = inner.otherUserId,
|
||||
otherUserId = innerVerificationRequest.otherUserId,
|
||||
// room id
|
||||
roomId = inner.roomId,
|
||||
roomId = innerVerificationRequest.roomId,
|
||||
// transaction id
|
||||
transactionId = inner.flowId,
|
||||
transactionId = innerVerificationRequest.flowId,
|
||||
// val requestInfo: ValidVerificationInfoRequest? = null,
|
||||
requestInfo = requestInfo,
|
||||
// val readyInfo: ValidVerificationInfoReady? = null,
|
||||
|
@ -341,9 +343,9 @@ internal class VerificationRequest(
|
|||
// cancel code if there is one
|
||||
cancelConclusion = cancelCode,
|
||||
// are we done/successful
|
||||
isSuccessful = inner.isDone,
|
||||
isSuccessful = innerVerificationRequest.isDone,
|
||||
// did another device answer the request
|
||||
handledByOtherSession = inner.isPassive,
|
||||
handledByOtherSession = innerVerificationRequest.isPassive,
|
||||
// devices that should receive the events we send out
|
||||
targetDevices = null
|
||||
)
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto.verification
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import uniffi.olm.OlmMachine
|
||||
|
||||
internal class VerificationRequestFactory(
|
||||
private val innerOlmMachine: OlmMachine,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val listeners: ArrayList<VerificationService.Listener>,
|
||||
private val clock: Clock,
|
||||
) {
|
||||
|
||||
fun create(inner: uniffi.olm.VerificationRequest): VerificationRequest {
|
||||
return VerificationRequest(
|
||||
innerOlmMachine = innerOlmMachine,
|
||||
innerVerificationRequest = inner,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = listeners,
|
||||
clock = clock
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
package org.matrix.android.sdk.internal.crypto.verification.qrcode
|
||||
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
|
@ -26,6 +26,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf
|
|||
import org.matrix.android.sdk.api.util.fromBase64
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.OlmMachine
|
||||
import uniffi.olm.QrCode
|
||||
|
@ -213,6 +214,12 @@ internal class QrCodeVerification(
|
|||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "QrCodeVerification(qrCodeText=$qrCodeText, state=$state, transactionId='$transactionId', otherUserId='$otherUserId', otherDeviceId=$otherDeviceId, isIncoming=$isIncoming)"
|
||||
return "QrCodeVerification(" +
|
||||
"qrCodeText=$qrCodeText, " +
|
||||
"state=$state, " +
|
||||
"transactionId='$transactionId', " +
|
||||
"otherUserId='$otherUserId', " +
|
||||
"otherDeviceId=$otherDeviceId, " +
|
||||
"isIncoming=$isIncoming)"
|
||||
}
|
||||
}
|
|
@ -19,10 +19,6 @@ package org.matrix.android.sdk.internal.session
|
|||
import org.matrix.android.sdk.api.session.ToDeviceService
|
||||
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
|
||||
import org.matrix.android.sdk.api.session.events.model.Content
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.internal.crypto.EncryptEventContentUseCase
|
||||
import org.matrix.android.sdk.internal.crypto.OlmMachineProvider
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -52,7 +48,7 @@ internal class DefaultToDeviceService @Inject constructor(
|
|||
}
|
||||
|
||||
override suspend fun sendEncryptedToDevice(eventType: String, targets: Map<String, List<String>>, content: Content, txnId: String?) {
|
||||
//TODO: add to rust-ffi
|
||||
// TODO: add to rust-ffi
|
||||
/*
|
||||
val payloadJson = mapOf(
|
||||
"type" to eventType,
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.matrix.android.sdk.api.util.Optional
|
|||
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||
import org.matrix.android.sdk.internal.session.space.DefaultSpace
|
||||
import java.security.InvalidParameterException
|
||||
|
||||
internal class DefaultRoom(
|
||||
override val roomId: String,
|
||||
|
@ -81,7 +80,6 @@ internal class DefaultRoom(
|
|||
return roomSummaryDataSource.getRoomSummary(roomId)
|
||||
}
|
||||
|
||||
|
||||
override fun asSpace(): Space? {
|
||||
if (roomSummary()?.roomType != RoomType.SPACE) return null
|
||||
return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder)
|
||||
|
|
|
@ -21,7 +21,6 @@ import io.realm.kotlin.createObject
|
|||
import kotlinx.coroutines.runBlocking
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.matrix.android.sdk.api.session.Session
|
|||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrust
|
||||
|
||||
class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState,
|
||||
session: Session
|
||||
|
|
|
@ -66,6 +66,7 @@ class KeyRequestHandler @Inject constructor(
|
|||
var session: Session? = null
|
||||
|
||||
var scope: CoroutineScope? = null
|
||||
|
||||
// This functionality is disabled in element for now. As it could be prone to social attacks
|
||||
var enablePromptingForRequest = false
|
||||
|
||||
|
|
|
@ -44,12 +44,10 @@ import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
|||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult
|
||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
||||
import org.matrix.android.sdk.api.util.awaitCallback
|
||||
import org.matrix.android.sdk.api.util.fromBase64
|
||||
import java.io.OutputStream
|
||||
import kotlin.coroutines.Continuation
|
||||
|
|
|
@ -462,7 +462,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
tx.performAccept()
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
// Use this one!
|
||||
setState {
|
||||
copy(
|
||||
|
|
|
@ -42,15 +42,12 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
|||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
|
||||
import org.matrix.android.sdk.api.session.getUser
|
||||
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
||||
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.api.settings.LightweightSettingsStorage
|
||||
import org.matrix.android.sdk.api.util.awaitCallback
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import timber.log.Timber
|
||||
|
|
|
@ -250,7 +250,7 @@ class MessageActionsViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List<EventSharedAction> {
|
||||
private suspend fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List<EventSharedAction> {
|
||||
val messageContent = timelineEvent.getLastMessageContent()
|
||||
val msgType = messageContent?.msgType
|
||||
|
||||
|
|
Loading…
Reference in New Issue