Create isRecoverySetup()

This commit is contained in:
Benoit Marty 2020-06-17 11:25:30 +02:00 committed by Valere
parent bcd78a96bf
commit 12a4f6f05b
7 changed files with 74 additions and 42 deletions

View file

@ -99,7 +99,9 @@ interface CryptoService {
fun removeRoomKeysRequestListener(listener: GossipingRequestListener)
fun fetchDevicesList(callback: MatrixCallback<DevicesListResponse>)
fun getMyDevicesInfo() : List<DeviceInfo>
fun getLiveMyDevicesInfo() : LiveData<List<DeviceInfo>>
fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>)

View file

@ -18,6 +18,9 @@ package im.vector.matrix.android.api.session.securestorage
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
import im.vector.matrix.android.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
/**
* Some features may require clients to store encrypted data on the server so that it can be shared securely between clients.
@ -111,7 +114,17 @@ interface SharedSecretStorageService {
*/
fun getSecret(name: String, keyId: String?, secretKey: SsssKeySpec, callback: MatrixCallback<String>)
fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?) : IntegrityResult
/**
* Return true if SSSS is configured
*/
fun isRecoverySetup(): Boolean {
return checkShouldBeAbleToAccessSecrets(
secretNames = listOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME),
keyId = null
) is IntegrityResult.Success
}
fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?): IntegrityResult
fun requestSecret(name: String, myOtherDeviceId: String)

View file

@ -212,7 +212,9 @@ internal interface IMXCryptoStore {
fun getLiveDeviceList(): LiveData<List<CryptoDeviceInfo>>
fun getMyDevicesInfo() : List<DeviceInfo>
fun getLiveMyDevicesInfo() : LiveData<List<DeviceInfo>>
fun saveMyDevicesInfo(info: List<DeviceInfo>)
/**
* Store the crypto algorithm for a room.

View file

@ -44,7 +44,6 @@ import im.vector.matrix.android.api.session.crypto.verification.VerificationTran
import im.vector.matrix.android.api.session.crypto.verification.VerificationTxState
import im.vector.matrix.android.api.session.events.model.LocalEcho
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
import im.vector.matrix.android.api.session.securestorage.IntegrityResult
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.matrix.android.api.util.toMatrixItem
import im.vector.matrix.android.internal.crypto.crosssigning.fromBase64
@ -118,10 +117,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
session.cryptoService().verificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
}
val ssssOk = session.sharedSecretStorageService.checkShouldBeAbleToAccessSecrets(
listOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME),
null // default key
) is IntegrityResult.Success
setState {
copy(
otherUserMxItem = userItem?.toMatrixItem(),
@ -133,7 +128,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
roomId = args.roomId,
isMe = args.otherUserId == session.myUserId,
currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(),
quadSContainsSecrets = ssssOk
quadSContainsSecrets = session.sharedSecretStorageService.isRecoverySetup()
)
}

View file

@ -41,34 +41,37 @@ class CrossSigningSettingsController @Inject constructor(
override fun buildModels(data: CrossSigningSettingsViewState?) {
if (data == null) return
if (data.xSigningKeyCanSign) {
genericItem {
id("can")
titleIconResourceId(R.drawable.ic_shield_trusted)
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_complete))
}
} else if (data.xSigningKeysAreTrusted) {
genericItem {
id("trusted")
titleIconResourceId(R.drawable.ic_shield_custom)
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_trusted))
}
bottomSheetVerificationActionItem {
id("verify")
title(stringProvider.getString(R.string.crosssigning_verify_this_session))
titleColor(colorProvider.getColor(R.color.riotx_positive_accent))
iconRes(R.drawable.ic_arrow_right)
iconColor(colorProvider.getColor(R.color.riotx_positive_accent))
listener {
interactionListener?.verifySession()
when {
data.xSigningKeyCanSign -> {
genericItem {
id("can")
titleIconResourceId(R.drawable.ic_shield_trusted)
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_complete))
}
}
} else if (data.xSigningIsEnableInAccount) {
genericItem {
id("enable")
titleIconResourceId(R.drawable.ic_shield_black)
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_not_trusted))
data.xSigningKeysAreTrusted -> {
genericItem {
id("trusted")
titleIconResourceId(R.drawable.ic_shield_custom)
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_trusted))
}
}
data.xSigningIsEnableInAccount -> {
genericItem {
id("enable")
titleIconResourceId(R.drawable.ic_shield_black)
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_not_trusted))
}
}
else -> {
genericItem {
id("not")
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_disabled))
}
}
}
if (data.recoveryHasToBeSetUp) {
bottomSheetVerificationActionItem {
id("setup_recovery")
title(stringProvider.getString(R.string.settings_setup_secure_backup))
@ -78,6 +81,9 @@ class CrossSigningSettingsController @Inject constructor(
interactionListener?.setupRecovery()
}
}
}
if (data.deviceHasToBeVerified) {
bottomSheetVerificationActionItem {
id("verify")
title(stringProvider.getString(R.string.crosssigning_verify_this_session))
@ -88,11 +94,6 @@ class CrossSigningSettingsController @Inject constructor(
interactionListener?.verifySession()
}
}
} else {
genericItem {
id("not")
title(stringProvider.getString(R.string.encryption_information_dg_xsigning_disabled))
}
}
val crossSigningKeys = data.crossSigningInfo

View file

@ -21,27 +21,43 @@ import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.crypto.crosssigning.isVerified
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.matrix.rx.rx
import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.platform.VectorViewModel
import io.reactivex.Observable
import io.reactivex.functions.BiFunction
class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted private val initialState: CrossSigningSettingsViewState,
private val session: Session)
: VectorViewModel<CrossSigningSettingsViewState, CrossSigningSettingsAction, CrossSigningSettingsViewEvents>(initialState) {
init {
session.rx().liveCrossSigningInfo(session.myUserId)
.execute {
val crossSigningKeys = it.invoke()?.getOrNull()
Observable.combineLatest<List<DeviceInfo>, Optional<MXCrossSigningInfo>, Pair<List<DeviceInfo>, Optional<MXCrossSigningInfo>>>(
session.rx().liveMyDeviceInfo(),
session.rx().liveCrossSigningInfo(session.myUserId),
BiFunction { myDeviceInfo, mxCrossSigningInfo ->
(myDeviceInfo to mxCrossSigningInfo)
}
)
.execute { data ->
val crossSigningKeys = data.invoke()?.second?.getOrNull()
val xSigningIsEnableInAccount = crossSigningKeys != null
val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified()
val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign()
val hasSeveralDevices = data.invoke()?.first?.size ?: 0 > 1
copy(
crossSigningInfo = crossSigningKeys,
xSigningIsEnableInAccount = xSigningIsEnableInAccount,
xSigningKeysAreTrusted = xSigningKeysAreTrusted,
xSigningKeyCanSign = xSigningKeyCanSign
xSigningKeyCanSign = xSigningKeyCanSign,
deviceHasToBeVerified = hasSeveralDevices && (xSigningIsEnableInAccount || xSigningKeysAreTrusted),
recoveryHasToBeSetUp = !session.sharedSecretStorageService.isRecoverySetup()
)
}
}

View file

@ -23,5 +23,8 @@ data class CrossSigningSettingsViewState(
val crossSigningInfo: MXCrossSigningInfo? = null,
val xSigningIsEnableInAccount: Boolean = false,
val xSigningKeysAreTrusted: Boolean = false,
val xSigningKeyCanSign: Boolean = true
val xSigningKeyCanSign: Boolean = true,
val deviceHasToBeVerified: Boolean = false,
val recoveryHasToBeSetUp: Boolean = false
) : MvRxState