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.launch
import kotlinx.coroutines.runBlocking
import org.junit.Assert.*
import java.util.*
import org.junit.Assert.assertEquals
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.TimeUnit
@ -280,7 +283,7 @@ class CommonTestHelper(context: Context) {
fun signout(session: Session) {
val lock = CountDownLatch(1)
session.signOut(true, object : TestMatrixCallback<Unit>(lock) {})
session.signOut(true, TestMatrixCallback(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.rest.UserPasswordAuth
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
@ -73,14 +74,12 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD
)
val aliceLatch = CountDownLatch(1)
val bobLatch = CountDownLatch(1)
val latch = CountDownLatch(2)
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(aliceLatch))
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(bobLatch))
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
mTestHelper.await(aliceLatch)
mTestHelper.await(bobLatch)
mTestHelper.await(latch)
// Check that alice can see bob keys
val downloadLatch = CountDownLatch(1)
@ -88,14 +87,14 @@ class XSigningTest : InstrumentedTest {
mTestHelper.await(downloadLatch)
val bobKeysFromAlicePOV = aliceSession.getCrossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV?.masterKey())
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV?.userKey())
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV?.selfSigningKey())
assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey())
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
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?.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.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)
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(bobSession)
@ -117,14 +116,12 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD
)
val aliceLatch = CountDownLatch(1)
val bobLatch = CountDownLatch(1)
val latch = CountDownLatch(2)
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(aliceLatch))
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(bobLatch))
aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
mTestHelper.await(aliceLatch)
mTestHelper.await(bobLatch)
mTestHelper.await(latch)
// Check that alice can see bob keys
val downloadLatch = CountDownLatch(1)

View file

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

View file

