Secure secrets passed to intent
This commit is contained in:
parent
76b425ee8a
commit
6c9b16088f
@ -49,7 +49,8 @@ class ReAuthActivity : SimpleFragmentActivity(), ReAuthViewModel.Factory {
|
|||||||
val flowType: String?,
|
val flowType: String?,
|
||||||
val title: String?,
|
val title: String?,
|
||||||
val session: String?,
|
val session: String?,
|
||||||
val lastErrorCode: String?
|
val lastErrorCode: String?,
|
||||||
|
val resultKeyStoreAlias: String
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
// For sso
|
// For sso
|
||||||
@ -101,7 +102,7 @@ class ReAuthActivity : SimpleFragmentActivity(), ReAuthViewModel.Factory {
|
|||||||
is ReAuthEvents.PasswordFinishSuccess -> {
|
is ReAuthEvents.PasswordFinishSuccess -> {
|
||||||
setResult(RESULT_OK, Intent().apply {
|
setResult(RESULT_OK, Intent().apply {
|
||||||
putExtra(RESULT_FLOW_TYPE, LoginFlowTypes.PASSWORD)
|
putExtra(RESULT_FLOW_TYPE, LoginFlowTypes.PASSWORD)
|
||||||
putExtra(RESULT_VALUE, it.password)
|
putExtra(RESULT_VALUE, it.passwordSafeForIntent)
|
||||||
})
|
})
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
@ -197,8 +198,13 @@ class ReAuthActivity : SimpleFragmentActivity(), ReAuthViewModel.Factory {
|
|||||||
const val EXTRA_REASON_TITLE = "EXTRA_REASON_TITLE"
|
const val EXTRA_REASON_TITLE = "EXTRA_REASON_TITLE"
|
||||||
const val RESULT_FLOW_TYPE = "RESULT_FLOW_TYPE"
|
const val RESULT_FLOW_TYPE = "RESULT_FLOW_TYPE"
|
||||||
const val RESULT_VALUE = "RESULT_VALUE"
|
const val RESULT_VALUE = "RESULT_VALUE"
|
||||||
|
const val DEFAULT_RESULT_KEYSTORE_ALIAS = "ReAuthActivity"
|
||||||
|
|
||||||
fun newIntent(context: Context, fromError: RegistrationFlowResponse, lastErrorCode: String?, reasonTitle: String?): Intent {
|
fun newIntent(context: Context,
|
||||||
|
fromError: RegistrationFlowResponse,
|
||||||
|
lastErrorCode: String?,
|
||||||
|
reasonTitle: String?,
|
||||||
|
resultKeyStoreAlias: String = DEFAULT_RESULT_KEYSTORE_ALIAS): Intent {
|
||||||
val authType = when (fromError.nextUncompletedStage()) {
|
val authType = when (fromError.nextUncompletedStage()) {
|
||||||
LoginFlowTypes.PASSWORD -> {
|
LoginFlowTypes.PASSWORD -> {
|
||||||
LoginFlowTypes.PASSWORD
|
LoginFlowTypes.PASSWORD
|
||||||
@ -212,7 +218,7 @@ class ReAuthActivity : SimpleFragmentActivity(), ReAuthViewModel.Factory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Intent(context, ReAuthActivity::class.java).apply {
|
return Intent(context, ReAuthActivity::class.java).apply {
|
||||||
putExtra(MvRx.KEY_ARG, Args(authType, reasonTitle, fromError.session, lastErrorCode))
|
putExtra(MvRx.KEY_ARG, Args(authType, reasonTitle, fromError.session, lastErrorCode, resultKeyStoreAlias))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,5 +21,5 @@ import im.vector.app.core.platform.VectorViewEvents
|
|||||||
sealed class ReAuthEvents : VectorViewEvents {
|
sealed class ReAuthEvents : VectorViewEvents {
|
||||||
data class OpenSsoURl(val url: String) : ReAuthEvents()
|
data class OpenSsoURl(val url: String) : ReAuthEvents()
|
||||||
object Dismiss : ReAuthEvents()
|
object Dismiss : ReAuthEvents()
|
||||||
data class PasswordFinishSuccess(val password: String) : ReAuthEvents()
|
data class PasswordFinishSuccess(val passwordSafeForIntent: String) : ReAuthEvents()
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,15 @@ data class ReAuthState(
|
|||||||
val flowType: String? = null,
|
val flowType: String? = null,
|
||||||
val ssoFallbackPageWasShown: Boolean = false,
|
val ssoFallbackPageWasShown: Boolean = false,
|
||||||
val passwordVisible: Boolean = false,
|
val passwordVisible: Boolean = false,
|
||||||
val lastErrorCode: String? = null
|
val lastErrorCode: String? = null,
|
||||||
|
val resultKeyStoreAlias: String = ""
|
||||||
) : MvRxState {
|
) : MvRxState {
|
||||||
constructor(args: ReAuthActivity.Args) : this(
|
constructor(args: ReAuthActivity.Args) : this(
|
||||||
args.title,
|
args.title,
|
||||||
args.session,
|
args.session,
|
||||||
args.flowType,
|
args.flowType,
|
||||||
lastErrorCode = args.lastErrorCode
|
lastErrorCode = args.lastErrorCode,
|
||||||
|
resultKeyStoreAlias = args.resultKeyStoreAlias
|
||||||
)
|
)
|
||||||
|
|
||||||
constructor() : this(null, null)
|
constructor() : this(null, null)
|
||||||
|
@ -24,14 +24,14 @@ import dagger.assisted.Assisted
|
|||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import org.matrix.android.sdk.api.auth.AuthenticationService
|
|
||||||
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
class ReAuthViewModel @AssistedInject constructor(
|
class ReAuthViewModel @AssistedInject constructor(
|
||||||
@Assisted val initialState: ReAuthState,
|
@Assisted val initialState: ReAuthState,
|
||||||
private val session: Session,
|
private val session: Session
|
||||||
private val authenticationService: AuthenticationService
|
|
||||||
) : VectorViewModel<ReAuthState, ReAuthActions, ReAuthEvents>(initialState) {
|
) : VectorViewModel<ReAuthState, ReAuthActions, ReAuthEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
@ -72,7 +72,12 @@ class ReAuthViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is ReAuthActions.ReAuthWithPass -> {
|
is ReAuthActions.ReAuthWithPass -> {
|
||||||
_viewEvents.post(ReAuthEvents.PasswordFinishSuccess(action.password))
|
val safeForIntentCypher = ByteArrayOutputStream().also {
|
||||||
|
it.use {
|
||||||
|
session.securelyStoreObject(action.password, initialState.resultKeyStoreAlias, it)
|
||||||
|
}
|
||||||
|
}.toByteArray().toBase64NoPadding()
|
||||||
|
_viewEvents.post(ReAuthEvents.PasswordFinishSuccess(safeForIntentCypher))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import im.vector.app.core.extensions.exhaustive
|
|||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.platform.WaitingViewData
|
import im.vector.app.core.platform.WaitingViewData
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.auth.ReAuthActivity
|
||||||
import im.vector.app.features.login.ReAuthHelper
|
import im.vector.app.features.login.ReAuthHelper
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -44,6 +45,7 @@ import org.matrix.android.sdk.api.session.Session
|
|||||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||||
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
|
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.internal.auth.registration.nextUncompletedStage
|
import org.matrix.android.sdk.internal.auth.registration.nextUncompletedStage
|
||||||
|
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
||||||
import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
|
import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
||||||
@ -269,10 +271,11 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
|||||||
uiaContinuation?.resume(DefaultBaseAuth(session = pendingAuth?.session ?: ""))
|
uiaContinuation?.resume(DefaultBaseAuth(session = pendingAuth?.session ?: ""))
|
||||||
}
|
}
|
||||||
is BootstrapActions.PasswordAuthDone -> {
|
is BootstrapActions.PasswordAuthDone -> {
|
||||||
|
val decryptedPass = session.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
||||||
uiaContinuation?.resume(
|
uiaContinuation?.resume(
|
||||||
UserPasswordAuth(
|
UserPasswordAuth(
|
||||||
session = pendingAuth?.session,
|
session = pendingAuth?.session,
|
||||||
password = action.password,
|
password = decryptedPass,
|
||||||
user = session.myUserId
|
user = session.myUserId
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -26,6 +26,7 @@ import im.vector.app.R
|
|||||||
import im.vector.app.core.extensions.exhaustive
|
import im.vector.app.core.extensions.exhaustive
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.auth.ReAuthActivity
|
||||||
import im.vector.app.features.login.ReAuthHelper
|
import im.vector.app.features.login.ReAuthHelper
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
@ -38,6 +39,7 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
|||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
|
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.internal.auth.registration.nextUncompletedStage
|
import org.matrix.android.sdk.internal.auth.registration.nextUncompletedStage
|
||||||
|
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||||
import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified
|
import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||||
@ -134,10 +136,11 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
|||||||
Unit
|
Unit
|
||||||
}
|
}
|
||||||
is CrossSigningSettingsAction.PasswordAuthDone -> {
|
is CrossSigningSettingsAction.PasswordAuthDone -> {
|
||||||
|
val decryptedPass = session.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
||||||
uiaContinuation?.resume(
|
uiaContinuation?.resume(
|
||||||
UserPasswordAuth(
|
UserPasswordAuth(
|
||||||
session = pendingAuth?.session,
|
session = pendingAuth?.session,
|
||||||
password = action.password,
|
password = decryptedPass,
|
||||||
user = session.myUserId
|
user = session.myUserId
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -32,6 +32,7 @@ import dagger.assisted.AssistedInject
|
|||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.auth.ReAuthActivity
|
||||||
import im.vector.app.features.login.ReAuthHelper
|
import im.vector.app.features.login.ReAuthHelper
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
@ -51,6 +52,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxStat
|
|||||||
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
|
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.internal.auth.registration.nextUncompletedStage
|
import org.matrix.android.sdk.internal.auth.registration.nextUncompletedStage
|
||||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||||
|
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||||
@ -221,10 +223,11 @@ class DevicesViewModel @AssistedInject constructor(
|
|||||||
Unit
|
Unit
|
||||||
}
|
}
|
||||||
is DevicesAction.PasswordAuthDone -> {
|
is DevicesAction.PasswordAuthDone -> {
|
||||||
|
val decryptedPass = session.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
||||||
uiaContinuation?.resume(
|
uiaContinuation?.resume(
|
||||||
UserPasswordAuth(
|
UserPasswordAuth(
|
||||||
session = pendingAuth?.session,
|
session = pendingAuth?.session,
|
||||||
password = action.password,
|
password = decryptedPass,
|
||||||
user = session.myUserId
|
user = session.myUserId
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user