SAS Tested

This commit is contained in:
Benoit Marty 2019-05-16 17:28:51 +02:00
parent e70fd8e351
commit 102bc9c01b
9 changed files with 31 additions and 29 deletions

View File

@ -61,7 +61,7 @@ internal class MXOlmDevice(
// They are not stored in 'store' to avoid to remember to which devices we sent the session key. // They are not stored in 'store' to avoid to remember to which devices we sent the session key.
// Plus, in cryptography, it is good to refresh sessions from time to time. // Plus, in cryptography, it is good to refresh sessions from time to time.
// The key is the session id, the value the outbound group session. // The key is the session id, the value the outbound group session.
private val mOutboundGroupSessionStore: MutableMap<String, OlmOutboundGroupSession> private val mOutboundGroupSessionStore: MutableMap<String, OlmOutboundGroupSession> = HashMap()


// Store a set of decrypted message indexes for each group session. // Store a set of decrypted message indexes for each group session.
// This partially mitigates a replay attack where a MITM resends a group // This partially mitigates a replay attack where a MITM resends a group
@ -75,7 +75,7 @@ internal class MXOlmDevice(
// The first level keys are timeline ids. // The first level keys are timeline ids.
// The second level keys are strings of form "<senderKey>|<session_id>|<message_index>" // The second level keys are strings of form "<senderKey>|<session_id>|<message_index>"
// Values are true. // Values are true.
private val mInboundGroupSessionMessageIndexes: MutableMap<String, MutableMap<String, Boolean>> private val mInboundGroupSessionMessageIndexes: MutableMap<String, MutableMap<String, Boolean>> = HashMap()


/** /**
* inboundGroupSessionWithId error * inboundGroupSessionWithId error
@ -107,8 +107,6 @@ internal class MXOlmDevice(
mOlmUtility = null mOlmUtility = null
} }


mOutboundGroupSessionStore = HashMap()

try { try {
deviceCurve25519Key = mOlmAccount!!.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY] deviceCurve25519Key = mOlmAccount!!.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY]
} catch (e: Exception) { } catch (e: Exception) {
@ -120,8 +118,6 @@ internal class MXOlmDevice(
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## MXOlmDevice : cannot find " + OlmAccount.JSON_KEY_FINGER_PRINT_KEY + " with error") Timber.e(e, "## MXOlmDevice : cannot find " + OlmAccount.JSON_KEY_FINGER_PRINT_KEY + " with error")
} }

mInboundGroupSessionMessageIndexes = HashMap()
} }


/** /**

View File

@ -16,6 +16,7 @@
package im.vector.matrix.android.internal.crypto.model.rest package im.vector.matrix.android.internal.crypto.model.rest


import com.squareup.moshi.Json import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.session.crypto.sas.SasMode import im.vector.matrix.android.api.session.crypto.sas.SasMode
import im.vector.matrix.android.internal.crypto.verification.SASVerificationTransaction import im.vector.matrix.android.internal.crypto.verification.SASVerificationTransaction
import timber.log.Timber import timber.log.Timber
@ -23,6 +24,7 @@ import timber.log.Timber
/** /**
* Sent by Alice to initiate an interactive key verification. * Sent by Alice to initiate an interactive key verification.
*/ */
@JsonClass(generateAdapter = true)
class KeyVerificationStart : SendToDeviceObject { class KeyVerificationStart : SendToDeviceObject {


/** /**

View File

@ -59,7 +59,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia


// Event received from the sync // Event received from the sync
fun onToDeviceEvent(event: Event) { fun onToDeviceEvent(event: Event) {
CryptoAsyncHelper.getDecryptBackgroundHandler().post { CryptoAsyncHelper.getDecryptBackgroundHandler().post { // TODO We are already in a BG thread
when (event.type) { when (event.type) {
EventType.KEY_VERIFICATION_START -> { EventType.KEY_VERIFICATION_START -> {
onStartRequestReceived(event) onStartRequestReceived(event)
@ -226,10 +226,10 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia
} }
} }


override fun onSuccess(info: MXUsersDevicesMap<MXDeviceInfo>) { override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
CryptoAsyncHelper.getDecryptBackgroundHandler().post { CryptoAsyncHelper.getDecryptBackgroundHandler().post {
if (info.getUserDeviceIds(otherUserId).contains(startReq.fromDevice)) { if (data.getUserDeviceIds(otherUserId).contains(startReq.fromDevice)) {
success(info) success(data)
} else { } else {
error() error()
} }

View File

@ -38,8 +38,9 @@ internal class IncomingSASVerificationTransaction(
private val mCredentials: Credentials, private val mCredentials: Credentials,
private val mCryptoStore: IMXCryptoStore, private val mCryptoStore: IMXCryptoStore,
private val mSendToDeviceTask: SendToDeviceTask, private val mSendToDeviceTask: SendToDeviceTask,
private val mTaskExecutor: TaskExecutor, transactionId: String, private val mTaskExecutor: TaskExecutor,
deviceFingerprint: String, deviceFingerprint: String,
transactionId: String,
otherUserID: String) otherUserID: String)
: SASVerificationTransaction( : SASVerificationTransaction(
mSasVerificationService, mSasVerificationService,

View File

@ -24,11 +24,11 @@ import im.vector.matrix.android.api.session.crypto.sas.SasMode
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.internal.crypto.CryptoAsyncHelper import im.vector.matrix.android.internal.crypto.CryptoAsyncHelper
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXKey import im.vector.matrix.android.internal.crypto.model.MXKey
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.* import im.vector.matrix.android.internal.crypto.model.rest.*
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
@ -182,7 +182,7 @@ internal abstract class SASVerificationTransaction(
is KeyVerificationAccept -> onVerificationAccept(event) is KeyVerificationAccept -> onVerificationAccept(event)
is KeyVerificationKey -> onKeyVerificationKey(senderId, event) is KeyVerificationKey -> onKeyVerificationKey(senderId, event)
is KeyVerificationMac -> onKeyVerificationMac(event) is KeyVerificationMac -> onKeyVerificationMac(event)
else -> { else -> {
//nop //nop
} }
} }
@ -323,11 +323,11 @@ internal abstract class SASVerificationTransaction(
if (shortCodeBytes!!.size < 5) return null if (shortCodeBytes!!.size < 5) return null
return getDecimalCodeRepresentation(shortCodeBytes!!) return getDecimalCodeRepresentation(shortCodeBytes!!)
} }
SasMode.EMOJI -> { SasMode.EMOJI -> {
if (shortCodeBytes!!.size < 6) return null if (shortCodeBytes!!.size < 6) return null
return getEmojiCodeRepresentation(shortCodeBytes!!).joinToString(" ") { it.emoji } return getEmojiCodeRepresentation(shortCodeBytes!!).joinToString(" ") { it.emoji }
} }
else -> return null else -> return null
} }
} }



View File

@ -75,7 +75,7 @@ class AppModule(private val context: Context) {
} }


single { single {
IncomingVerificationRequestHandler(get(), get(), get()) IncomingVerificationRequestHandler(context, get())
} }





View File

@ -17,7 +17,7 @@ package im.vector.riotredesign.features.crypto.verification


import android.content.Context import android.content.Context
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransaction import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransaction
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
@ -28,11 +28,10 @@ import im.vector.riotredesign.features.popup.PopupAlertManager
* Listens to the VerificationManager and add a new notification when an incoming request is detected. * Listens to the VerificationManager and add a new notification when an incoming request is detected.
*/ */
class IncomingVerificationRequestHandler(val context: Context, class IncomingVerificationRequestHandler(val context: Context,
private val credentials: Credentials, private val session: Session) : SasVerificationService.SasVerificationListener {
verificationService: SasVerificationService) : SasVerificationService.SasVerificationListener {


init { fun ensureStarted() {
verificationService.addListener(this) session.getSasVerificationService().addListener(this)
} }


override fun transactionCreated(tx: SasVerificationTransaction) {} override fun transactionCreated(tx: SasVerificationTransaction) {}
@ -53,7 +52,7 @@ class IncomingVerificationRequestHandler(val context: Context,
).apply { ).apply {
contentAction = Runnable { contentAction = Runnable {
val intent = SASVerificationActivity.incomingIntent(context, val intent = SASVerificationActivity.incomingIntent(context,
credentials.userId, session.sessionParams.credentials.userId,
tx.otherUserId, tx.otherUserId,
tx.transactionId) tx.transactionId)
weakCurrentActivity?.get()?.startActivity(intent) weakCurrentActivity?.get()?.startActivity(intent)
@ -71,7 +70,7 @@ class IncomingVerificationRequestHandler(val context: Context,
context.getString(R.string.action_open), context.getString(R.string.action_open),
Runnable { Runnable {
val intent = SASVerificationActivity.incomingIntent(context, val intent = SASVerificationActivity.incomingIntent(context,
credentials.userId, session.sessionParams.credentials.userId,
tx.otherUserId, tx.otherUserId,
tx.transactionId) tx.transactionId)
weakCurrentActivity?.get()?.startActivity(intent) weakCurrentActivity?.get()?.startActivity(intent)
@ -85,11 +84,11 @@ class IncomingVerificationRequestHandler(val context: Context,
} }
SasVerificationTxState.Cancelled, SasVerificationTxState.Cancelled,
SasVerificationTxState.OnCancelled, SasVerificationTxState.OnCancelled,
SasVerificationTxState.Verified -> { SasVerificationTxState.Verified -> {
//cancel related notification //cancel related notification
PopupAlertManager.cancelAlert("kvr_${tx.transactionId}") PopupAlertManager.cancelAlert("kvr_${tx.transactionId}")
} }
else -> Unit else -> Unit
} }
} }



View File

@ -37,6 +37,7 @@ import im.vector.riotredesign.core.extensions.replaceFragment
import im.vector.riotredesign.core.platform.OnBackPressed import im.vector.riotredesign.core.platform.OnBackPressed
import im.vector.riotredesign.core.platform.ToolbarConfigurable import im.vector.riotredesign.core.platform.ToolbarConfigurable
import im.vector.riotredesign.core.platform.VectorBaseActivity import im.vector.riotredesign.core.platform.VectorBaseActivity
import im.vector.riotredesign.features.crypto.verification.IncomingVerificationRequestHandler
import im.vector.riotredesign.features.home.room.detail.LoadingRoomDetailFragment import im.vector.riotredesign.features.home.room.detail.LoadingRoomDetailFragment
import im.vector.riotredesign.features.rageshake.BugReporter import im.vector.riotredesign.features.rageshake.BugReporter
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
@ -53,6 +54,9 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
private val homeActivityViewModel: HomeActivityViewModel by viewModel() private val homeActivityViewModel: HomeActivityViewModel by viewModel()
private val homeNavigator by inject<HomeNavigator>() private val homeNavigator by inject<HomeNavigator>()


// TODO Move this elsewhere
private val incomingVerificationRequestHandler by inject<IncomingVerificationRequestHandler>()

private var progress: ProgressDialog? = null private var progress: ProgressDialog? = null


private val drawerListener = object : DrawerLayout.SimpleDrawerListener() { private val drawerListener = object : DrawerLayout.SimpleDrawerListener() {
@ -88,6 +92,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
progress?.dismiss() progress?.dismiss()
} }
}) })

incomingVerificationRequestHandler.ensureStarted()
} }


override fun onDestroy() { override fun onDestroy() {
@ -124,7 +130,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {


override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
android.R.id.home -> { android.R.id.home -> {
drawerLayout.openDrawer(GravityCompat.START) drawerLayout.openDrawer(GravityCompat.START)
return true return true
} }
@ -137,7 +143,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
return true return true
} }
// TODO Temporary code here to create a room // TODO Temporary code here to create a room
R.id.tmp_menu_create_room -> { R.id.tmp_menu_create_room -> {
homeActivityViewModel.createRoom() homeActivityViewModel.createRoom()
return true return true
} }

View File

@ -86,8 +86,6 @@ class SignOutViewModel : ViewModel(), KeysBackupService.KeysBackupStateListener
* The backup check on logout flow has to be displayed if there are keys in the store, and the keys backup state is not Ready * The backup check on logout flow has to be displayed if there are keys in the store, and the keys backup state is not Ready
*/ */
fun doYouNeedToBeDisplayed(session: Session?): Boolean { fun doYouNeedToBeDisplayed(session: Session?): Boolean {
return false

return session return session
?.inboundGroupSessionsCount(false) ?.inboundGroupSessionsCount(false)
?: 0 > 0 ?: 0 > 0