@ -47,7 +47,6 @@ import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import java.util.ArrayList
import java.util.concurrent.CountDownLatch
@RunWith(AndroidJUnit4::class)
@ -78,7 +77,10 @@ class SASTest : InstrumentedTest {
}
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)
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
@ -325,7 +327,7 @@ class SASTest : InstrumentedTest {
val aliceCreatedLatch = CountDownLatch(2)
val aliceCancelledLatch = CountDownLatch(2)
val createdTx = ArrayList<SASDefaultVerificationTransaction>()
val createdTx = mutableListOf<SASDefaultVerificationTransaction>()
val aliceListener = object : VerificationService.VerificationListener {
override fun transactionCreated(tx: VerificationTransaction) {
createdTx.add(tx as SASDefaultVerificationTransaction)
@ -344,8 +346,8 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession!!.myUserId
val bobDeviceId = bobSession.getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId)
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId)
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceCreatedLatch)
mTestHelper.await(aliceCancelledLatch)
@ -402,7 +404,7 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession.myUserId
val bobDeviceId = bobSession.getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId)
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceAcceptedLatch)
assertTrue("Should have receive a commitment", accepted!!.commitment?.trim()?.isEmpty() == false)
@ -471,7 +473,7 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession.myUserId
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(bobSASLatch)
@ -541,7 +543,7 @@ class SASTest : InstrumentedTest {
val bobUserId = bobSession.myUserId
val bobDeviceId = bobSession.getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId)
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceSASLatch)
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
data class MXCrossSigningInfo(
var userId: String,
var crossSigningKeys: List<CryptoCrossSigningKey> = ArrayList()
val userId: String,
val crossSigningKeys: List<CryptoCrossSigningKey>
) {
fun isTrusted() : Boolean = masterKey()?.trustLevel?.isVerified() == true
fun isTrusted(): Boolean = masterKey()?.trustLevel?.isVerified() == true
&& selfSigningKey()?.trustLevel?.isVerified() == true
fun masterKey(): CryptoCrossSigningKey? = crossSigningKeys

View file

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

View file

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

View file

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

View file

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

View file

@ -15,8 +15,10 @@
*/
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 isCrossSigningVerified() = crossSigningVerified
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
sealed class DeviceTrustResult {
data class Success(val level: DeviceTrustLevel) : DeviceTrustResult()
data class UnknownDevice(val deviceID: 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()
}
fun DeviceTrustResult.isSuccess(): Boolean = this is DeviceTrustResult.Success
fun DeviceTrustResult.isCrossSignedVerified(): Boolean = (this as? DeviceTrustResult.Success)?.level?.isCrossSigningVerified() == true
fun DeviceTrustResult.isLocallyVerified(): Boolean = (this as? DeviceTrustResult.Success)?.level?.isLocallyVerified() == true
fun DeviceTrustResult.isSuccess() = this is DeviceTrustResult.Success
fun DeviceTrustResult.isCrossSignedVerified() = this is DeviceTrustResult.Success && level.isCrossSigningVerified()
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
* limitations under the License.
*/
package im.vector.matrix.android.internal.crypto.crosssigning
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
sealed class UserTrustResult {
object Success : UserTrustResult()
// data class Success(val deviceID: String, val crossSigned: Boolean) : UserTrustResult()
//
// data class UnknownDevice(val deviceID: String) : UserTrustResult()
// data class Success(val deviceID: String, val crossSigned: Boolean) : UserTrustResult()
// data class UnknownDevice(val deviceID: String) : UserTrustResult()
data class CrossSigningNotConfigured(val userID: String) : UserTrustResult()
data class UnknownCrossSignatureInfo(val userID: String) : UserTrustResult()
data class KeysNotTrusted(val key: MXCrossSigningInfo) : 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
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
@ -87,6 +103,6 @@ enum class KeyUsage(val value: String) {
USER_SIGNING("user_signing")
}
fun CryptoCrossSigningKey.toRest(): RestKeyInfo {
internal fun CryptoCrossSigningKey.toRest(): RestKeyInfo {
return CryptoInfoMapper.map(this)
}

View file

@ -29,15 +29,12 @@ data class CryptoDeviceInfo(
override val signatures: Map<String, Map<String, String>>? = null,
val unsigned: JsonDict? = null,
// 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)
// 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)
var trustLevel: DeviceTrustLevel? = null,
var isBlocked: Boolean = false
)
: CryptoInfo {
) : CryptoInfo {
val isVerified: Boolean
get() = trustLevel?.isVerified() ?: false
@ -93,7 +90,7 @@ data class CryptoDeviceInfo(
// }
}
fun CryptoDeviceInfo.toRest(): RestDeviceInfo {
internal fun CryptoDeviceInfo.toRest(): RestDeviceInfo {
return CryptoInfoMapper.map(this)
}

View file

@ -15,14 +15,10 @@
*/
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.RestKeyInfo
import im.vector.matrix.android.internal.di.SerializeNulls
object CryptoInfoMapper {
private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
internal object CryptoInfoMapper {
fun map(restDeviceInfo: RestDeviceInfo): CryptoDeviceInfo {
return CryptoDeviceInfo(

View file

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

View file

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

View file

@ -22,7 +22,7 @@ import com.squareup.moshi.JsonClass
* This class describes the key changes response
*/
@JsonClass(generateAdapter = true)
data class KeyChangesResponse(
internal data class KeyChangesResponse(
// list of user ids which have new devices
@Json(name = "changed")
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.
*/
@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
*/
@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
*/
@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
*/
@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
*/
@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)
@ -89,14 +89,14 @@ internal data class KeyVerificationAccept(
commitment: String,
messageAuthenticationCode: String,
shortAuthenticationStrings: List<String>): VerificationInfoAccept {
return KeyVerificationAccept().apply {
this.transactionID = tid
this.keyAgreementProtocol = keyAgreementProtocol
this.hash = hash
this.commitment = commitment
this.messageAuthenticationCode = messageAuthenticationCode
this.shortAuthenticationStrings = shortAuthenticationStrings
}
return KeyVerificationAccept(
transactionID = tid,
keyAgreementProtocol = keyAgreementProtocol,
hash = hash,
commitment = commitment,
messageAuthenticationCode = messageAuthenticationCode,
shortAuthenticationStrings = shortAuthenticationStrings
)
}
}
}

View file

@ -34,12 +34,12 @@ internal data class KeyVerificationCancel(
/**
* 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.
*/
override var reason: String? = null
override val reason: String? = null
) : SendToDeviceObject, VerificationInfoCancel {
companion object {

View file

@ -28,7 +28,7 @@ internal data class KeyVerificationKey(
/**
* 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

View file

@ -26,7 +26,7 @@ import im.vector.matrix.android.internal.crypto.verification.VerificationInfoRea
internal data class KeyVerificationReady(
@Json(name = "from_device") override val fromDevice: 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 {
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.
*/
@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.

View file

@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass
* This class represents the response to /keys/claim request made by claimOneTimeKeysForUsersDevices.
*/
@JsonClass(generateAdapter = true)
data class KeysClaimResponse(
internal data class KeysClaimResponse(
/**
* 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
*/
@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.

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.
*/
@JsonClass(generateAdapter = true)
data class KeysQueryResponse(
internal data class KeysQueryResponse(
/**
* The device keys per devices per users.
* Map from userId to map from deviceId to MXDeviceInfo
* TODO Use MXUsersDevicesMap?
*/
@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 ?
* TODO Use MXUsersDevicesMap?
*/
var failures: Map<String, Map<String, Any>>? = null,
val failures: Map<String, Map<String, Any>>? = null,
@Json(name = "master_keys")
var masterKeys: Map<String, RestKeyInfo?>? = null,
val masterKeys: Map<String, RestKeyInfo?>? = null,
@Json(name = "self_signing_keys")
var selfSigningKeys: Map<String, RestKeyInfo?>? = null,
val selfSigningKeys: Map<String, RestKeyInfo?>? = null,
@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
@JsonClass(generateAdapter = true)
data class KeysUploadBody(
internal data class KeysUploadBody(
@Json(name = "device_keys")
var deviceKeys: RestDeviceInfo? = null,
val deviceKeys: RestDeviceInfo? = null,
@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.
*/
@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).

View file

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

View file

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

View file

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

View file

@ -16,13 +16,12 @@
package im.vector.matrix.android.internal.crypto.model.rest
class SendToDeviceBody {
/**
* `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 device ID may also be *, meaning all known devices for the user.
*/
var messages: Map<String, Map<String, Any>>? = null
}
internal data class SendToDeviceBody(
/**
* `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 device ID may also be *, meaning all known devices for the user.
*/
val messages: Map<String, Map<String, Any>>?
)

View file

@ -24,8 +24,7 @@ import com.squareup.moshi.JsonClass
* Upload Signature response
*/
@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,
* 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
* 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(
@Json(name = "status")
val status: Int,
@Json(name = "errCode")
val errCode: String,
@Json(name = "message")
val message: String
)

View file

@ -20,12 +20,10 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@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.
*/
@Json(name = "display_name")
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
*/
data class UploadSignatureQueryBuilder(
private val deviceInfoList: ArrayList<CryptoDeviceInfo> = ArrayList(),
private val signingKeyInfoList: ArrayList<CryptoCrossSigningKey> = ArrayList()
internal data class UploadSignatureQueryBuilder(
private val deviceInfoList: MutableList<CryptoDeviceInfo> = mutableListOf(),
private val signingKeyInfoList: MutableList<CryptoCrossSigningKey> = mutableListOf()
) {
fun withDeviceInfo(deviceInfo: CryptoDeviceInfo) = apply {

View file

@ -28,15 +28,15 @@ data class UserPasswordAuth(
// device device session id
@Json(name = "session")
var session: String? = null,
val session: String? = null,
// registration information
@Json(name = "type")
var type: String? = LoginFlowTypes.PASSWORD,
val type: String? = LoginFlowTypes.PASSWORD,
@Json(name = "user")
var user: String? = null,
val user: String? = null,
@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 unsignedMapJson: String? = null,
var trustLevelEntity: TrustLevelEntity? = null
)
: RealmObject() {
) : RealmObject() {
// // Deserialize data
// 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
import io.realm.RealmObject
@ -9,5 +25,5 @@ internal open class TrustLevelEntity(
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.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.UserPasswordAuth
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
@ -42,16 +42,16 @@ internal class DefaultDeleteDeviceWithUserPasswordTask @Inject constructor(
override suspend fun execute(params: DeleteDeviceWithUserPasswordTask.Params) {
return executeRequest(eventBus) {
apiCall = cryptoApi.deleteDevice(params.deviceId, DeleteDeviceParams()
.apply {
userPasswordAuth = UserPasswordAuth()
.apply {
type = LoginFlowTypes.PASSWORD
session = params.authSession
user = userId
apiCall = cryptoApi.deleteDevice(params.deviceId,
DeleteDeviceParams(
userPasswordAuth = UserPasswordAuth(
type = LoginFlowTypes.PASSWORD,
session = params.authSession,
user = userId,
password = params.password
}
})
)
)
)
}
}
}

View file

@ -35,7 +35,7 @@ import javax.inject.Inject
internal interface RoomVerificationUpdateTask : Task<RoomVerificationUpdateTask.Params, Unit> {
data class Params(
val events: List<Event>,
val sasVerificationService: DefaultVerificationService,
val verificationService: DefaultVerificationService,
val cryptoService: CryptoService
)
}
@ -104,7 +104,7 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
// The verification is started from another device
Timber.v("## SAS Verification live observer: Transaction started by other device tid:${it.transactionID} ")
it.transactionID?.let { txId -> transactionsHandledByOtherDevice.add(txId) }
params.sasVerificationService.onRoomRequestHandledByOtherDevice(event)
params.verificationService.onRoomRequestHandledByOtherDevice(event)
}
}
} else if (EventType.KEY_VERIFICATION_READY == event.type) {
@ -113,13 +113,13 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
// The verification is started from another device
Timber.v("## SAS Verification live observer: Transaction started by other device tid:${it.transactionID} ")
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) {
event.getClearContent().toModel<MessageRelationContent>()?.relatesTo?.eventId?.let {
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_READY,
EventType.KEY_VERIFICATION_DONE -> {
params.sasVerificationService.onRoomEvent(event)
params.verificationService.onRoomEvent(event)
}
EventType.MESSAGE -> {
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 {
override suspend fun execute(params: SendToDeviceTask.Params) {
val sendToDeviceBody = SendToDeviceBody()
sendToDeviceBody.messages = params.contentMap.map
val sendToDeviceBody = SendToDeviceBody(
messages = params.contentMap.map
)
return executeRequest(eventBus) {
apiCall = cryptoApi.sendToDevice(

View file

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

View file

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

View file

@ -21,6 +21,15 @@ import im.vector.matrix.android.internal.crypto.model.rest.SendToDeviceObject
interface VerificationInfo {
fun toEventContent(): Content? = 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?
// 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
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
*/

View file

@ -16,8 +16,6 @@
package im.vector.matrix.android.internal.crypto.verification
internal interface VerificationInfoCancel : VerificationInfo {
override val transactionID: String?
/**
* 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.
*/
internal interface VerificationInfoKey : VerificationInfo {
override val transactionID: 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
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
*/

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
* with a m.key.verification.start event instead.
*/
interface VerificationInfoReady : VerificationInfo {
override val transactionID: String?
/**
* 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?
/**
* 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.
* Must include curve25519.

View file

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

View file

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

View file

@ -32,7 +32,7 @@ import timber.log.Timber
import javax.inject.Inject
internal class CryptoSyncHandler @Inject constructor(private val cryptoService: DefaultCryptoService,
private val sasVerificationService: DefaultVerificationService) {
private val verificationService: DefaultVerificationService) {
fun handleToDevice(toDevice: ToDeviceSyncResponse, initialSyncProgressService: DefaultInitialSyncProgressService? = null) {
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") {
Timber.e("## handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}")
} else {
sasVerificationService.onToDeviceEvent(event)
verificationService.onToDeviceEvent(event)
cryptoService.onToDeviceEvent(event)
}
}

View file

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

View file

@ -89,7 +89,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted privat
override fun handle(action: CrossSigningAction) {
when (action) {
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_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_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="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>