mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-26 15:18:19 +08:00
Continue cleaning mostly on coroutine
This commit is contained in:
parent
ba540eb861
commit
9cb43ce4c8
@ -16,7 +16,6 @@
|
||||
|
||||
package org.matrix.android.sdk.api.session.crypto.crosssigning
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
@ -62,8 +61,8 @@ interface CrossSigningService {
|
||||
* by the server and if they do so
|
||||
*/
|
||||
suspend fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?,
|
||||
uskKeyPrivateKey: String?,
|
||||
sskPrivateKey: String?): UserTrustResult
|
||||
uskKeyPrivateKey: String?,
|
||||
sskPrivateKey: String?): UserTrustResult
|
||||
|
||||
/**
|
||||
* Get the public cross signing keys for the given user
|
||||
@ -94,7 +93,7 @@ interface CrossSigningService {
|
||||
|
||||
/** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */
|
||||
suspend fun trustUser(otherUserId: String,
|
||||
callback: MatrixCallback<Unit>)
|
||||
callback: MatrixCallback<Unit>)
|
||||
|
||||
/** Mark our own master key as trusted */
|
||||
suspend fun markMyMasterKeyAsTrusted()
|
||||
@ -115,9 +114,9 @@ interface CrossSigningService {
|
||||
* key of another user.
|
||||
*/
|
||||
suspend fun checkDeviceTrust(otherUserId: String,
|
||||
otherDeviceId: String,
|
||||
// TODO what is locallyTrusted used for?
|
||||
locallyTrusted: Boolean?): DeviceTrustResult
|
||||
otherDeviceId: String,
|
||||
// TODO what is locallyTrusted used for?
|
||||
locallyTrusted: Boolean?): DeviceTrustResult
|
||||
|
||||
// FIXME Those method do not have to be in the service
|
||||
// TODO those three methods doesn't seem to be used anywhere?
|
||||
|
@ -988,18 +988,17 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
val cancellation = requestPair.cancellation
|
||||
val request = requestPair.keyRequest
|
||||
|
||||
if (cancellation != null) {
|
||||
when (cancellation) {
|
||||
is Request.ToDevice -> {
|
||||
sendToDevice(cancellation)
|
||||
}
|
||||
when (cancellation) {
|
||||
is Request.ToDevice -> {
|
||||
sendToDevice(cancellation)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
|
||||
when (request) {
|
||||
is Request.ToDevice -> {
|
||||
sendToDevice(request)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1100,7 +1099,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
}
|
||||
try {
|
||||
preshareRoomKey(roomId, userIds)
|
||||
}catch (failure: Throwable){
|
||||
} catch (failure: Throwable) {
|
||||
Timber.tag(loggerTag.value).e("prepareToEncrypt() : Failed to PreshareRoomKey")
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
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.crosssigning.DeviceTrustLevel
|
||||
@ -39,16 +39,17 @@ internal class Device(
|
||||
private val machine: OlmMachine,
|
||||
private var inner: InnerDevice,
|
||||
private val sender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val listeners: ArrayList<VerificationService.Listener>
|
||||
) {
|
||||
@Throws(CryptoStoreException::class)
|
||||
private suspend fun refreshData() {
|
||||
val device = withContext(Dispatchers.IO) {
|
||||
val device = withContext(coroutineDispatchers.io) {
|
||||
machine.getDevice(inner.userId, inner.deviceId)
|
||||
}
|
||||
|
||||
if (device != null) {
|
||||
this.inner = device
|
||||
inner = device
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,12 +67,12 @@ internal class Device(
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun requestVerification(methods: List<VerificationMethod>): VerificationRequest? {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
val result = withContext(coroutineDispatchers.io) {
|
||||
machine.requestVerificationWithDevice(inner.userId, inner.deviceId, stringMethods)
|
||||
}
|
||||
|
||||
return if (result != null) {
|
||||
this.sender.sendVerificationRequest(result.request)
|
||||
sender.sendVerificationRequest(result.request)
|
||||
result.verification
|
||||
} else {
|
||||
null
|
||||
@ -89,14 +90,18 @@ internal class Device(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun startVerification(): SasVerification? {
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
val result = withContext(coroutineDispatchers.io) {
|
||||
machine.startSasWithDevice(inner.userId, inner.deviceId)
|
||||
}
|
||||
|
||||
return if (result != null) {
|
||||
this.sender.sendVerificationRequest(result.request)
|
||||
sender.sendVerificationRequest(result.request)
|
||||
SasVerification(
|
||||
this.machine, result.sas, this.sender, this.listeners,
|
||||
machine = machine,
|
||||
inner = result.sas,
|
||||
sender = sender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = listeners
|
||||
)
|
||||
} else {
|
||||
null
|
||||
@ -111,7 +116,7 @@ internal class Device(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun markAsTrusted() {
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(coroutineDispatchers.io) {
|
||||
machine.markDeviceAsTrusted(inner.userId, inner.deviceId)
|
||||
}
|
||||
}
|
||||
@ -127,11 +132,11 @@ internal class Device(
|
||||
*/
|
||||
@Throws(SignatureException::class)
|
||||
suspend fun verify(): Boolean {
|
||||
val request = withContext(Dispatchers.IO) {
|
||||
val request = withContext(coroutineDispatchers.io) {
|
||||
machine.verifyDevice(inner.userId, inner.deviceId)
|
||||
}
|
||||
|
||||
this.sender.sendSignatureUpload(request)
|
||||
sender.sendSignatureUpload(request)
|
||||
|
||||
return true
|
||||
}
|
||||
@ -151,20 +156,20 @@ internal class Device(
|
||||
* This will not fetch out fresh data from the Rust side.
|
||||
**/
|
||||
internal fun toCryptoDeviceInfo(): CryptoDeviceInfo {
|
||||
val keys = this.inner.keys.map { (keyId, key) -> "$keyId:$this.inner.deviceId" to key }.toMap()
|
||||
val keys = inner.keys.map { (keyId, key) -> "$keyId:$inner.deviceId" to key }.toMap()
|
||||
|
||||
return CryptoDeviceInfo(
|
||||
this.inner.deviceId,
|
||||
this.inner.userId,
|
||||
this.inner.algorithms,
|
||||
keys,
|
||||
deviceId = inner.deviceId,
|
||||
userId = inner.userId,
|
||||
algorithms = inner.algorithms,
|
||||
keys = keys,
|
||||
// The Kotlin side doesn't need to care about signatures,
|
||||
// so we're not filling this out
|
||||
mapOf(),
|
||||
UnsignedDeviceInfo(this.inner.displayName),
|
||||
DeviceTrustLevel(crossSigningVerified = this.inner.crossSigningTrusted, locallyVerified = this.inner.locallyTrusted),
|
||||
this.inner.isBlocked,
|
||||
signatures = mapOf(),
|
||||
unsigned = UnsignedDeviceInfo(inner.displayName),
|
||||
trustLevel = DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted),
|
||||
isBlocked = inner.isBlocked,
|
||||
// TODO
|
||||
null)
|
||||
firstTimeSeenLocalTs = null)
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -102,7 +103,8 @@ internal class OlmMachine(
|
||||
device_id: String,
|
||||
path: File,
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val moshi: Moshi
|
||||
) {
|
||||
private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString())
|
||||
internal val verificationListeners = ArrayList<VerificationService.Listener>()
|
||||
@ -110,21 +112,21 @@ internal class OlmMachine(
|
||||
|
||||
/** Get our own user ID. */
|
||||
fun userId(): String {
|
||||
return this.inner.userId()
|
||||
return inner.userId()
|
||||
}
|
||||
|
||||
/** Get our own device ID. */
|
||||
fun deviceId(): String {
|
||||
return this.inner.deviceId()
|
||||
return inner.deviceId()
|
||||
}
|
||||
|
||||
/** Get our own public identity keys ID. */
|
||||
fun identityKeys(): Map<String, String> {
|
||||
return this.inner.identityKeys()
|
||||
return inner.identityKeys()
|
||||
}
|
||||
|
||||
fun inner(): InnerMachine {
|
||||
return this.inner
|
||||
return inner
|
||||
}
|
||||
|
||||
private suspend fun updateLiveDevices() {
|
||||
@ -142,7 +144,7 @@ internal class OlmMachine(
|
||||
}
|
||||
|
||||
private suspend fun updateLivePrivateKeys() {
|
||||
val keys = this.exportCrossSigningKeys().toOptional()
|
||||
val keys = exportCrossSigningKeys().toOptional()
|
||||
for (privateKeyCollector in flowCollectors.privateKeyCollectors) {
|
||||
privateKeyCollector.send(keys)
|
||||
}
|
||||
@ -152,18 +154,18 @@ internal class OlmMachine(
|
||||
* Get our own device info as [CryptoDeviceInfo].
|
||||
*/
|
||||
suspend fun ownDevice(): CryptoDeviceInfo {
|
||||
val deviceId = this.deviceId()
|
||||
val deviceId = deviceId()
|
||||
|
||||
val keys = this.identityKeys().map { (keyId, key) -> "$keyId:$deviceId" to key }.toMap()
|
||||
val keys = identityKeys().map { (keyId, key) -> "$keyId:$deviceId" to key }.toMap()
|
||||
|
||||
val crossSigningVerified = when (val ownIdentity = this.getIdentity(this.userId())) {
|
||||
val crossSigningVerified = when (val ownIdentity = getIdentity(userId())) {
|
||||
is OwnUserIdentity -> ownIdentity.trustsOurOwnDevice()
|
||||
else -> false
|
||||
}
|
||||
|
||||
return CryptoDeviceInfo(
|
||||
this.deviceId(),
|
||||
this.userId(),
|
||||
deviceId(),
|
||||
userId(),
|
||||
// TODO pass the algorithms here.
|
||||
listOf(),
|
||||
keys,
|
||||
@ -238,7 +240,7 @@ internal class OlmMachine(
|
||||
val devices =
|
||||
DeviceLists(deviceChanges?.changed.orEmpty(), deviceChanges?.left.orEmpty())
|
||||
val adapter =
|
||||
MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java)
|
||||
moshi.adapter(ToDeviceSyncResponse::class.java)
|
||||
val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!!
|
||||
|
||||
// TODO once our sync response type parses the unused fallback key
|
||||
@ -247,7 +249,7 @@ internal class OlmMachine(
|
||||
}
|
||||
|
||||
// We may get cross signing keys over a to-device event, update our listeners.
|
||||
this.updateLivePrivateKeys()
|
||||
updateLivePrivateKeys()
|
||||
|
||||
return response
|
||||
}
|
||||
@ -270,7 +272,7 @@ internal class OlmMachine(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
fun isUserTracked(userId: String): Boolean {
|
||||
return this.inner.isUserTracked(userId)
|
||||
return inner.isUserTracked(userId)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -344,7 +346,7 @@ internal class OlmMachine(
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun encrypt(roomId: String, eventType: String, content: Content): Content =
|
||||
withContext(coroutineDispatchers.io) {
|
||||
val adapter = MoshiProvider.providesMoshi().adapter<Content>(Map::class.java)
|
||||
val adapter = moshi.adapter<Content>(Map::class.java)
|
||||
val contentString = adapter.toJson(content)
|
||||
val encrypted = inner.encrypt(roomId, eventType, contentString)
|
||||
adapter.fromJson(encrypted)!!
|
||||
@ -362,7 +364,7 @@ internal class OlmMachine(
|
||||
@Throws(MXCryptoError::class)
|
||||
suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult =
|
||||
withContext(coroutineDispatchers.io) {
|
||||
val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java)
|
||||
val adapter = moshi.adapter(Event::class.java)
|
||||
try {
|
||||
if (event.roomId.isNullOrBlank()) {
|
||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
||||
@ -371,7 +373,7 @@ internal class OlmMachine(
|
||||
val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId)
|
||||
|
||||
val deserializationAdapter =
|
||||
MoshiProvider.providesMoshi().adapter<JsonDict>(Map::class.java)
|
||||
moshi.adapter<JsonDict>(Map::class.java)
|
||||
val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent)
|
||||
?: throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
||||
|
||||
@ -402,7 +404,7 @@ internal class OlmMachine(
|
||||
@Throws(DecryptionException::class)
|
||||
suspend fun requestRoomKey(event: Event): KeyRequestPair =
|
||||
withContext(coroutineDispatchers.io) {
|
||||
val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java)
|
||||
val adapter = moshi.adapter(Event::class.java)
|
||||
val serializedEvent = adapter.toJson(event)
|
||||
|
||||
inner.requestRoomKey(serializedEvent, event.roomId!!)
|
||||
@ -453,7 +455,7 @@ internal class OlmMachine(
|
||||
listener: ProgressListener?
|
||||
): ImportRoomKeysResult =
|
||||
withContext(coroutineDispatchers.io) {
|
||||
val adapter = MoshiProvider.providesMoshi().adapter(List::class.java)
|
||||
val adapter = moshi.adapter(List::class.java)
|
||||
|
||||
// If the key backup is too big we take the risk of causing OOM
|
||||
// when serializing to json
|
||||
@ -485,22 +487,28 @@ internal class OlmMachine(
|
||||
val identity = withContext(coroutineDispatchers.io) {
|
||||
inner.getIdentity(userId)
|
||||
}
|
||||
val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java)
|
||||
val adapter = moshi.adapter(RestKeyInfo::class.java)
|
||||
|
||||
return when (identity) {
|
||||
is RustUserIdentity.Other -> {
|
||||
val verified = this.inner().isIdentityVerified(userId)
|
||||
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(identity.userId, masterKey, selfSigningKey, this, this.requestSender)
|
||||
UserIdentity(
|
||||
userId = identity.userId,
|
||||
masterKey = masterKey,
|
||||
selfSigningKey = selfSigningKey,
|
||||
olmMachine = this,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers
|
||||
)
|
||||
}
|
||||
is RustUserIdentity.Own -> {
|
||||
val verified = this.inner().isIdentityVerified(userId)
|
||||
val verified = inner().isIdentityVerified(userId)
|
||||
|
||||
val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply {
|
||||
trustLevel = DeviceTrustLevel(verified, verified)
|
||||
@ -511,13 +519,14 @@ internal class OlmMachine(
|
||||
val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel()
|
||||
|
||||
OwnUserIdentity(
|
||||
identity.userId,
|
||||
masterKey,
|
||||
selfSigningKey,
|
||||
userSigningKey,
|
||||
identity.trustsOurOwnDevice,
|
||||
this,
|
||||
this.requestSender
|
||||
userId = identity.userId,
|
||||
masterKey = masterKey,
|
||||
selfSigningKey = selfSigningKey,
|
||||
userSigningKey = userSigningKey,
|
||||
trustsOurOwnDevice = identity.trustsOurOwnDevice,
|
||||
olmMachine = this,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers
|
||||
)
|
||||
}
|
||||
null -> null
|
||||
@ -552,12 +561,26 @@ internal class OlmMachine(
|
||||
inner.getDevice(userId, deviceId)
|
||||
} ?: return null
|
||||
|
||||
return Device(this.inner, device, this.requestSender, this.verificationListeners)
|
||||
return Device(
|
||||
machine = inner,
|
||||
inner = device,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getUserDevices(userId: String): List<Device> {
|
||||
return withContext(coroutineDispatchers.io) {
|
||||
inner.getUserDevices(userId).map { Device(inner, it, requestSender, verificationListeners) }
|
||||
inner.getUserDevices(userId).map {
|
||||
Device(
|
||||
machine = inner,
|
||||
inner = it,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,12 +593,12 @@ internal class OlmMachine(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> {
|
||||
val devices = this.getUserDevices(userId).map { it.toCryptoDeviceInfo() }.toMutableList()
|
||||
val devices = getUserDevices(userId).map { it.toCryptoDeviceInfo() }.toMutableList()
|
||||
|
||||
// EA doesn't differentiate much between our own and other devices of
|
||||
// while the rust-sdk does, append our own device here.
|
||||
if (userId == this.userId()) {
|
||||
devices.add(this.ownDevice())
|
||||
if (userId == userId()) {
|
||||
devices.add(ownDevice())
|
||||
}
|
||||
|
||||
return devices
|
||||
@ -592,7 +615,7 @@ internal class OlmMachine(
|
||||
val plainDevices: ArrayList<CryptoDeviceInfo> = arrayListOf()
|
||||
|
||||
for (user in userIds) {
|
||||
val devices = this.getCryptoDeviceInfo(user)
|
||||
val devices = getCryptoDeviceInfo(user)
|
||||
plainDevices.addAll(devices)
|
||||
}
|
||||
|
||||
@ -612,7 +635,7 @@ internal class OlmMachine(
|
||||
val userMap = MXUsersDevicesMap<CryptoDeviceInfo>()
|
||||
|
||||
for (user in userIds) {
|
||||
val devices = this.getCryptoDeviceInfo(user)
|
||||
val devices = getCryptoDeviceInfo(user)
|
||||
|
||||
for (device in devices) {
|
||||
userMap.setObject(user, device.deviceId, device)
|
||||
@ -703,26 +726,27 @@ internal class OlmMachine(
|
||||
* @return The list of [VerificationRequest] that we share with the given user
|
||||
*/
|
||||
fun getVerificationRequests(userId: String): List<VerificationRequest> {
|
||||
return this.inner.getVerificationRequests(userId).map {
|
||||
return inner.getVerificationRequests(userId).map {
|
||||
VerificationRequest(
|
||||
this.inner,
|
||||
it,
|
||||
this.requestSender,
|
||||
this.verificationListeners,
|
||||
machine = inner,
|
||||
inner = it,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Get a verification request for the given user with the given flow ID */
|
||||
fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? {
|
||||
val request = this.inner.getVerificationRequest(userId, flowId)
|
||||
|
||||
val request = inner.getVerificationRequest(userId, flowId)
|
||||
return if (request != null) {
|
||||
VerificationRequest(
|
||||
this.inner,
|
||||
request,
|
||||
requestSender,
|
||||
this.verificationListeners,
|
||||
machine = inner,
|
||||
inner = request,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
@ -735,13 +759,26 @@ internal class OlmMachine(
|
||||
* verification.
|
||||
*/
|
||||
fun getVerification(userId: String, flowId: String): VerificationTransaction? {
|
||||
return when (val verification = this.inner.getVerification(userId, flowId)) {
|
||||
return when (val verification = inner.getVerification(userId, flowId)) {
|
||||
is uniffi.olm.Verification.QrCodeV1 -> {
|
||||
val request = this.getVerificationRequest(userId, flowId) ?: return null
|
||||
QrCodeVerification(inner, request, verification.qrcode, requestSender, verificationListeners)
|
||||
val request = getVerificationRequest(userId, flowId) ?: return null
|
||||
QrCodeVerification(
|
||||
machine = inner,
|
||||
request = request,
|
||||
inner = verification.qrcode,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners
|
||||
)
|
||||
}
|
||||
is uniffi.olm.Verification.SasV1 -> {
|
||||
SasVerification(inner, verification.sas, requestSender, verificationListeners)
|
||||
SasVerification(
|
||||
machine = inner,
|
||||
inner = verification.sas,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners
|
||||
)
|
||||
}
|
||||
null -> {
|
||||
// This branch exists because scanning a QR code is tied to the QrCodeVerification,
|
||||
@ -751,7 +788,14 @@ internal class OlmMachine(
|
||||
val request = getVerificationRequest(userId, flowId) ?: return null
|
||||
|
||||
if (request.canScanQrCodes()) {
|
||||
QrCodeVerification(inner, request, null, requestSender, verificationListeners)
|
||||
QrCodeVerification(
|
||||
machine = inner,
|
||||
request = request,
|
||||
inner = null,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = verificationListeners
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@ -763,16 +807,15 @@ internal class OlmMachine(
|
||||
val requests = withContext(coroutineDispatchers.io) {
|
||||
inner.bootstrapCrossSigning()
|
||||
}
|
||||
|
||||
this.requestSender.uploadCrossSigningKeys(requests.uploadSigningKeysRequest, uiaInterceptor)
|
||||
this.requestSender.sendSignatureUpload(requests.signatureRequest)
|
||||
requestSender.uploadCrossSigningKeys(requests.uploadSigningKeysRequest, uiaInterceptor)
|
||||
requestSender.sendSignatureUpload(requests.signatureRequest)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of our private cross signing keys, i.e. which private keys do we have stored locally.
|
||||
*/
|
||||
fun crossSigningStatus(): CrossSigningStatus {
|
||||
return this.inner.crossSigningStatus()
|
||||
return inner.crossSigningStatus()
|
||||
}
|
||||
|
||||
suspend fun exportCrossSigningKeys(): PrivateKeysInfo? {
|
||||
@ -867,8 +910,7 @@ internal class OlmMachine(
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun checkAuthDataSignature(authData: MegolmBackupAuthData): Boolean {
|
||||
return withContext(coroutineDispatchers.computation) {
|
||||
val adapter = MoshiProvider
|
||||
.providesMoshi()
|
||||
val adapter = moshi
|
||||
.newBuilder()
|
||||
.add(CheckNumberType.JSON_ADAPTER_FACTORY)
|
||||
.build()
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.internal.di.DeviceId
|
||||
import org.matrix.android.sdk.internal.di.SessionFilesDirectory
|
||||
@ -30,8 +31,15 @@ internal class OlmMachineProvider @Inject constructor(
|
||||
@DeviceId private val deviceId: String?,
|
||||
@SessionFilesDirectory private val dataDir: File,
|
||||
requestSender: RequestSender,
|
||||
coroutineDispatchers: MatrixCoroutineDispatchers
|
||||
coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
moshi: Moshi
|
||||
) {
|
||||
|
||||
var olmMachine: OlmMachine = OlmMachine(userId, deviceId!!, dataDir, requestSender, coroutineDispatchers)
|
||||
var olmMachine: OlmMachine = OlmMachine(
|
||||
user_id = userId,
|
||||
device_id = deviceId!!,
|
||||
path = dataDir,
|
||||
requestSender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
moshi = moshi)
|
||||
}
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
@ -36,13 +36,15 @@ internal class QrCodeVerification(
|
||||
private var request: VerificationRequest,
|
||||
private var inner: QrCode?,
|
||||
private val sender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
listeners: ArrayList<VerificationService.Listener>
|
||||
) : QrCodeVerificationTransaction {
|
||||
|
||||
private val dispatcher = UpdateDispatcher(listeners)
|
||||
|
||||
private fun dispatchTxUpdated() {
|
||||
refreshData()
|
||||
this.dispatcher.dispatchTxUpdated(this)
|
||||
dispatcher.dispatchTxUpdated(this)
|
||||
}
|
||||
|
||||
/** Generate, if possible, data that should be encoded as a QR code for QR code verification.
|
||||
@ -59,7 +61,7 @@ internal class QrCodeVerification(
|
||||
*/
|
||||
override val qrCodeText: String?
|
||||
get() {
|
||||
val data = this.inner?.let { this.machine.generateQrCode(it.otherUserId, it.flowId) }
|
||||
val data = inner?.let { machine.generateQrCode(it.otherUserId, it.flowId) }
|
||||
|
||||
// TODO Why are we encoding this to ISO_8859_1? If we're going to encode, why not base64?
|
||||
return data?.fromBase64()?.toString(Charsets.ISO_8859_1)
|
||||
@ -85,7 +87,7 @@ internal class QrCodeVerification(
|
||||
override var state: VerificationTxState
|
||||
get() {
|
||||
refreshData()
|
||||
val inner = this.inner
|
||||
val inner = inner
|
||||
val cancelInfo = inner?.cancelInfo
|
||||
|
||||
return if (inner != null) {
|
||||
@ -111,22 +113,22 @@ internal class QrCodeVerification(
|
||||
|
||||
/** Get the unique id of this verification */
|
||||
override val transactionId: String
|
||||
get() = this.request.flowId()
|
||||
get() = request.flowId()
|
||||
|
||||
/** Get the user id of the other user participating in this verification flow */
|
||||
override val otherUserId: String
|
||||
get() = this.request.otherUser()
|
||||
get() = request.otherUser()
|
||||
|
||||
/** Get the device id of the other user's device participating in this verification flow */
|
||||
override var otherDeviceId: String?
|
||||
get() = this.request.otherDeviceId()
|
||||
get() = request.otherDeviceId()
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
set(value) {
|
||||
}
|
||||
|
||||
/** Did the other side initiate this verification flow */
|
||||
override val isIncoming: Boolean
|
||||
get() = !this.request.weStarted()
|
||||
get() = !request.weStarted()
|
||||
|
||||
/** Cancel the verification flow
|
||||
*
|
||||
@ -158,7 +160,7 @@ internal class QrCodeVerification(
|
||||
|
||||
/** Is this verification happening over to-device messages */
|
||||
override fun isToDeviceTransport(): Boolean {
|
||||
return this.request.roomId() == null
|
||||
return request.roomId() == null
|
||||
}
|
||||
|
||||
/** Confirm the QR code verification
|
||||
@ -171,24 +173,24 @@ internal class QrCodeVerification(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
private suspend fun confirm() {
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
val result = withContext(coroutineDispatchers.io) {
|
||||
machine.confirmVerification(request.otherUser(), request.flowId())
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
this.sender.sendVerificationRequest(result.request)
|
||||
sender.sendVerificationRequest(result.request)
|
||||
dispatchTxUpdated()
|
||||
|
||||
val signatureRequest = result.signatureRequest
|
||||
|
||||
if (signatureRequest != null) {
|
||||
this.sender.sendSignatureUpload(signatureRequest)
|
||||
sender.sendSignatureUpload(signatureRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun cancelHelper(code: CancelCode) {
|
||||
val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value)
|
||||
val request = machine.cancelVerification(request.otherUser(), request.flowId(), code.value)
|
||||
|
||||
if (request != null) {
|
||||
sender.sendVerificationRequest(request)
|
||||
@ -198,9 +200,9 @@ internal class QrCodeVerification(
|
||||
|
||||
/** Fetch fresh data from the Rust side for our verification flow */
|
||||
private fun refreshData() {
|
||||
when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) {
|
||||
when (val verification = machine.getVerification(request.otherUser(), request.flowId())) {
|
||||
is Verification.QrCodeV1 -> {
|
||||
this.inner = verification.qrcode
|
||||
inner = verification.qrcode
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||
@ -31,7 +30,6 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified
|
||||
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.extensions.foldToCallback
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RustCrossSigningService @Inject constructor(
|
||||
@ -54,7 +52,7 @@ internal class RustCrossSigningService @Inject constructor(
|
||||
|
||||
override suspend fun isUserTrusted(otherUserId: String): Boolean {
|
||||
// This seems to be used only in tests.
|
||||
return this.checkUserTrust(otherUserId).isVerified()
|
||||
return checkUserTrust(otherUserId).isVerified()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,13 +134,13 @@ internal class RustCrossSigningService @Inject constructor(
|
||||
* Returning true means that we have the private self-signing and user-signing keys at hand.
|
||||
*/
|
||||
override fun canCrossSign(): Boolean {
|
||||
val status = this.olmMachine.crossSigningStatus()
|
||||
val status = olmMachine.crossSigningStatus()
|
||||
|
||||
return status.hasSelfSigning && status.hasUserSigning
|
||||
}
|
||||
|
||||
override fun allPrivateKeysKnown(): Boolean {
|
||||
val status = this.olmMachine.crossSigningStatus()
|
||||
val status = olmMachine.crossSigningStatus()
|
||||
|
||||
return status.hasMaster && status.hasSelfSigning && status.hasUserSigning
|
||||
}
|
||||
@ -163,7 +161,7 @@ internal class RustCrossSigningService @Inject constructor(
|
||||
/** Mark our own master key as trusted */
|
||||
override suspend fun markMyMasterKeyAsTrusted() {
|
||||
// This doesn't seem to be used?
|
||||
this.trustUser(this.olmMachine.userId(), NoOpMatrixCallback())
|
||||
trustUser(olmMachine.userId(), NoOpMatrixCallback())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,7 +211,7 @@ internal class RustCrossSigningService @Inject constructor(
|
||||
}
|
||||
|
||||
override fun onSecretUSKGossip(uskPrivateKey: String) {
|
||||
// And this.
|
||||
// And
|
||||
}
|
||||
|
||||
override suspend fun shieldForGroup(userIds: List<String>): RoomEncryptionTrustLevel {
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
||||
@ -36,6 +36,7 @@ internal class SasVerification(
|
||||
private val machine: OlmMachine,
|
||||
private var inner: Sas,
|
||||
private val sender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
listeners: ArrayList<VerificationService.Listener>
|
||||
) :
|
||||
SasVerificationTransaction {
|
||||
@ -43,27 +44,27 @@ internal class SasVerification(
|
||||
|
||||
private fun dispatchTxUpdated() {
|
||||
refreshData()
|
||||
this.dispatcher.dispatchTxUpdated(this)
|
||||
dispatcher.dispatchTxUpdated(this)
|
||||
}
|
||||
|
||||
/** The user ID of the other user that is participating in this verification flow */
|
||||
override val otherUserId: String = this.inner.otherUserId
|
||||
override val otherUserId: String = inner.otherUserId
|
||||
|
||||
/** Get the device id of the other user's device participating in this verification flow */
|
||||
override var otherDeviceId: String?
|
||||
get() = this.inner.otherDeviceId
|
||||
get() = inner.otherDeviceId
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
set(value) {
|
||||
}
|
||||
|
||||
/** Did the other side initiate this verification flow */
|
||||
override val isIncoming: Boolean
|
||||
get() = !this.inner.weStarted
|
||||
get() = !inner.weStarted
|
||||
|
||||
override var state: VerificationTxState
|
||||
get() {
|
||||
refreshData()
|
||||
val cancelInfo = this.inner.cancelInfo
|
||||
val cancelInfo = inner.cancelInfo
|
||||
|
||||
return when {
|
||||
cancelInfo != null -> {
|
||||
@ -83,7 +84,7 @@ internal class SasVerification(
|
||||
|
||||
/** Get the unique id of this verification */
|
||||
override val transactionId: String
|
||||
get() = this.inner.flowId
|
||||
get() = inner.flowId
|
||||
|
||||
/** Cancel the verification flow
|
||||
*
|
||||
@ -95,7 +96,7 @@ internal class SasVerification(
|
||||
* The method turns into a noop, if the verification flow has already been cancelled.
|
||||
* */
|
||||
override suspend fun cancel() {
|
||||
this.cancelHelper(CancelCode.User)
|
||||
cancelHelper(CancelCode.User)
|
||||
}
|
||||
|
||||
/** Cancel the verification flow
|
||||
@ -110,7 +111,7 @@ internal class SasVerification(
|
||||
* @param code The cancel code that should be given as the reason for the cancellation.
|
||||
* */
|
||||
override suspend fun cancel(code: CancelCode) {
|
||||
this.cancelHelper(code)
|
||||
cancelHelper(code)
|
||||
}
|
||||
|
||||
/** Cancel the verification flow
|
||||
@ -123,11 +124,11 @@ internal class SasVerification(
|
||||
* The method turns into a noop, if the verification flow has already been cancelled.
|
||||
*/
|
||||
override suspend fun shortCodeDoesNotMatch() {
|
||||
this.cancelHelper(CancelCode.MismatchedSas)
|
||||
cancelHelper(CancelCode.MismatchedSas)
|
||||
}
|
||||
|
||||
/** Is this verification happening over to-device messages */
|
||||
override fun isToDeviceTransport(): Boolean = this.inner.roomId == null
|
||||
override fun isToDeviceTransport(): Boolean = inner.roomId == null
|
||||
|
||||
/** Does the verification flow support showing decimals as the short auth string */
|
||||
override fun supportsDecimal(): Boolean {
|
||||
@ -140,7 +141,7 @@ internal class SasVerification(
|
||||
/** Does the verification flow support showing emojis as the short auth string */
|
||||
override fun supportsEmoji(): Boolean {
|
||||
refreshData()
|
||||
return this.inner.supportsEmoji
|
||||
return inner.supportsEmoji
|
||||
}
|
||||
|
||||
/** Confirm that the short authentication code matches on both sides
|
||||
@ -175,7 +176,7 @@ internal class SasVerification(
|
||||
* in a presentable state.
|
||||
*/
|
||||
override fun getDecimalCodeRepresentation(): String {
|
||||
val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId)
|
||||
val decimals = machine.getDecimals(inner.otherUserId, inner.flowId)
|
||||
|
||||
return decimals?.joinToString(" ") ?: ""
|
||||
}
|
||||
@ -187,40 +188,40 @@ internal class SasVerification(
|
||||
* state.
|
||||
*/
|
||||
override fun getEmojiCodeRepresentation(): List<EmojiRepresentation> {
|
||||
val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId)
|
||||
val emojiIndex = machine.getEmojiIndex(inner.otherUserId, inner.flowId)
|
||||
|
||||
return emojiIndex?.map { getEmojiForCode(it) } ?: listOf()
|
||||
}
|
||||
|
||||
internal suspend fun accept() {
|
||||
val request = this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId)
|
||||
val request = machine.acceptSasVerification(inner.otherUserId, inner.flowId)
|
||||
|
||||
if (request != null) {
|
||||
this.sender.sendVerificationRequest(request)
|
||||
sender.sendVerificationRequest(request)
|
||||
dispatchTxUpdated()
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(CryptoStoreException::class)
|
||||
private suspend fun confirm() {
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
val result = withContext(coroutineDispatchers.io) {
|
||||
machine.confirmVerification(inner.otherUserId, inner.flowId)
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
this.sender.sendVerificationRequest(result.request)
|
||||
sender.sendVerificationRequest(result.request)
|
||||
dispatchTxUpdated()
|
||||
|
||||
val signatureRequest = result.signatureRequest
|
||||
|
||||
if (signatureRequest != null) {
|
||||
this.sender.sendSignatureUpload(signatureRequest)
|
||||
sender.sendSignatureUpload(signatureRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun cancelHelper(code: CancelCode) {
|
||||
val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value)
|
||||
val request = machine.cancelVerification(inner.otherUserId, inner.flowId, code.value)
|
||||
|
||||
if (request != null) {
|
||||
sender.sendVerificationRequest(request)
|
||||
@ -230,9 +231,9 @@ internal class SasVerification(
|
||||
|
||||
/** Fetch fresh data from the Rust side for our verification flow */
|
||||
private fun refreshData() {
|
||||
when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) {
|
||||
when (val verification = machine.getVerification(inner.otherUserId, inner.flowId)) {
|
||||
is Verification.SasV1 -> {
|
||||
this.inner = verification.sas
|
||||
inner = verification.sas
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
|
@ -16,9 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
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
|
||||
@ -80,11 +79,12 @@ internal class OwnUserIdentity(
|
||||
private val userSigningKey: CryptoCrossSigningKey,
|
||||
private val trustsOurOwnDevice: Boolean,
|
||||
private val olmMachine: OlmMachine,
|
||||
private val requestSender: RequestSender) : UserIdentities() {
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() {
|
||||
/**
|
||||
* Our own user id.
|
||||
*/
|
||||
override fun userId() = this.userId
|
||||
override fun userId() = userId
|
||||
|
||||
/**
|
||||
* Manually verify our user identity.
|
||||
@ -95,8 +95,8 @@ internal class OwnUserIdentity(
|
||||
*/
|
||||
@Throws(SignatureException::class)
|
||||
override suspend fun verify() {
|
||||
val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) }
|
||||
this.requestSender.sendSignatureUpload(request)
|
||||
val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) }
|
||||
requestSender.sendSignatureUpload(request)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,13 +106,13 @@ internal class OwnUserIdentity(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
override suspend fun verified(): Boolean {
|
||||
return withContext(Dispatchers.IO) { olmMachine.inner().isIdentityVerified(userId) }
|
||||
return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the identity trust our own device.
|
||||
*/
|
||||
fun trustsOurOwnDevice() = this.trustsOurOwnDevice
|
||||
fun trustsOurOwnDevice() = trustsOurOwnDevice
|
||||
|
||||
/**
|
||||
* Request an interactive verification to begin
|
||||
@ -133,14 +133,15 @@ internal class OwnUserIdentity(
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun requestVerification(methods: List<VerificationMethod>): VerificationRequest {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
val result = this.olmMachine.inner().requestSelfVerification(stringMethods)
|
||||
this.requestSender.sendVerificationRequest(result!!.request)
|
||||
val result = olmMachine.inner().requestSelfVerification(stringMethods)
|
||||
requestSender.sendVerificationRequest(result!!.request)
|
||||
|
||||
return VerificationRequest(
|
||||
this.olmMachine.inner(),
|
||||
result.verification,
|
||||
this.requestSender,
|
||||
this.olmMachine.verificationListeners
|
||||
machine = olmMachine.inner(),
|
||||
inner = result.verification,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = olmMachine.verificationListeners
|
||||
)
|
||||
}
|
||||
|
||||
@ -148,9 +149,9 @@ internal class OwnUserIdentity(
|
||||
* Convert the identity into a MxCrossSigningInfo class.
|
||||
*/
|
||||
override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo {
|
||||
val masterKey = this.masterKey
|
||||
val selfSigningKey = this.selfSigningKey
|
||||
val userSigningKey = this.userSigningKey
|
||||
val masterKey = masterKey
|
||||
val selfSigningKey = selfSigningKey
|
||||
val userSigningKey = userSigningKey
|
||||
val trustLevel = DeviceTrustLevel(verified(), false)
|
||||
// TODO remove this, this is silly, we have way too many methods to check if a user is verified
|
||||
masterKey.trustLevel = trustLevel
|
||||
@ -158,7 +159,7 @@ internal class OwnUserIdentity(
|
||||
userSigningKey.trustLevel = trustLevel
|
||||
|
||||
val crossSigningKeys = listOf(masterKey, selfSigningKey, userSigningKey)
|
||||
return MXCrossSigningInfo(this.userId, crossSigningKeys)
|
||||
return MXCrossSigningInfo(userId, crossSigningKeys)
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,11 +173,12 @@ internal class UserIdentity(
|
||||
private val masterKey: CryptoCrossSigningKey,
|
||||
private val selfSigningKey: CryptoCrossSigningKey,
|
||||
private val olmMachine: OlmMachine,
|
||||
private val requestSender: RequestSender) : UserIdentities() {
|
||||
private val requestSender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() {
|
||||
/**
|
||||
* The unique ID of the user that this identity belongs to.
|
||||
*/
|
||||
override fun userId() = this.userId
|
||||
override fun userId() = userId
|
||||
|
||||
/**
|
||||
* Manually verify this user identity.
|
||||
@ -189,8 +191,8 @@ internal class UserIdentity(
|
||||
*/
|
||||
@Throws(SignatureException::class)
|
||||
override suspend fun verify() {
|
||||
val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) }
|
||||
this.requestSender.sendSignatureUpload(request)
|
||||
val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) }
|
||||
requestSender.sendSignatureUpload(request)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,7 +201,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(Dispatchers.IO) { olmMachine.inner().isIdentityVerified(userId) }
|
||||
return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,17 +234,18 @@ internal class UserIdentity(
|
||||
transactionId: String
|
||||
): VerificationRequest {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
val content = this.olmMachine.inner().verificationRequestContent(this.userId, stringMethods)!!
|
||||
val content = olmMachine.inner().verificationRequestContent(userId, stringMethods)!!
|
||||
|
||||
val eventID = requestSender.sendRoomMessage(EventType.MESSAGE, roomId, content, transactionId)
|
||||
|
||||
val innerRequest = this.olmMachine.inner().requestVerification(this.userId, roomId, eventID, stringMethods)!!
|
||||
val innerRequest = olmMachine.inner().requestVerification(userId, roomId, eventID, stringMethods)!!
|
||||
|
||||
return VerificationRequest(
|
||||
this.olmMachine.inner(),
|
||||
innerRequest,
|
||||
this.requestSender,
|
||||
this.olmMachine.verificationListeners
|
||||
machine = olmMachine.inner(),
|
||||
inner = innerRequest,
|
||||
sender = requestSender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = olmMachine.verificationListeners
|
||||
)
|
||||
}
|
||||
|
||||
@ -250,14 +253,14 @@ internal class UserIdentity(
|
||||
* Convert the identity into a MxCrossSigningInfo class.
|
||||
*/
|
||||
override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo {
|
||||
// val crossSigningKeys = listOf(this.masterKey, this.selfSigningKey)
|
||||
// val crossSigningKeys = listOf(masterKey, selfSigningKey)
|
||||
val trustLevel = DeviceTrustLevel(verified(), false)
|
||||
// TODO remove this, this is silly, we have way too many methods to check if a user is verified
|
||||
masterKey.trustLevel = trustLevel
|
||||
selfSigningKey.trustLevel = trustLevel
|
||||
return MXCrossSigningInfo(this.userId, listOf(
|
||||
this.masterKey.also { it.trustLevel = trustLevel },
|
||||
this.selfSigningKey.also { it.trustLevel = trustLevel }
|
||||
return MXCrossSigningInfo(userId, listOf(
|
||||
masterKey.also { it.trustLevel = trustLevel },
|
||||
selfSigningKey.also { it.trustLevel = trustLevel }
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady
|
||||
@ -45,6 +46,7 @@ internal class VerificationRequest(
|
||||
private val machine: OlmMachine,
|
||||
private var inner: VerificationRequest,
|
||||
private val sender: RequestSender,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val listeners: ArrayList<VerificationService.Listener>
|
||||
) {
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
@ -53,7 +55,7 @@ internal class VerificationRequest(
|
||||
uiHandler.post {
|
||||
listeners.forEach {
|
||||
try {
|
||||
it.verificationRequestUpdated(this.toPendingVerificationRequest())
|
||||
it.verificationRequestUpdated(toPendingVerificationRequest())
|
||||
} catch (e: Throwable) {
|
||||
Timber.e(e, "## Error while notifying listeners")
|
||||
}
|
||||
@ -68,12 +70,12 @@ internal class VerificationRequest(
|
||||
* event that initiated the flow.
|
||||
*/
|
||||
internal fun flowId(): String {
|
||||
return this.inner.flowId
|
||||
return inner.flowId
|
||||
}
|
||||
|
||||
/** The user ID of the other user that is participating in this verification flow */
|
||||
internal fun otherUser(): String {
|
||||
return this.inner.otherUserId
|
||||
return inner.otherUserId
|
||||
}
|
||||
|
||||
/** The device ID of the other user's device that is participating in this verification flow
|
||||
@ -83,12 +85,12 @@ internal class VerificationRequest(
|
||||
* */
|
||||
internal fun otherDeviceId(): String? {
|
||||
refreshData()
|
||||
return this.inner.otherDeviceId
|
||||
return inner.otherDeviceId
|
||||
}
|
||||
|
||||
/** Did we initiate this verification flow */
|
||||
internal fun weStarted(): Boolean {
|
||||
return this.inner.weStarted
|
||||
return inner.weStarted
|
||||
}
|
||||
|
||||
/** Get the id of the room where this verification is happening
|
||||
@ -96,7 +98,7 @@ internal class VerificationRequest(
|
||||
* Will be null if the verification is not happening inside a room.
|
||||
*/
|
||||
internal fun roomId(): String? {
|
||||
return this.inner.roomId
|
||||
return inner.roomId
|
||||
}
|
||||
|
||||
/** Did the non-initiating side respond with a m.key.verification.read event
|
||||
@ -107,13 +109,13 @@ internal class VerificationRequest(
|
||||
*/
|
||||
internal fun isReady(): Boolean {
|
||||
refreshData()
|
||||
return this.inner.isReady
|
||||
return inner.isReady
|
||||
}
|
||||
|
||||
/** Did we advertise that we're able to scan QR codes */
|
||||
internal fun canScanQrCodes(): Boolean {
|
||||
refreshData()
|
||||
return this.inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false
|
||||
return inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false
|
||||
}
|
||||
|
||||
/** Accept the verification request advertising the given methods as supported
|
||||
@ -132,15 +134,15 @@ internal class VerificationRequest(
|
||||
suspend fun acceptWithMethods(methods: List<VerificationMethod>) {
|
||||
val stringMethods = prepareMethods(methods)
|
||||
|
||||
val request = this.machine.acceptVerificationRequest(
|
||||
this.inner.otherUserId,
|
||||
this.inner.flowId,
|
||||
val request = machine.acceptVerificationRequest(
|
||||
inner.otherUserId,
|
||||
inner.flowId,
|
||||
stringMethods
|
||||
)
|
||||
|
||||
if (request != null) {
|
||||
this.sender.sendVerificationRequest(request)
|
||||
this.dispatchRequestUpdated()
|
||||
sender.sendVerificationRequest(request)
|
||||
dispatchRequestUpdated()
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,12 +160,12 @@ internal class VerificationRequest(
|
||||
* emoji verification, or null if we can't yet transition into emoji verification.
|
||||
*/
|
||||
internal suspend fun startSasVerification(): SasVerification? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
return withContext(coroutineDispatchers.io) {
|
||||
val result = machine.startSasVerification(inner.otherUserId, inner.flowId)
|
||||
|
||||
if (result != null) {
|
||||
sender.sendVerificationRequest(result.request)
|
||||
SasVerification(machine, result.sas, sender, listeners)
|
||||
SasVerification(machine, result.sas, sender, coroutineDispatchers, listeners)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@ -187,10 +189,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 = this.machine.scanQrCode(this.otherUser(), this.flowId(), encodedData) ?: return null
|
||||
val result = machine.scanQrCode(otherUser(), flowId(), encodedData) ?: return null
|
||||
|
||||
this.sender.sendVerificationRequest(result.request)
|
||||
return QrCodeVerification(this.machine, this, result.qr, this.sender, this.listeners)
|
||||
sender.sendVerificationRequest(result.request)
|
||||
return QrCodeVerification(machine, this, result.qr, sender, coroutineDispatchers, listeners)
|
||||
}
|
||||
|
||||
/** Transition into a QR code verification to display a QR code
|
||||
@ -211,15 +213,16 @@ internal class VerificationRequest(
|
||||
* QR code verification, or null if we can't yet transition into QR code verification.
|
||||
*/
|
||||
internal fun startQrVerification(): QrCodeVerification? {
|
||||
val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId)
|
||||
val qrcode = machine.startQrVerification(inner.otherUserId, inner.flowId)
|
||||
|
||||
return if (qrcode != null) {
|
||||
QrCodeVerification(
|
||||
this.machine,
|
||||
this,
|
||||
qrcode,
|
||||
this.sender,
|
||||
this.listeners,
|
||||
machine = machine,
|
||||
request = this,
|
||||
inner = qrcode,
|
||||
sender = sender,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
listeners = listeners,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
@ -237,24 +240,24 @@ internal class VerificationRequest(
|
||||
* The method turns into a noop, if the verification flow has already been cancelled.
|
||||
*/
|
||||
internal suspend fun cancel() {
|
||||
val request = this.machine.cancelVerification(
|
||||
this.inner.otherUserId,
|
||||
this.inner.flowId,
|
||||
val request = machine.cancelVerification(
|
||||
inner.otherUserId,
|
||||
inner.flowId,
|
||||
CancelCode.User.value
|
||||
)
|
||||
|
||||
if (request != null) {
|
||||
this.sender.sendVerificationRequest(request)
|
||||
this.dispatchRequestUpdated()
|
||||
sender.sendVerificationRequest(request)
|
||||
dispatchRequestUpdated()
|
||||
}
|
||||
}
|
||||
|
||||
/** Fetch fresh data from the Rust side for our verification flow */
|
||||
private fun refreshData() {
|
||||
val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId)
|
||||
val request = machine.getVerificationRequest(inner.otherUserId, inner.flowId)
|
||||
|
||||
if (request != null) {
|
||||
this.inner = request
|
||||
inner = request
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +272,7 @@ internal class VerificationRequest(
|
||||
*/
|
||||
internal fun toPendingVerificationRequest(): PendingVerificationRequest {
|
||||
refreshData()
|
||||
val cancelInfo = this.inner.cancelInfo
|
||||
val cancelInfo = inner.cancelInfo
|
||||
val cancelCode =
|
||||
if (cancelInfo != null) {
|
||||
safeValueOf(cancelInfo.cancelCode)
|
||||
@ -277,72 +280,72 @@ internal class VerificationRequest(
|
||||
null
|
||||
}
|
||||
|
||||
val ourMethods = this.inner.ourMethods
|
||||
val theirMethods = this.inner.theirMethods
|
||||
val otherDeviceId = this.inner.otherDeviceId
|
||||
val ourMethods = inner.ourMethods
|
||||
val theirMethods = inner.theirMethods
|
||||
val otherDeviceId = inner.otherDeviceId
|
||||
|
||||
var requestInfo: ValidVerificationInfoRequest? = null
|
||||
var readyInfo: ValidVerificationInfoReady? = null
|
||||
|
||||
if (this.inner.weStarted && ourMethods != null) {
|
||||
if (inner.weStarted && ourMethods != null) {
|
||||
requestInfo =
|
||||
ValidVerificationInfoRequest(
|
||||
this.inner.flowId,
|
||||
this.machine.deviceId(),
|
||||
ourMethods,
|
||||
null,
|
||||
transactionId = inner.flowId,
|
||||
fromDevice = machine.deviceId(),
|
||||
methods = ourMethods,
|
||||
timestamp = null,
|
||||
)
|
||||
} else if (!this.inner.weStarted && ourMethods != null) {
|
||||
} else if (!inner.weStarted && ourMethods != null) {
|
||||
readyInfo =
|
||||
ValidVerificationInfoReady(
|
||||
this.inner.flowId,
|
||||
this.machine.deviceId(),
|
||||
ourMethods,
|
||||
transactionId = inner.flowId,
|
||||
fromDevice = machine.deviceId(),
|
||||
methods = ourMethods,
|
||||
)
|
||||
}
|
||||
|
||||
if (this.inner.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
if (inner.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
readyInfo =
|
||||
ValidVerificationInfoReady(
|
||||
this.inner.flowId,
|
||||
otherDeviceId,
|
||||
theirMethods,
|
||||
transactionId = inner.flowId,
|
||||
fromDevice = otherDeviceId,
|
||||
methods = theirMethods,
|
||||
)
|
||||
} else if (!this.inner.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
} else if (!inner.weStarted && theirMethods != null && otherDeviceId != null) {
|
||||
requestInfo =
|
||||
ValidVerificationInfoRequest(
|
||||
this.inner.flowId,
|
||||
otherDeviceId,
|
||||
theirMethods,
|
||||
System.currentTimeMillis(),
|
||||
transactionId = inner.flowId,
|
||||
fromDevice = otherDeviceId,
|
||||
methods = theirMethods,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
)
|
||||
}
|
||||
|
||||
return PendingVerificationRequest(
|
||||
// Creation time
|
||||
System.currentTimeMillis(),
|
||||
ageLocalTs = System.currentTimeMillis(),
|
||||
// Who initiated the request
|
||||
!this.inner.weStarted,
|
||||
isIncoming = !inner.weStarted,
|
||||
// Local echo id, what to do here?
|
||||
this.inner.flowId,
|
||||
localId = inner.flowId,
|
||||
// other user
|
||||
this.inner.otherUserId,
|
||||
otherUserId = inner.otherUserId,
|
||||
// room id
|
||||
this.inner.roomId,
|
||||
roomId = inner.roomId,
|
||||
// transaction id
|
||||
this.inner.flowId,
|
||||
transactionId = inner.flowId,
|
||||
// val requestInfo: ValidVerificationInfoRequest? = null,
|
||||
requestInfo,
|
||||
requestInfo = requestInfo,
|
||||
// val readyInfo: ValidVerificationInfoReady? = null,
|
||||
readyInfo,
|
||||
readyInfo = readyInfo,
|
||||
// cancel code if there is one
|
||||
cancelCode,
|
||||
cancelConclusion = cancelCode,
|
||||
// are we done/successful
|
||||
this.inner.isDone,
|
||||
isSuccessful = inner.isDone,
|
||||
// did another device answer the request
|
||||
this.inner.isPassive,
|
||||
handledByOtherSession = inner.isPassive,
|
||||
// devices that should receive the events we send out
|
||||
null,
|
||||
targetDevices = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import android.os.Looper
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.WorkerThread
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
@ -95,7 +94,7 @@ internal class RustKeyBackupService @Inject constructor(
|
||||
|
||||
// private var backupAllGroupSessionsCallback: MatrixCallback<Unit>? = null
|
||||
|
||||
private val importScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||
private val importScope = CoroutineScope(SupervisorJob() + coroutineDispatchers.main)
|
||||
|
||||
private var keysBackupStateListener: KeysBackupStateListener? = null
|
||||
|
||||
@ -490,7 +489,7 @@ internal class RustKeyBackupService @Inject constructor(
|
||||
val data = getKeys(sessionId, roomId, keysVersionResult.version)
|
||||
|
||||
return withContext(coroutineDispatchers.computation) {
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(coroutineDispatchers.main) {
|
||||
stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(0, data.roomIdToRoomKeysBackupData.size))
|
||||
}
|
||||
// Decrypting by chunk of 500 keys in parallel
|
||||
@ -513,7 +512,7 @@ internal class RustKeyBackupService @Inject constructor(
|
||||
.awaitAll()
|
||||
.flatten()
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(coroutineDispatchers.main) {
|
||||
val stepProgress = StepProgressListener.Step.DecryptingKey(data.roomIdToRoomKeysBackupData.size, data.roomIdToRoomKeysBackupData.size)
|
||||
stepProgressListener?.onStepProgress(stepProgress)
|
||||
}
|
||||
@ -532,7 +531,7 @@ internal class RustKeyBackupService @Inject constructor(
|
||||
val progressListener = if (stepProgressListener != null) {
|
||||
object : ProgressListener {
|
||||
override fun onProgress(progress: Int, total: Int) {
|
||||
cryptoCoroutineScope.launch(Dispatchers.Main) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val stepProgress = StepProgressListener.Step.ImportingKey(progress, total)
|
||||
stepProgressListener.onStepProgress(stepProgress)
|
||||
}
|
||||
@ -878,7 +877,7 @@ internal class RustKeyBackupService @Inject constructor(
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
if (failure is Failure.ServerError) {
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(coroutineDispatchers.main) {
|
||||
Timber.e(failure, "backupKeys: backupKeys failed.")
|
||||
|
||||
when (failure.error.code) {
|
||||
|
Loading…
Reference in New Issue
Block a user