Quick Fix todevice verif broken

Added dbg screen for cross signing
This commit is contained in:
Valere 2020-01-21 14:57:37 +01:00
parent a6364f0be5
commit a0aa1f34d3
18 changed files with 134 additions and 56 deletions

View File

@ -47,7 +47,6 @@ class XSigningTest : InstrumentedTest {
assertTrue("Signing Keys should be trusted", aliceSession.getCrossSigningService().checkUserTrust(aliceSession.myUserId).isVerified())
mTestHelper.signout(aliceSession)
}

View File

@ -41,6 +41,7 @@ interface CrossSigningService {
fun getUserCrossSigningKeys(userId: String): MXCrossSigningInfo?
fun getMyCrossSigningKeys(): MXCrossSigningInfo?
fun canCrossSign(): Boolean
fun trustUser(userId: String, callback: MatrixCallback<SignatureUploadResponse>)

View File

@ -49,4 +49,6 @@ interface SasVerificationTransaction {
fun userHasVerifiedShortCode()
fun shortCodeDoesNotMatch()
fun isToDeviceTransport() : Boolean
}

View File

@ -450,6 +450,10 @@ internal class DefaultCrossSigningService @Inject constructor(
return cryptoStore.getMyCrossSigningInfo()
}
override fun canCrossSign(): Boolean {
return checkSelfTrust().isVerified() && cryptoStore.getCrossSigningPrivateKeys()?.selfSigned != null
}
override fun trustUser(userId: String, callback: MatrixCallback<SignatureUploadResponse>) {
// We should have this user keys
val otherMasterKeys = getUserCrossSigningKeys(userId)?.masterKey()

View File

@ -16,7 +16,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.user.model.User
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
sealed class UserTrustResult {

View File

@ -43,6 +43,8 @@ internal data class KeyVerificationKey(
}
}
override fun toSendToDeviceObject() = this
override fun isValid(): Boolean {
if (transactionID.isNullOrBlank() || key.isNullOrBlank()) {
return false

View File

@ -27,7 +27,7 @@ import im.vector.matrix.android.internal.crypto.verification.VerificationInfoMac
internal data class KeyVerificationMac(
@Json(name = "transaction_id") override val transactionID: String? = null,
@Json(name = "mac") override val mac: Map<String, String>? = null,
@Json(name = "key") override val keys: String? = null
@Json(name = "keys") override val keys: String? = null
) : SendToDeviceObject, VerificationInfoMac {

View File

@ -50,9 +50,9 @@ internal object RealmCryptoStoreMigration : RealmMigration {
val trustLevelentityEntitySchema = realm.schema.create("TrustLevelEntity")
.addField(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, Boolean::class.java)
.setNullable(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED,true)
.setNullable(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, true)
.addField(TrustLevelEntityFields.LOCALLY_VERIFIED, Boolean::class.java)
.setNullable(TrustLevelEntityFields.LOCALLY_VERIFIED,true)
.setNullable(TrustLevelEntityFields.LOCALLY_VERIFIED, true)
Timber.d("Create CrossSigningInfoEntity")
@ -91,8 +91,8 @@ internal object RealmCryptoStoreMigration : RealmMigration {
?.addField(DeviceInfoEntityFields.SIGNATURE_MAP_JSON, String::class.java)
?.addField(DeviceInfoEntityFields.UNSIGNED_MAP_JSON, String::class.java)
?.addField(DeviceInfoEntityFields.IS_BLOCKED, Boolean::class.java)
?.setNullable(DeviceInfoEntityFields.IS_BLOCKED,true)
?.addRealmObjectField(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`,trustLevelentityEntitySchema)
?.setNullable(DeviceInfoEntityFields.IS_BLOCKED, true)
?.addRealmObjectField(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevelentityEntitySchema)
?.transform { obj ->
val oldSerializedData = obj.getString("deviceInfoData")

View File

@ -204,6 +204,10 @@ internal abstract class SASVerificationTransaction(
cancel(CancelCode.MismatchedSas)
}
override fun isToDeviceTransport() : Boolean {
return transport is SasTransportToDevice
}
override fun acceptVerificationEvent(senderId: String, info: VerificationInfo) {
when (info) {
is VerificationInfoStart -> onVerificationStart(info)

View File

@ -51,48 +51,46 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context
override fun transactionCreated(tx: SasVerificationTransaction) {}
override fun transactionUpdated(tx: SasVerificationTransaction) {
if (!tx.isToDeviceTransport()) return
// TODO maybe check also if
when (tx.state) {
SasVerificationTxState.OnStarted -> {
// // Add a notification for every incoming request
// val name = session?.getUser(tx.otherUserId)?.displayName
// ?: tx.otherUserId
//
// val alert = PopupAlertManager.VectorAlert(
// "kvr_${tx.transactionId}",
// context.getString(R.string.sas_incoming_request_notif_title),
// context.getString(R.string.sas_incoming_request_notif_content, name),
// R.drawable.shield)
// .apply {
// contentAction = Runnable {
// val intent = SASVerificationActivity.incomingIntent(context,
// session?.myUserId ?: "",
// tx.otherUserId,
// tx.transactionId)
// weakCurrentActivity?.get()?.startActivity(intent)
// }
// dismissedAction = Runnable {
// tx.cancel()
// }
// addButton(
// context.getString(R.string.ignore),
// Runnable {
// tx.cancel()
// }
// )
// addButton(
// context.getString(R.string.action_open),
// Runnable {
// val intent = SASVerificationActivity.incomingIntent(context,
// session?.myUserId ?: "",
// tx.otherUserId,
// tx.transactionId)
// weakCurrentActivity?.get()?.startActivity(intent)
// }
// )
// // 10mn expiration
// expirationTimestamp = System.currentTimeMillis() + (10 * 60 * 1000L)
// }
// PopupAlertManager.postVectorAlert(alert)
// Add a notification for every incoming request
val name = session?.getUser(tx.otherUserId)?.displayName
?: tx.otherUserId
val alert = PopupAlertManager.VectorAlert(
"kvr_${tx.transactionId}",
context.getString(R.string.sas_incoming_request_notif_title),
context.getString(R.string.sas_incoming_request_notif_content, name),
R.drawable.shield)
.apply {
contentAction = Runnable {
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
it.navigator.performDeviceVerification(it, tx.otherUserId, tx.transactionId)
}
}
dismissedAction = Runnable {
tx.cancel()
}
addButton(
context.getString(R.string.ignore),
Runnable {
tx.cancel()
}
)
addButton(
context.getString(R.string.action_open),
Runnable {
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
it.navigator.performDeviceVerification(it, tx.otherUserId, tx.transactionId)
}
}
)
// 10mn expiration
expirationTimestamp = System.currentTimeMillis() + (10 * 60 * 1000L)
}
PopupAlertManager.postVectorAlert(alert)
}
SasVerificationTxState.Cancelled,
SasVerificationTxState.OnCancelled,

View File

@ -131,7 +131,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
showFragment(VerificationEmojiCodeFragment::class, Bundle().apply {
putParcelable(MvRx.KEY_ARG, VerificationArgs(
it.otherUserMxItem?.id ?: "",
it.pendingRequest?.transactionId))
it.transactionId))
})
}
SasVerificationTxState.Verified,
@ -204,7 +204,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
}
companion object {
fun withArgs(roomId: String, otherUserId: String, transactionId: String? = null): VerificationBottomSheet {
fun withArgs(roomId: String?, otherUserId: String, transactionId: String? = null): VerificationBottomSheet {
return VerificationBottomSheet().apply {
arguments = Bundle().apply {
putParcelable(MvRx.KEY_ARG, VerificationBottomSheet.VerificationArgs(

View File

@ -35,6 +35,7 @@ data class VerificationBottomSheetViewState(
val roomId: String? = null,
val pendingRequest: PendingVerificationRequest? = null,
val sasTransactionState: SasVerificationTxState? = null,
val transactionId: String? = null,
val cancelCode: CancelCode? = null
) : MvRxState
@ -82,13 +83,14 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
val pr = session.getSasVerificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
val sasTx = pr?.transactionId?.let {
val sasTx = (pr?.transactionId ?: args.verificationId)?.let {
session.getSasVerificationService().getExistingTransaction(args.otherUserId, it)
}
return fragment.verificationViewModelFactory.create(VerificationBottomSheetViewState(
otherUserMxItem = userItem?.toMatrixItem(),
sasTransactionState = sasTx?.state,
transactionId = args.verificationId,
pendingRequest = pr,
roomId = args.roomId)
)
@ -99,10 +101,9 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
val otherUserId = state.otherUserMxItem?.id ?: return@withState
val roomId = state.roomId
?: session.getExistingDirectRoomWithUser(otherUserId)?.roomId
?: return@withState
when (action) {
is VerificationAction.RequestVerificationByDM -> {
// session
if (roomId == null) return@withState
setState {
copy(pendingRequest = session.getSasVerificationService().requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, roomId))
}
@ -110,7 +111,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
is VerificationAction.StartSASVerification -> {
val request = session.getSasVerificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
?: return@withState
if (roomId == null) return@withState
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
session.getSasVerificationService().beginKeyVerificationInDMs(
VerificationMethod.SAS,
@ -142,7 +143,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
}
override fun transactionUpdated(tx: SasVerificationTransaction) = withState { state ->
if (tx.transactionId == state.pendingRequest?.transactionId) {
if (tx.transactionId == (state.pendingRequest?.transactionId ?: state.transactionId)) {
// A SAS tx has been started following this request
setState {
copy(

View File

@ -20,6 +20,7 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.core.app.TaskStackBuilder
import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder
@ -29,6 +30,7 @@ import im.vector.riotx.core.utils.toast
import im.vector.riotx.features.createdirect.CreateDirectRoomActivity
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity
import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
import im.vector.riotx.features.debug.DebugMenuActivity
import im.vector.riotx.features.home.room.detail.RoomDetailActivity
import im.vector.riotx.features.home.room.detail.RoomDetailArgs
@ -61,6 +63,18 @@ class DefaultNavigator @Inject constructor(
startActivity(context, intent, buildTask)
}
override fun performDeviceVerification(context: Context, otherUserId: String, sasTransationId: String) {
val session = sessionHolder.getSafeActiveSession() ?: return
val tx = session.getSasVerificationService().getExistingTransaction(otherUserId, sasTransationId) ?: return
(tx as? IncomingSasVerificationTransaction)?.performAccept()
if (context is VectorBaseActivity) {
VerificationBottomSheet.withArgs(
roomId = null,
otherUserId = otherUserId,
transactionId = sasTransationId
).show(context.supportFragmentManager, "REQPOP")
}
}
override fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String?, buildTask: Boolean) {
if (context is VectorBaseActivity) {
context.notImplemented("Open not joined room")

View File

@ -26,6 +26,8 @@ interface Navigator {
fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false)
fun performDeviceVerification(context: Context, otherUserId: String, sasTransationId: String)
fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData)
fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String? = null, buildTask: Boolean = false)

View File

@ -67,6 +67,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
const val SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY = "SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY"
const val SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY = "SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY"
const val SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY"
const val SETTINGS_ENCRYPTION_CROSS_SIGNING_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_CROSS_SIGNING_PREFERENCE_KEY"
const val SETTINGS_ENCRYPTION_INFORMATION_DEVICE_ID_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_INFORMATION_DEVICE_ID_PREFERENCE_KEY"
const val SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
const val SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"

View File

@ -29,6 +29,7 @@ import androidx.preference.SwitchPreference
import com.google.android.material.textfield.TextInputEditText
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.extensions.getFingerprintHumanReadable
import im.vector.matrix.android.internal.crypto.crosssigning.isVerified
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.riotx.R
@ -38,7 +39,13 @@ import im.vector.riotx.core.intent.analyseIntent
import im.vector.riotx.core.intent.getFilenameFromUri
import im.vector.riotx.core.platform.SimpleTextWatcher
import im.vector.riotx.core.preference.VectorPreference
import im.vector.riotx.core.utils.*
import im.vector.riotx.core.utils.PERMISSIONS_FOR_WRITING_FILES
import im.vector.riotx.core.utils.PERMISSION_REQUEST_CODE_EXPORT_KEYS
import im.vector.riotx.core.utils.allGranted
import im.vector.riotx.core.utils.checkPermissions
import im.vector.riotx.core.utils.copyToClipboard
import im.vector.riotx.core.utils.openFileSelection
import im.vector.riotx.core.utils.toast
import im.vector.riotx.features.crypto.keys.KeysExporter
import im.vector.riotx.features.crypto.keys.KeysImporter
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
@ -68,6 +75,11 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
private val mPushersSettingsCategory by lazy {
findPreference<PreferenceCategory>(VectorPreferences.SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY)!!
}
private val mCrossSigningStatePreference by lazy {
findPreference<VectorPreference>(VectorPreferences.SETTINGS_ENCRYPTION_CROSS_SIGNING_PREFERENCE_KEY)!!
}
private val cryptoInfoDeviceNamePreference by lazy {
findPreference<VectorPreference>(VectorPreferences.SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY)!!
}
@ -121,6 +133,31 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
true
}
}
if (vectorPreferences.developerMode()) {
val crossSigningKeys = session.getCrossSigningService().getMyCrossSigningKeys()
val xSigningIsEnableInAccount = crossSigningKeys != null
val xSigningCaseAreTrusted = session.getCrossSigningService().checkUserTrust(session.myUserId).isVerified()
val xSigningKeyCanSign = session.getCrossSigningService().canCrossSign()
if (xSigningKeyCanSign) {
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_trusted)
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_complete)
} else if (xSigningCaseAreTrusted) {
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_warning)
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_trusted)
} else if (xSigningIsEnableInAccount) {
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_black)
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_not_trusted)
} else {
mCrossSigningStatePreference.setIcon(android.R.color.transparent)
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_disabled)
}
mCrossSigningStatePreference.isVisible = true
} else {
mCrossSigningStatePreference.isVisible = false
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {

View File

@ -95,4 +95,11 @@
<string name="verification_code_notice">Compare the code with the one displayed on the other user\'s screen.</string>
<string name="verification_conclusion_ok_notice">Messages with this user are end-to-end encrypted and can\'t be read by third parties.</string>
<string name="encryption_information_cross_signing_state">Cross-Signing</string>
<string name="encryption_information_dg_xsigning_complete">Cross-Signing is enabled\nPrivate Keys on device.</string>
<string name="encryption_information_dg_xsigning_trusted">Cross-Signing is enabled\nKeys are trusted\n.Private keys are not known</string>
<string name="encryption_information_dg_xsigning_not_trusted">Cross-Signing is enabled\nKeys are not trusted</string>
<string name="encryption_information_dg_xsigning_disabled">Cross-Signing is not enabled</string>
</resources>

View File

@ -1,11 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<!-- ************ Cryptography section ************ -->
<im.vector.riotx.core.preference.VectorPreferenceCategory
android:key="SETTINGS_CRYPTOGRAPHY_PREFERENCE_KEY"
android:title="@string/settings_cryptography">
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_CROSS_SIGNING_PREFERENCE_KEY"
tools:icon="@drawable/ic_shield_trusted"
android:persistent="false"
android:title="@string/encryption_information_cross_signing_state" />
<im.vector.riotx.core.preference.VectorPreference
android:key="SETTINGS_ENCRYPTION_INFORMATION_DEVICE_NAME_PREFERENCE_KEY"