PR Review: var -> val, internal and other cleanup

This commit is contained in:
Benoit Marty 2020-01-30 23:15:19 +01:00
parent 506c2dd262
commit 9dde43f65b
58 changed files with 224 additions and 211 deletions

View file

@ -37,8 +37,11 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Assert.* import org.junit.Assert.assertEquals
import java.util.* import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import java.util.ArrayList
import java.util.UUID
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -280,7 +283,7 @@ class CommonTestHelper(context: Context) {
fun signout(session: Session) { fun signout(session: Session) {
val lock = CountDownLatch(1) val lock = CountDownLatch(1)
session.signOut(true, object : TestMatrixCallback<Unit>(lock) {}) session.signOut(true, TestMatrixCallback(lock))
await(lock) await(lock)
} }
} }

View file

@ -12,6 +12,7 @@ import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
@ -73,14 +74,12 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD password = TestConstants.PASSWORD
) )
val aliceLatch = CountDownLatch(1) val latch = CountDownLatch(2)
val bobLatch = CountDownLatch(1)
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(aliceLatch)) aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(bobLatch)) bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
mTestHelper.await(aliceLatch) mTestHelper.await(latch)
mTestHelper.await(bobLatch)
// Check that alice can see bob keys // Check that alice can see bob keys
val downloadLatch = CountDownLatch(1) val downloadLatch = CountDownLatch(1)
@ -88,14 +87,14 @@ class XSigningTest : InstrumentedTest {
mTestHelper.await(downloadLatch) mTestHelper.await(downloadLatch)
val bobKeysFromAlicePOV = aliceSession.getCrossSigningService().getUserCrossSigningKeys(bobSession.myUserId) val bobKeysFromAlicePOV = aliceSession.getCrossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV?.masterKey()) assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey())
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV?.userKey()) assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV?.selfSigningKey()) assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV?.masterKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey) assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV?.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey) assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
assertTrue("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV?.isTrusted() == false) assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())
mTestHelper.signout(aliceSession) mTestHelper.signout(aliceSession)
mTestHelper.signout(bobSession) mTestHelper.signout(bobSession)
@ -117,14 +116,12 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD password = TestConstants.PASSWORD
) )
val aliceLatch = CountDownLatch(1) val latch = CountDownLatch(2)
val bobLatch = CountDownLatch(1)
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(aliceLatch)) aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(bobLatch)) bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
mTestHelper.await(aliceLatch) mTestHelper.await(latch)
mTestHelper.await(bobLatch)
// Check that alice can see bob keys // Check that alice can see bob keys
val downloadLatch = CountDownLatch(1) val downloadLatch = CountDownLatch(1)

View file

@ -314,7 +314,8 @@ class KeysBackupTest : InstrumentedTest {
val sessionData = keysBackup val sessionData = keysBackup
.decryptKeyBackupData(keyBackupData, .decryptKeyBackupData(keyBackupData,
session.olmInboundGroupSession!!.sessionIdentifier(), session.olmInboundGroupSession!!.sessionIdentifier(),
cryptoTestData.roomId, decryption!!) cryptoTestData.roomId,
decryption!!)
assertNotNull(sessionData) assertNotNull(sessionData)
// - Compare the decrypted megolm key with the original one // - Compare the decrypted megolm key with the original one
assertKeysEquals(session.exportKeys(), sessionData) assertKeysEquals(session.exportKeys(), sessionData)

View file

@ -47,7 +47,6 @@ import org.junit.FixMethodOrder
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.MethodSorters import org.junit.runners.MethodSorters
import java.util.ArrayList
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@ -78,7 +77,10 @@ class SASTest : InstrumentedTest {
} }
bobVerificationService.addListener(bobListener) bobVerificationService.addListener(bobListener)
val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobSession.myUserId, bobSession.getMyDevice().deviceId) val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
bobSession.myUserId,
bobSession.getMyDevice().deviceId,
null)
assertNotNull("Alice should have a started transaction", txID) assertNotNull("Alice should have a started transaction", txID)
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!) val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
@ -325,7 +327,7 @@ class SASTest : InstrumentedTest {
val aliceCreatedLatch = CountDownLatch(2) val aliceCreatedLatch = CountDownLatch(2)
val aliceCancelledLatch = CountDownLatch(2) val aliceCancelledLatch = CountDownLatch(2)
val createdTx = ArrayList<SASDefaultVerificationTransaction>() val createdTx = mutableListOf<SASDefaultVerificationTransaction>()
val aliceListener = object : VerificationService.VerificationListener { val aliceListener = object : VerificationService.VerificationListener {
override fun transactionCreated(tx: VerificationTransaction) { override fun transactionCreated(tx: VerificationTransaction) {
createdTx.add(tx as SASDefaultVerificationTransaction) createdTx.add(tx as SASDefaultVerificationTransaction)
@ -344,8 +346,8 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession!!.myUserId val bobUserId = bobSession!!.myUserId
val bobDeviceId = bobSession.getMyDevice().deviceId val bobDeviceId = bobSession.getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId) aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId) aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceCreatedLatch) mTestHelper.await(aliceCreatedLatch)
mTestHelper.await(aliceCancelledLatch) mTestHelper.await(aliceCancelledLatch)
@ -402,7 +404,7 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession.myUserId val bobUserId = bobSession.myUserId
val bobDeviceId = bobSession.getMyDevice().deviceId val bobDeviceId = bobSession.getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId) aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceAcceptedLatch) mTestHelper.await(aliceAcceptedLatch)
assertTrue("Should have receive a commitment", accepted!!.commitment?.trim()?.isEmpty() == false) assertTrue("Should have receive a commitment", accepted!!.commitment?.trim()?.isEmpty() == false)
@ -471,7 +473,7 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession.myUserId val bobUserId = bobSession.myUserId
val bobDeviceId = bobSession.getMyDevice().deviceId val bobDeviceId = bobSession.getMyDevice().deviceId
val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId) val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceSASLatch) mTestHelper.await(aliceSASLatch)
mTestHelper.await(bobSASLatch) mTestHelper.await(bobSASLatch)
@ -541,7 +543,7 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession.myUserId val bobUserId = bobSession.myUserId
val bobDeviceId = bobSession.getMyDevice().deviceId val bobDeviceId = bobSession.getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId) aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceSASLatch) mTestHelper.await(aliceSASLatch)
mTestHelper.await(bobSASLatch) mTestHelper.await(bobSASLatch)

View file

@ -20,14 +20,11 @@ import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
import im.vector.matrix.android.internal.crypto.model.KeyUsage import im.vector.matrix.android.internal.crypto.model.KeyUsage
data class MXCrossSigningInfo( data class MXCrossSigningInfo(
val userId: String,
var userId: String, val crossSigningKeys: List<CryptoCrossSigningKey>
var crossSigningKeys: List<CryptoCrossSigningKey> = ArrayList()
) { ) {
fun isTrusted() : Boolean = masterKey()?.trustLevel?.isVerified() == true fun isTrusted(): Boolean = masterKey()?.trustLevel?.isVerified() == true
&& selfSigningKey()?.trustLevel?.isVerified() == true && selfSigningKey()?.trustLevel?.isVerified() == true
fun masterKey(): CryptoCrossSigningKey? = crossSigningKeys fun masterKey(): CryptoCrossSigningKey? = crossSigningKeys

View file

@ -58,16 +58,14 @@ interface VerificationService {
fun requestKeyVerificationInDMs(methods: List<VerificationMethod>, fun requestKeyVerificationInDMs(methods: List<VerificationMethod>,
otherUserId: String, otherUserId: String,
roomId: String, roomId: String,
localId: String? = LocalEcho.createLocalEchoId() localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
): PendingVerificationRequest
/** /**
* Request a key verification from another user using toDevice events. * Request a key verification from another user using toDevice events.
*/ */
fun requestKeyVerification(methods: List<VerificationMethod>, fun requestKeyVerification(methods: List<VerificationMethod>,
otherUserId: String, otherUserId: String,
otherDevices: List<String>? otherDevices: List<String>?): PendingVerificationRequest
): PendingVerificationRequest
fun declineVerificationRequestInDMs(otherUserId: String, fun declineVerificationRequestInDMs(otherUserId: String,
otherDeviceId: String, otherDeviceId: String,

View file

@ -86,9 +86,9 @@ data class Event(
var sendState: SendState = SendState.UNKNOWN var sendState: SendState = SendState.UNKNOWN
/** /**
The `age` value transcoded in a timestamp based on the device clock when the SDK received * The `age` value transcoded in a timestamp based on the device clock when the SDK received
the event from the home server. * the event from the home server.
Unlike `age`, this value is static. * Unlike `age`, this value is static.
*/ */
@Transient @Transient
var ageLocalTs: Long? = null var ageLocalTs: Long? = null

View file

@ -42,22 +42,28 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
fun onUsersDeviceUpdate(users: List<String>) fun onUsersDeviceUpdate(users: List<String>)
} }
private val deviceChangeListeners = ArrayList<UserDevicesUpdateListener>() private val deviceChangeListeners = mutableListOf<UserDevicesUpdateListener>()
fun addListener(listener: UserDevicesUpdateListener) { fun addListener(listener: UserDevicesUpdateListener) {
synchronized(deviceChangeListeners) {
deviceChangeListeners.add(listener) deviceChangeListeners.add(listener)
} }
}
fun removeListener(listener: UserDevicesUpdateListener) { fun removeListener(listener: UserDevicesUpdateListener) {
synchronized(deviceChangeListeners) {
deviceChangeListeners.remove(listener) deviceChangeListeners.remove(listener)
} }
}
fun dispatchDeviceChange(users: List<String>) { private fun dispatchDeviceChange(users: List<String>) {
synchronized(deviceChangeListeners) {
deviceChangeListeners.forEach { deviceChangeListeners.forEach {
try { try {
it.onUsersDeviceUpdate(users) it.onUsersDeviceUpdate(users)
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.e(failure, "Failed to dispatch device chande") Timber.e(failure, "Failed to dispatch device change")
}
} }
} }
} }

View file

@ -271,13 +271,13 @@ internal class DefaultCrossSigningService @Inject constructor(
} }
private fun clearSigningKeys() { private fun clearSigningKeys() {
this@DefaultCrossSigningService.masterPkSigning?.releaseSigning() masterPkSigning?.releaseSigning()
this@DefaultCrossSigningService.userPkSigning?.releaseSigning() userPkSigning?.releaseSigning()
this@DefaultCrossSigningService.selfSigningPkSigning?.releaseSigning() selfSigningPkSigning?.releaseSigning()
this@DefaultCrossSigningService.masterPkSigning = null masterPkSigning = null
this@DefaultCrossSigningService.userPkSigning = null userPkSigning = null
this@DefaultCrossSigningService.selfSigningPkSigning = null selfSigningPkSigning = null
cryptoStore.setMyCrossSigningInfo(null) cryptoStore.setMyCrossSigningInfo(null)
cryptoStore.storePrivateKeysInfo(null, null, null) cryptoStore.storePrivateKeysInfo(null, null, null)

View file

@ -15,8 +15,10 @@
*/ */
package im.vector.matrix.android.internal.crypto.crosssigning package im.vector.matrix.android.internal.crypto.crosssigning
data class DeviceTrustLevel(val crossSigningVerified: Boolean, val locallyVerified: Boolean?) { data class DeviceTrustLevel(
val crossSigningVerified: Boolean,
val locallyVerified: Boolean?
) {
fun isVerified() = crossSigningVerified || locallyVerified == true fun isVerified() = crossSigningVerified || locallyVerified == true
fun isCrossSigningVerified() = crossSigningVerified fun isCrossSigningVerified() = crossSigningVerified
fun isLocallyVerified() = locallyVerified fun isLocallyVerified() = locallyVerified

View file

@ -18,7 +18,6 @@ package im.vector.matrix.android.internal.crypto.crosssigning
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
sealed class DeviceTrustResult { sealed class DeviceTrustResult {
data class Success(val level: DeviceTrustLevel) : DeviceTrustResult() data class Success(val level: DeviceTrustLevel) : DeviceTrustResult()
data class UnknownDevice(val deviceID: String) : DeviceTrustResult() data class UnknownDevice(val deviceID: String) : DeviceTrustResult()
data class CrossSigningNotConfigured(val userID: String) : DeviceTrustResult() data class CrossSigningNotConfigured(val userID: String) : DeviceTrustResult()
@ -27,6 +26,6 @@ sealed class DeviceTrustResult {
data class InvalidDeviceSignature(val deviceId: String, val signingKey: String, val throwable: Throwable?) : DeviceTrustResult() data class InvalidDeviceSignature(val deviceId: String, val signingKey: String, val throwable: Throwable?) : DeviceTrustResult()
} }
fun DeviceTrustResult.isSuccess(): Boolean = this is DeviceTrustResult.Success fun DeviceTrustResult.isSuccess() = this is DeviceTrustResult.Success
fun DeviceTrustResult.isCrossSignedVerified(): Boolean = (this as? DeviceTrustResult.Success)?.level?.isCrossSigningVerified() == true fun DeviceTrustResult.isCrossSignedVerified() = this is DeviceTrustResult.Success && level.isCrossSigningVerified()
fun DeviceTrustResult.isLocallyVerified(): Boolean = (this as? DeviceTrustResult.Success)?.level?.isLocallyVerified() == true fun DeviceTrustResult.isLocallyVerified() = this is DeviceTrustResult.Success && level.isLocallyVerified() == true

View file

@ -13,19 +13,19 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package im.vector.matrix.android.internal.crypto.crosssigning package im.vector.matrix.android.internal.crypto.crosssigning
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
sealed class UserTrustResult { sealed class UserTrustResult {
object Success : UserTrustResult() object Success : UserTrustResult()
// data class Success(val deviceID: String, val crossSigned: Boolean) : UserTrustResult() // data class Success(val deviceID: String, val crossSigned: Boolean) : UserTrustResult()
// // data class UnknownDevice(val deviceID: String) : UserTrustResult()
// data class UnknownDevice(val deviceID: String) : UserTrustResult()
data class CrossSigningNotConfigured(val userID: String) : UserTrustResult() data class CrossSigningNotConfigured(val userID: String) : UserTrustResult()
data class UnknownCrossSignatureInfo(val userID: String) : UserTrustResult() data class UnknownCrossSignatureInfo(val userID: String) : UserTrustResult()
data class KeysNotTrusted(val key: MXCrossSigningInfo) : UserTrustResult() data class KeysNotTrusted(val key: MXCrossSigningInfo) : UserTrustResult()
data class KeyNotSigned(val key: CryptoCrossSigningKey) : UserTrustResult() data class KeyNotSigned(val key: CryptoCrossSigningKey) : UserTrustResult()

View file

@ -1,3 +1,19 @@
/*
* Copyright 2020 New Vector Ltd
*
* 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 im.vector.matrix.android.internal.crypto.model package im.vector.matrix.android.internal.crypto.model
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
@ -87,6 +103,6 @@ enum class KeyUsage(val value: String) {
USER_SIGNING("user_signing") USER_SIGNING("user_signing")
} }
fun CryptoCrossSigningKey.toRest(): RestKeyInfo { internal fun CryptoCrossSigningKey.toRest(): RestKeyInfo {
return CryptoInfoMapper.map(this) return CryptoInfoMapper.map(this)
} }

View file

@ -29,15 +29,12 @@ data class CryptoDeviceInfo(
override val signatures: Map<String, Map<String, String>>? = null, override val signatures: Map<String, Map<String, String>>? = null,
val unsigned: JsonDict? = null, val unsigned: JsonDict? = null,
// TODO how to store if this device is verified by a user SSK, or is legacy trusted? // TODO how to store if this device is verified by a user SSK, or is legacy trusted?
// I need to know if it is trusted via cross signing (Trusted because bob verified it) // I need to know if it is trusted via cross signing (Trusted because bob verified it)
var trustLevel: DeviceTrustLevel? = null, var trustLevel: DeviceTrustLevel? = null,
var isBlocked: Boolean = false var isBlocked: Boolean = false
) : CryptoInfo {
)
: CryptoInfo {
val isVerified: Boolean val isVerified: Boolean
get() = trustLevel?.isVerified() ?: false get() = trustLevel?.isVerified() ?: false
@ -93,7 +90,7 @@ data class CryptoDeviceInfo(
// } // }
} }
fun CryptoDeviceInfo.toRest(): RestDeviceInfo { internal fun CryptoDeviceInfo.toRest(): RestDeviceInfo {
return CryptoInfoMapper.map(this) return CryptoInfoMapper.map(this)
} }

View file

@ -15,14 +15,10 @@
*/ */
package im.vector.matrix.android.internal.crypto.model package im.vector.matrix.android.internal.crypto.model
import com.squareup.moshi.Moshi
import im.vector.matrix.android.internal.crypto.model.rest.RestDeviceInfo import im.vector.matrix.android.internal.crypto.model.rest.RestDeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.RestKeyInfo import im.vector.matrix.android.internal.crypto.model.rest.RestKeyInfo
import im.vector.matrix.android.internal.di.SerializeNulls
object CryptoInfoMapper { internal object CryptoInfoMapper {
private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
fun map(restDeviceInfo: RestDeviceInfo): CryptoDeviceInfo { fun map(restDeviceInfo: RestDeviceInfo): CryptoDeviceInfo {
return CryptoDeviceInfo( return CryptoDeviceInfo(

View file

@ -24,5 +24,5 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
internal data class DeleteDeviceParams( internal data class DeleteDeviceParams(
@Json(name = "auth") @Json(name = "auth")
var userPasswordAuth: UserPasswordAuth? = null val userPasswordAuth: UserPasswordAuth? = null
) )

View file

@ -38,5 +38,4 @@ data class DeviceKeys(
@Json(name = "usage") @Json(name = "usage")
val usage: List<String>? = null val usage: List<String>? = null
) )

View file

@ -22,7 +22,7 @@ import com.squareup.moshi.JsonClass
* This class describes the key changes response * This class describes the key changes response
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class KeyChangesResponse( internal data class KeyChangesResponse(
// list of user ids which have new devices // list of user ids which have new devices
@Json(name = "changed") @Json(name = "changed")
var changed: List<String>? = null, var changed: List<String>? = null,

View file

@ -33,31 +33,31 @@ internal data class KeyVerificationAccept(
* Alices device should record this ID and use it in future messages in this transaction. * Alices device should record this ID and use it in future messages in this transaction.
*/ */
@Json(name = "transaction_id") @Json(name = "transaction_id")
override var transactionID: String? = null, override val transactionID: String? = null,
/** /**
* The key agreement protocol that Bobs device has selected to use, out of the list proposed by Alices device * The key agreement protocol that Bobs device has selected to use, out of the list proposed by Alices device
*/ */
@Json(name = "key_agreement_protocol") @Json(name = "key_agreement_protocol")
override var keyAgreementProtocol: String? = null, override val keyAgreementProtocol: String? = null,
/** /**
* The hash algorithm that Bobs device has selected to use, out of the list proposed by Alices device * The hash algorithm that Bobs device has selected to use, out of the list proposed by Alices device
*/ */
@Json(name = "hash") @Json(name = "hash")
override var hash: String? = null, override val hash: String? = null,
/** /**
* The message authentication code that Bobs device has selected to use, out of the list proposed by Alices device * The message authentication code that Bobs device has selected to use, out of the list proposed by Alices device
*/ */
@Json(name = "message_authentication_code") @Json(name = "message_authentication_code")
override var messageAuthenticationCode: String? = null, override val messageAuthenticationCode: String? = null,
/** /**
* An array of short authentication string methods that Bobs client (and Bob) understands. Must be a subset of the list proposed by Alices device * An array of short authentication string methods that Bobs client (and Bob) understands. Must be a subset of the list proposed by Alices device
*/ */
@Json(name = "short_authentication_string") @Json(name = "short_authentication_string")
override var shortAuthenticationStrings: List<String>? = null, override val shortAuthenticationStrings: List<String>? = null,
/** /**
* The hash (encoded as unpadded base64) of the concatenation of the devices ephemeral public key (QB, encoded as unpadded base64) * The hash (encoded as unpadded base64) of the concatenation of the devices ephemeral public key (QB, encoded as unpadded base64)
@ -89,14 +89,14 @@ internal data class KeyVerificationAccept(
commitment: String, commitment: String,
messageAuthenticationCode: String, messageAuthenticationCode: String,
shortAuthenticationStrings: List<String>): VerificationInfoAccept { shortAuthenticationStrings: List<String>): VerificationInfoAccept {
return KeyVerificationAccept().apply { return KeyVerificationAccept(
this.transactionID = tid transactionID = tid,
this.keyAgreementProtocol = keyAgreementProtocol keyAgreementProtocol = keyAgreementProtocol,
this.hash = hash hash = hash,
this.commitment = commitment commitment = commitment,
this.messageAuthenticationCode = messageAuthenticationCode messageAuthenticationCode = messageAuthenticationCode,
this.shortAuthenticationStrings = shortAuthenticationStrings shortAuthenticationStrings = shortAuthenticationStrings
} )
} }
} }
} }

View file

@ -34,12 +34,12 @@ internal data class KeyVerificationCancel(
/** /**
* machine-readable reason for cancelling, see #CancelCode * machine-readable reason for cancelling, see #CancelCode
*/ */
override var code: String? = null, override val code: String? = null,
/** /**
* human-readable reason for cancelling. This should only be used if the receiving client does not understand the code given. * human-readable reason for cancelling. This should only be used if the receiving client does not understand the code given.
*/ */
override var reason: String? = null override val reason: String? = null
) : SendToDeviceObject, VerificationInfoCancel { ) : SendToDeviceObject, VerificationInfoCancel {
companion object { companion object {

View file

@ -28,7 +28,7 @@ internal data class KeyVerificationKey(
/** /**
* the ID of the transaction that the message is part of * the ID of the transaction that the message is part of
*/ */
@Json(name = "transaction_id") override var transactionID: String? = null, @Json(name = "transaction_id") override val transactionID: String? = null,
/** /**
* The devices ephemeral public key, as an unpadded base64 string * The devices ephemeral public key, as an unpadded base64 string

View file

@ -26,7 +26,7 @@ import im.vector.matrix.android.internal.crypto.verification.VerificationInfoRea
internal data class KeyVerificationReady( internal data class KeyVerificationReady(
@Json(name = "from_device") override val fromDevice: String?, @Json(name = "from_device") override val fromDevice: String?,
@Json(name = "methods") override val methods: List<String>?, @Json(name = "methods") override val methods: List<String>?,
@Json(name = "transaction_id") override var transactionID: String? = null @Json(name = "transaction_id") override val transactionID: String? = null
) : SendToDeviceObject, VerificationInfoReady { ) : SendToDeviceObject, VerificationInfoReady {
override fun toSendToDeviceObject() = this override fun toSendToDeviceObject() = this

View file

@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass
* This class represents the response to /keys/claim request made by claimOneTimeKeysForUsersDevices. * This class represents the response to /keys/claim request made by claimOneTimeKeysForUsersDevices.
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class KeysClaimBody( internal data class KeysClaimBody(
/** /**
* The time (in milliseconds) to wait when downloading keys from remote servers. 10 seconds is the recommended default. * The time (in milliseconds) to wait when downloading keys from remote servers. 10 seconds is the recommended default.

View file

@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass
* This class represents the response to /keys/claim request made by claimOneTimeKeysForUsersDevices. * This class represents the response to /keys/claim request made by claimOneTimeKeysForUsersDevices.
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class KeysClaimResponse( internal data class KeysClaimResponse(
/** /**
* The requested keys ordered by device by user. * The requested keys ordered by device by user.

View file

@ -24,7 +24,7 @@ import com.squareup.moshi.JsonClass
* This class represents the body to /keys/query * This class represents the body to /keys/query
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class KeysQueryBody( internal data class KeysQueryBody(
/** /**
* The time (in milliseconds) to wait when downloading keys from remote servers. 10 seconds is the recommended default. * The time (in milliseconds) to wait when downloading keys from remote servers. 10 seconds is the recommended default.

View file

@ -28,28 +28,27 @@ import com.squareup.moshi.JsonClass
* The user_signing_keys property will only be included when a user requests their own keys. * The user_signing_keys property will only be included when a user requests their own keys.
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class KeysQueryResponse( internal data class KeysQueryResponse(
/** /**
* The device keys per devices per users. * The device keys per devices per users.
* Map from userId to map from deviceId to MXDeviceInfo * Map from userId to map from deviceId to MXDeviceInfo
* TODO Use MXUsersDevicesMap? * TODO Use MXUsersDevicesMap?
*/ */
@Json(name = "device_keys") @Json(name = "device_keys")
var deviceKeys: Map<String, Map<String, RestDeviceInfo>>? = null, val deviceKeys: Map<String, Map<String, RestDeviceInfo>>? = null,
/** /**
* The failures sorted by homeservers. TODO Bad comment ? * The failures sorted by homeservers. TODO Bad comment ?
* TODO Use MXUsersDevicesMap? * TODO Use MXUsersDevicesMap?
*/ */
var failures: Map<String, Map<String, Any>>? = null, val failures: Map<String, Map<String, Any>>? = null,
@Json(name = "master_keys") @Json(name = "master_keys")
var masterKeys: Map<String, RestKeyInfo?>? = null, val masterKeys: Map<String, RestKeyInfo?>? = null,
@Json(name = "self_signing_keys") @Json(name = "self_signing_keys")
var selfSigningKeys: Map<String, RestKeyInfo?>? = null, val selfSigningKeys: Map<String, RestKeyInfo?>? = null,
@Json(name = "user_signing_keys") @Json(name = "user_signing_keys")
var userSigningKeys: Map<String, RestKeyInfo?>? = null val userSigningKeys: Map<String, RestKeyInfo?>? = null
) )

View file

@ -21,10 +21,10 @@ import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.api.util.JsonDict
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class KeysUploadBody( internal data class KeysUploadBody(
@Json(name = "device_keys") @Json(name = "device_keys")
var deviceKeys: RestDeviceInfo? = null, val deviceKeys: RestDeviceInfo? = null,
@Json(name = "one_time_keys") @Json(name = "one_time_keys")
var oneTimeKeys: JsonDict? = null val oneTimeKeys: JsonDict? = null
) )

View file

@ -22,7 +22,7 @@ import com.squareup.moshi.JsonClass
* This class represents the response to /keys/upload request made by uploadKeys. * This class represents the response to /keys/upload request made by uploadKeys.
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class KeysUploadResponse( internal data class KeysUploadResponse(
/** /**
* The count per algorithm as returned by the home server: a map (algorithm to count). * The count per algorithm as returned by the home server: a map (algorithm to count).

View file

@ -20,40 +20,41 @@ import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.api.util.JsonDict
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class RestDeviceInfo( internal data class RestDeviceInfo(
/** /**
* The id of this device. * The id of this device.
*/ */
@Json(name = "device_id") @Json(name = "device_id")
var deviceId: String, val deviceId: String,
/** /**
* the user id * the user id
*/ */
@Json(name = "user_id") @Json(name = "user_id")
var userId: String, val userId: String,
/** /**
* The list of algorithms supported by this device. * The list of algorithms supported by this device.
*/ */
@Json(name = "algorithms") @Json(name = "algorithms")
var algorithms: List<String>? = null, val algorithms: List<String>? = null,
/** /**
* A map from "<key type>:<deviceId>" to "<base64-encoded key>". * A map from "<key type>:<deviceId>" to "<base64-encoded key>".
*/ */
@Json(name = "keys") @Json(name = "keys")
var keys: Map<String, String>? = null, val keys: Map<String, String>? = null,
/** /**
* The signature of this MXDeviceInfo. * The signature of this MXDeviceInfo.
* A map from "<userId>" to a map from "<key type>:<deviceId>" to "<signature>" * A map from "<userId>" to a map from "<key type>:<deviceId>" to "<signature>"
*/ */
@Json(name = "signatures") @Json(name = "signatures")
var signatures: Map<String, Map<String, String>>? = null, val signatures: Map<String, Map<String, String>>? = null,
/* /*
* Additional data from the home server. * Additional data from the home server.
*/ */
@Json(name = "unsigned") @Json(name = "unsigned")
var unsigned: JsonDict? = null) val unsigned: JsonDict? = null
)

View file

@ -21,7 +21,7 @@ import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
import im.vector.matrix.android.internal.crypto.model.CryptoInfoMapper import im.vector.matrix.android.internal.crypto.model.CryptoInfoMapper
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class RestKeyInfo( internal data class RestKeyInfo(
/** /**
* The user who owns the key * The user who owns the key
*/ */

View file

@ -21,7 +21,7 @@ import com.squareup.moshi.Json
* Parent class representing an room key action request * Parent class representing an room key action request
* Note: this class cannot be abstract because of [org.matrix.androidsdk.core.JsonUtils.toRoomKeyShare] * Note: this class cannot be abstract because of [org.matrix.androidsdk.core.JsonUtils.toRoomKeyShare]
*/ */
open class RoomKeyShare : SendToDeviceObject { internal open class RoomKeyShare : SendToDeviceObject {
var action: String? = null var action: String? = null

View file

@ -21,7 +21,7 @@ import com.squareup.moshi.JsonClass
* Class representing an room key request cancellation content * Class representing an room key request cancellation content
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
class RoomKeyShareCancellation : RoomKeyShare() { internal class RoomKeyShareCancellation : RoomKeyShare() {
init { init {
action = ACTION_SHARE_CANCELLATION action = ACTION_SHARE_CANCELLATION
} }

View file

@ -22,8 +22,7 @@ import com.squareup.moshi.JsonClass
* Class representing an room key request content * Class representing an room key request content
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
class RoomKeyShareRequest : RoomKeyShare() { internal class RoomKeyShareRequest : RoomKeyShare() {
var body: RoomKeyRequestBody? = null var body: RoomKeyRequestBody? = null
init { init {

View file

@ -16,13 +16,12 @@
package im.vector.matrix.android.internal.crypto.model.rest package im.vector.matrix.android.internal.crypto.model.rest
class SendToDeviceBody { internal data class SendToDeviceBody(
/** /**
* `Any` should implement [SendToDeviceObject], but we cannot use interface here because of Json serialization * `Any` should implement [SendToDeviceObject], but we cannot use interface here because of Json serialization
* *
* The messages to send. A map from user ID, to a map from device ID to message body. * The messages to send. A map from user ID, to a map from device ID to message body.
* The device ID may also be *, meaning all known devices for the user. * The device ID may also be *, meaning all known devices for the user.
*/ */
var messages: Map<String, Map<String, Any>>? = null val messages: Map<String, Map<String, Any>>?
} )

View file

@ -24,8 +24,7 @@ import com.squareup.moshi.JsonClass
* Upload Signature response * Upload Signature response
*/ */
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class SignatureUploadResponse( internal data class SignatureUploadResponse(
/** /**
* The response contains a failures property, which is a map of user ID to device ID to failure reason, * The response contains a failures property, which is a map of user ID to device ID to failure reason,
* if any of the uploaded keys failed. * if any of the uploaded keys failed.
@ -33,7 +32,7 @@ data class SignatureUploadResponse(
* If a signature is not valid, the homeserver should set the corresponding entry in failures to a JSON object * If a signature is not valid, the homeserver should set the corresponding entry in failures to a JSON object
* with the errcode property set to M_INVALID_SIGNATURE. * with the errcode property set to M_INVALID_SIGNATURE.
*/ */
var failures: Map<String, Map<String, @JvmSuppressWildcards Any>>? = null val failures: Map<String, Map<String, @JvmSuppressWildcards Any>>? = null
) )
@ -41,8 +40,10 @@ data class SignatureUploadResponse(
data class UploadResponseFailure( data class UploadResponseFailure(
@Json(name = "status") @Json(name = "status")
val status: Int, val status: Int,
@Json(name = "errCode") @Json(name = "errCode")
val errCode: String, val errCode: String,
@Json(name = "message") @Json(name = "message")
val message: String val message: String
) )

View file

@ -20,12 +20,10 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class UpdateDeviceInfoBody( internal data class UpdateDeviceInfoBody(
/** /**
* The new display name for this device. If not given, the display name is unchanged. * The new display name for this device. If not given, the display name is unchanged.
*/ */
@Json(name = "display_name") @Json(name = "display_name")
var displayName: String? = null var displayName: String? = null
) )

View file

@ -22,9 +22,9 @@ import im.vector.matrix.android.internal.crypto.model.toRest
/** /**
* Helper class to build CryptoApi#uploadSignatures params * Helper class to build CryptoApi#uploadSignatures params
*/ */
data class UploadSignatureQueryBuilder( internal data class UploadSignatureQueryBuilder(
private val deviceInfoList: ArrayList<CryptoDeviceInfo> = ArrayList(), private val deviceInfoList: MutableList<CryptoDeviceInfo> = mutableListOf(),
private val signingKeyInfoList: ArrayList<CryptoCrossSigningKey> = ArrayList() private val signingKeyInfoList: MutableList<CryptoCrossSigningKey> = mutableListOf()
) { ) {
fun withDeviceInfo(deviceInfo: CryptoDeviceInfo) = apply { fun withDeviceInfo(deviceInfo: CryptoDeviceInfo) = apply {

View file

@ -28,15 +28,15 @@ data class UserPasswordAuth(
// device device session id // device device session id
@Json(name = "session") @Json(name = "session")
var session: String? = null, val session: String? = null,
// registration information // registration information
@Json(name = "type") @Json(name = "type")
var type: String? = LoginFlowTypes.PASSWORD, val type: String? = LoginFlowTypes.PASSWORD,
@Json(name = "user") @Json(name = "user")
var user: String? = null, val user: String? = null,
@Json(name = "password") @Json(name = "password")
var password: String? = null val password: String? = null
) )

View file

@ -35,8 +35,7 @@ internal open class DeviceInfoEntity(@PrimaryKey var primaryKey: String = "",
var signatureMapJson: String? = null, var signatureMapJson: String? = null,
var unsignedMapJson: String? = null, var unsignedMapJson: String? = null,
var trustLevelEntity: TrustLevelEntity? = null var trustLevelEntity: TrustLevelEntity? = null
) ) : RealmObject() {
: RealmObject() {
// // Deserialize data // // Deserialize data
// fun getDeviceInfo(): MXDeviceInfo? { // fun getDeviceInfo(): MXDeviceInfo? {

View file

@ -1,3 +1,19 @@
/*
* Copyright 2020 New Vector Ltd
*
* 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 im.vector.matrix.android.internal.crypto.store.db.model package im.vector.matrix.android.internal.crypto.store.db.model
import io.realm.RealmObject import io.realm.RealmObject
@ -9,5 +25,5 @@ internal open class TrustLevelEntity(
companion object companion object
fun isVerified() : Boolean = crossSignedVerified == true || locallyVerified == true fun isVerified(): Boolean = crossSignedVerified == true || locallyVerified == true
} }

View file

@ -18,8 +18,8 @@ package im.vector.matrix.android.internal.crypto.tasks
import im.vector.matrix.android.internal.auth.data.LoginFlowTypes import im.vector.matrix.android.internal.auth.data.LoginFlowTypes
import im.vector.matrix.android.internal.crypto.api.CryptoApi import im.vector.matrix.android.internal.crypto.api.CryptoApi
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
import im.vector.matrix.android.internal.crypto.model.rest.DeleteDeviceParams import im.vector.matrix.android.internal.crypto.model.rest.DeleteDeviceParams
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
@ -42,16 +42,16 @@ internal class DefaultDeleteDeviceWithUserPasswordTask @Inject constructor(
override suspend fun execute(params: DeleteDeviceWithUserPasswordTask.Params) { override suspend fun execute(params: DeleteDeviceWithUserPasswordTask.Params) {
return executeRequest(eventBus) { return executeRequest(eventBus) {
apiCall = cryptoApi.deleteDevice(params.deviceId, DeleteDeviceParams() apiCall = cryptoApi.deleteDevice(params.deviceId,
.apply { DeleteDeviceParams(
userPasswordAuth = UserPasswordAuth() userPasswordAuth = UserPasswordAuth(
.apply { type = LoginFlowTypes.PASSWORD,
type = LoginFlowTypes.PASSWORD session = params.authSession,
session = params.authSession user = userId,
user = userId
password = params.password password = params.password
} )
}) )
)
} }
} }
} }

View file

@ -35,7 +35,7 @@ import javax.inject.Inject
internal interface RoomVerificationUpdateTask : Task<RoomVerificationUpdateTask.Params, Unit> { internal interface RoomVerificationUpdateTask : Task<RoomVerificationUpdateTask.Params, Unit> {
data class Params( data class Params(
val events: List<Event>, val events: List<Event>,
val sasVerificationService: DefaultVerificationService, val verificationService: DefaultVerificationService,
val cryptoService: CryptoService val cryptoService: CryptoService
) )
} }
@ -104,7 +104,7 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
// The verification is started from another device // The verification is started from another device
Timber.v("## SAS Verification live observer: Transaction started by other device tid:${it.transactionID} ") Timber.v("## SAS Verification live observer: Transaction started by other device tid:${it.transactionID} ")
it.transactionID?.let { txId -> transactionsHandledByOtherDevice.add(txId) } it.transactionID?.let { txId -> transactionsHandledByOtherDevice.add(txId) }
params.sasVerificationService.onRoomRequestHandledByOtherDevice(event) params.verificationService.onRoomRequestHandledByOtherDevice(event)
} }
} }
} else if (EventType.KEY_VERIFICATION_READY == event.type) { } else if (EventType.KEY_VERIFICATION_READY == event.type) {
@ -113,13 +113,13 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
// The verification is started from another device // The verification is started from another device
Timber.v("## SAS Verification live observer: Transaction started by other device tid:${it.transactionID} ") Timber.v("## SAS Verification live observer: Transaction started by other device tid:${it.transactionID} ")
it.transactionID?.let { txId -> transactionsHandledByOtherDevice.add(txId) } it.transactionID?.let { txId -> transactionsHandledByOtherDevice.add(txId) }
params.sasVerificationService.onRoomRequestHandledByOtherDevice(event) params.verificationService.onRoomRequestHandledByOtherDevice(event)
} }
} }
} else if (EventType.KEY_VERIFICATION_CANCEL == event.type || EventType.KEY_VERIFICATION_DONE == event.type) { } else if (EventType.KEY_VERIFICATION_CANCEL == event.type || EventType.KEY_VERIFICATION_DONE == event.type) {
event.getClearContent().toModel<MessageRelationContent>()?.relatesTo?.eventId?.let { event.getClearContent().toModel<MessageRelationContent>()?.relatesTo?.eventId?.let {
transactionsHandledByOtherDevice.remove(it) transactionsHandledByOtherDevice.remove(it)
params.sasVerificationService.onRoomRequestHandledByOtherDevice(event) params.verificationService.onRoomRequestHandledByOtherDevice(event)
} }
} }
@ -141,11 +141,11 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
EventType.KEY_VERIFICATION_CANCEL, EventType.KEY_VERIFICATION_CANCEL,
EventType.KEY_VERIFICATION_READY, EventType.KEY_VERIFICATION_READY,
EventType.KEY_VERIFICATION_DONE -> { EventType.KEY_VERIFICATION_DONE -> {
params.sasVerificationService.onRoomEvent(event) params.verificationService.onRoomEvent(event)
} }
EventType.MESSAGE -> { EventType.MESSAGE -> {
if (MessageType.MSGTYPE_VERIFICATION_REQUEST == event.getClearContent().toModel<MessageContent>()?.type) { if (MessageType.MSGTYPE_VERIFICATION_REQUEST == event.getClearContent().toModel<MessageContent>()?.type) {
params.sasVerificationService.onRoomRequestReceived(event) params.verificationService.onRoomRequestReceived(event)
} }
} }
} }

View file

@ -42,8 +42,9 @@ internal class DefaultSendToDeviceTask @Inject constructor(
) : SendToDeviceTask { ) : SendToDeviceTask {
override suspend fun execute(params: SendToDeviceTask.Params) { override suspend fun execute(params: SendToDeviceTask.Params) {
val sendToDeviceBody = SendToDeviceBody() val sendToDeviceBody = SendToDeviceBody(
sendToDeviceBody.messages = params.contentMap.map messages = params.contentMap.map
)
return executeRequest(eventBus) { return executeRequest(eventBus) {
apiCall = cryptoApi.sendToDevice( apiCall = cryptoApi.sendToDevice(

View file

@ -45,15 +45,10 @@ internal class DefaultUploadKeysTask @Inject constructor(
override suspend fun execute(params: UploadKeysTask.Params): KeysUploadResponse { override suspend fun execute(params: UploadKeysTask.Params): KeysUploadResponse {
val encodedDeviceId = convertToUTF8(params.deviceId) val encodedDeviceId = convertToUTF8(params.deviceId)
val body = KeysUploadBody() val body = KeysUploadBody(
deviceKeys = params.deviceKeys,
if (null != params.deviceKeys) { oneTimeKeys = params.oneTimeKeys
body.deviceKeys = params.deviceKeys )
}
if (null != params.oneTimeKeys) {
body.oneTimeKeys = params.oneTimeKeys
}
return executeRequest(eventBus) { return executeRequest(eventBus) {
apiCall = if (encodedDeviceId.isBlank()) { apiCall = if (encodedDeviceId.isBlank()) {

View file

@ -30,7 +30,8 @@ import im.vector.matrix.android.internal.worker.getSessionComponent
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
internal class SendVerificationMessageWorker constructor(context: Context, params: WorkerParameters) internal class SendVerificationMessageWorker(context: Context,
params: WorkerParameters)
: CoroutineWorker(context, params) { : CoroutineWorker(context, params) {
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)

View file

@ -21,6 +21,15 @@ import im.vector.matrix.android.internal.crypto.model.rest.SendToDeviceObject
interface VerificationInfo { interface VerificationInfo {
fun toEventContent(): Content? = null fun toEventContent(): Content? = null
fun toSendToDeviceObject(): SendToDeviceObject? = null fun toSendToDeviceObject(): SendToDeviceObject? = null
fun isValid() : Boolean fun isValid(): Boolean
/**
* String to identify the transaction.
* This string must be unique for the pair of users performing verification for the duration that the transaction is valid.
* Alices device should record this ID and use it in future messages in this transaction.
*/
val transactionID: String? val transactionID: String?
// TODO Refacto Put the relatesTo here or at least in Message sent in Room parent?
// val relatesTo: RelationDefaultContent?
} }

View file

@ -16,9 +16,6 @@
package im.vector.matrix.android.internal.crypto.verification package im.vector.matrix.android.internal.crypto.verification
internal interface VerificationInfoAccept : VerificationInfo { internal interface VerificationInfoAccept : VerificationInfo {
override val transactionID: String?
/** /**
* The key agreement protocol that Bobs device has selected to use, out of the list proposed by Alices device * The key agreement protocol that Bobs device has selected to use, out of the list proposed by Alices device
*/ */

View file

@ -16,8 +16,6 @@
package im.vector.matrix.android.internal.crypto.verification package im.vector.matrix.android.internal.crypto.verification
internal interface VerificationInfoCancel : VerificationInfo { internal interface VerificationInfoCancel : VerificationInfo {
override val transactionID: String?
/** /**
* machine-readable reason for cancelling, see [CancelCode] * machine-readable reason for cancelling, see [CancelCode]
*/ */

View file

@ -19,8 +19,6 @@ package im.vector.matrix.android.internal.crypto.verification
* Sent by both devices to send their ephemeral Curve25519 public key to the other device. * Sent by both devices to send their ephemeral Curve25519 public key to the other device.
*/ */
internal interface VerificationInfoKey : VerificationInfo { internal interface VerificationInfoKey : VerificationInfo {
override val transactionID: String?
/** /**
* The devices ephemeral public key, as an unpadded base64 string * The devices ephemeral public key, as an unpadded base64 string
*/ */

View file

@ -16,9 +16,6 @@
package im.vector.matrix.android.internal.crypto.verification package im.vector.matrix.android.internal.crypto.verification
internal interface VerificationInfoMac : VerificationInfo { internal interface VerificationInfoMac : VerificationInfo {
override val transactionID: String?
/** /**
* A map of key ID to the MAC of the key, as an unpadded base64 string, calculated using the MAC key * A map of key ID to the MAC of the key, as an unpadded base64 string, calculated using the MAC key
*/ */

View file

@ -22,10 +22,8 @@ package im.vector.matrix.android.internal.crypto.verification
* The m.key.verification.ready event is optional; the recipient of the m.key.verification.request event may respond directly * The m.key.verification.ready event is optional; the recipient of the m.key.verification.request event may respond directly
* with a m.key.verification.start event instead. * with a m.key.verification.start event instead.
*/ */
interface VerificationInfoReady : VerificationInfo { interface VerificationInfoReady : VerificationInfo {
override val transactionID: String?
/** /**
* The ID of the device that sent the m.key.verification.ready message * The ID of the device that sent the m.key.verification.ready message
*/ */

View file

@ -24,13 +24,6 @@ internal interface VerificationInfoStart : VerificationInfo {
*/ */
val fromDevice: String? val fromDevice: String?
/**
* String to identify the transaction.
* This string must be unique for the pair of users performing verification for the duration that the transaction is valid.
* Alices device should record this ID and use it in future messages in this transaction.
*/
override val transactionID: String?
/** /**
* An array of key agreement protocols that Alices client understands. * An array of key agreement protocols that Alices client understands.
* Must include curve25519. * Must include curve25519.

View file

@ -37,7 +37,7 @@ internal class VerificationMessageLiveObserver @Inject constructor(
@SessionDatabase realmConfiguration: RealmConfiguration, @SessionDatabase realmConfiguration: RealmConfiguration,
private val roomVerificationUpdateTask: DefaultRoomVerificationUpdateTask, private val roomVerificationUpdateTask: DefaultRoomVerificationUpdateTask,
private val cryptoService: CryptoService, private val cryptoService: CryptoService,
private val sasVerificationService: DefaultVerificationService, private val verificationService: DefaultVerificationService,
private val taskExecutor: TaskExecutor private val taskExecutor: TaskExecutor
) : RealmLiveEntityObserver<EventEntity>(realmConfiguration) { ) : RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
@ -67,7 +67,7 @@ internal class VerificationMessageLiveObserver @Inject constructor(
.toList() .toList()
roomVerificationUpdateTask.configureWith( roomVerificationUpdateTask.configureWith(
RoomVerificationUpdateTask.Params(events, sasVerificationService, cryptoService) RoomVerificationUpdateTask.Params(events, verificationService, cryptoService)
).executeBy(taskExecutor) ).executeBy(taskExecutor)
} }
} }

View file

@ -32,7 +32,8 @@ import im.vector.matrix.android.internal.worker.getSessionComponent
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import javax.inject.Inject import javax.inject.Inject
internal class SendEventWorker constructor(context: Context, params: WorkerParameters) internal class SendEventWorker(context: Context,
params: WorkerParameters)
: CoroutineWorker(context, params) { : CoroutineWorker(context, params) {
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)

View file

@ -32,7 +32,7 @@ import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
internal class CryptoSyncHandler @Inject constructor(private val cryptoService: DefaultCryptoService, internal class CryptoSyncHandler @Inject constructor(private val cryptoService: DefaultCryptoService,
private val sasVerificationService: DefaultVerificationService) { private val verificationService: DefaultVerificationService) {
fun handleToDevice(toDevice: ToDeviceSyncResponse, initialSyncProgressService: DefaultInitialSyncProgressService? = null) { fun handleToDevice(toDevice: ToDeviceSyncResponse, initialSyncProgressService: DefaultInitialSyncProgressService? = null) {
val total = toDevice.events?.size ?: 0 val total = toDevice.events?.size ?: 0
@ -44,7 +44,7 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService:
&& event.getClearContent()?.toModel<MessageContent>()?.type == "m.bad.encrypted") { && event.getClearContent()?.toModel<MessageContent>()?.type == "m.bad.encrypted") {
Timber.e("## handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}") Timber.e("## handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}")
} else { } else {
sasVerificationService.onToDeviceEvent(event) verificationService.onToDeviceEvent(event)
cryptoService.onToDeviceEvent(event) cryptoService.onToDeviceEvent(event)
} }
} }

View file

@ -90,7 +90,7 @@ class CrossSigningSettingsFragment @Inject constructor(
super.onDestroyView() super.onDestroyView()
} }
fun requestPassword(sessionId: String) { private fun requestPassword(sessionId: String) {
// Ask for password // Ask for password
val inflater = this.layoutInflater val inflater = this.layoutInflater
val layout = inflater.inflate(R.layout.dialog_base_edit_text, null) val layout = inflater.inflate(R.layout.dialog_base_edit_text, null)
@ -105,6 +105,7 @@ class CrossSigningSettingsFragment @Inject constructor(
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.ok) { _, _ ->
val pass = input.text.toString() val pass = input.text.toString()
// TODO sessionId should never get out the ViewModel
viewModel.handle(CrossSigningAction.InitializeCrossSigning(UserPasswordAuth( viewModel.handle(CrossSigningAction.InitializeCrossSigning(UserPasswordAuth(
session = sessionId, session = sessionId,
password = pass password = pass

View file

@ -89,7 +89,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted privat
override fun handle(action: CrossSigningAction) { override fun handle(action: CrossSigningAction) {
when (action) { when (action) {
is CrossSigningAction.InitializeCrossSigning -> { is CrossSigningAction.InitializeCrossSigning -> {
initializeCrossSigning(action.auth?.also { it.user = session.myUserId }) initializeCrossSigning(action.auth?.copy(user = session.myUserId))
} }
} }
} }

View file

@ -1500,7 +1500,7 @@ Why choose Riot.im?
<string name="sas_verified">Verified!</string> <string name="sas_verified">Verified!</string>
<string name="sas_verified_successful">You\'ve successfully verified this device.</string> <string name="sas_verified_successful">You\'ve successfully verified this device.</string>
<string name="sas_verified_successful_description">Messages with this user in this room are end-to-end encrypted and cant be read by third parties.</string> <string name="sas_verified_successful_description">Messages with this user in this room are end-to-end encrypted and can\'t be read by third parties.</string>
<string name="sas_got_it">Got it</string> <string name="sas_got_it">Got it</string>
<string name="sas_verifying_keys">Nothing appearing? Not all clients supports interactive verification yet. Use legacy verification.</string> <string name="sas_verifying_keys">Nothing appearing? Not all clients supports interactive verification yet. Use legacy verification.</string>
@ -1694,7 +1694,6 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
<string name="room_directory_search_hint">Name or ID (#example:matrix.org)</string> <string name="room_directory_search_hint">Name or ID (#example:matrix.org)</string>
<string name="labs_swipe_to_reply_in_timeline">Enable swipe to reply in timeline</string> <string name="labs_swipe_to_reply_in_timeline">Enable swipe to reply in timeline</string>
<string name="labs_enable_verification_other_dm">Enable verification other DM</string>
<string name="link_copied_to_clipboard">Link copied to clipboard</string> <string name="link_copied_to_clipboard">Link copied to clipboard</string>