Fix incorrect RRP bugs and reglock state with reregistering.

This commit is contained in:
Cody Henthorne 2024-12-16 14:24:11 -05:00 committed by GitHub
parent 0ce75b21ee
commit fc34b60f77
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 15 additions and 24 deletions

View file

@ -392,7 +392,7 @@ object RegistrationRepository {
/**
* Submit the necessary assets as a verified account so that the user can actually use the service.
*/
suspend fun registerAccount(context: Context, sessionId: String?, registrationData: RegistrationData, pin: String? = null, masterKeyProducer: MasterKeyProducer? = null): RegisterAccountResult =
suspend fun registerAccount(context: Context, sessionId: String?, registrationData: RegistrationData, recoveryPassword: String?, pin: String? = null, masterKeyProducer: MasterKeyProducer? = null): RegisterAccountResult =
withContext(Dispatchers.IO) {
Log.v(TAG, "registerAccount()")
val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, registrationData.e164, SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.password).registrationApi
@ -424,7 +424,7 @@ object RegistrationRepository {
discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy.phoneNumberDiscoverabilityMode == PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.DISCOVERABLE,
name = null,
pniRegistrationId = registrationData.pniRegistrationId,
recoveryPassword = registrationData.recoveryPassword
recoveryPassword = recoveryPassword
)
SignalStore.account.generateAciIdentityKeyIfNecessary()
@ -436,7 +436,7 @@ object RegistrationRepository {
val aciPreKeyCollection = generateSignedAndLastResortPreKeys(aciIdentity, SignalStore.account.aciPreKeys)
val pniPreKeyCollection = generateSignedAndLastResortPreKeys(pniIdentity, SignalStore.account.pniPreKeys)
val result: NetworkResult<AccountRegistrationResult> = api.registerAccount(sessionId, registrationData.recoveryPassword, accountAttributes, aciPreKeyCollection, pniPreKeyCollection, registrationData.fcmToken, true)
val result: NetworkResult<AccountRegistrationResult> = api.registerAccount(sessionId, recoveryPassword, accountAttributes, aciPreKeyCollection, pniPreKeyCollection, registrationData.fcmToken, true)
.map { accountRegistrationResponse: VerifyAccountResponse ->
AccountRegistrationResult(
uuid = accountRegistrationResponse.uuid,

View file

@ -26,7 +26,6 @@ data class RegistrationState(
val phoneNumber: Phonenumber.PhoneNumber? = fetchExistingE164FromValues(),
val inProgress: Boolean = false,
val isReRegister: Boolean = false,
val recoveryPassword: String? = SignalStore.svr.recoveryPassword,
val canSkipSms: Boolean = false,
val svr2AuthCredentials: AuthCredentials? = null,
val svr3AuthCredentials: Svr3Credentials? = null,

View file

@ -221,7 +221,7 @@ class RegistrationViewModel : ViewModel() {
fun onBackupSuccessfullyRestored() {
val recoveryPassword = SignalStore.svr.recoveryPassword
store.update {
it.copy(registrationCheckpoint = RegistrationCheckpoint.BACKUP_RESTORED_OR_SKIPPED, recoveryPassword = SignalStore.svr.recoveryPassword, canSkipSms = recoveryPassword != null, isReRegister = true)
it.copy(registrationCheckpoint = RegistrationCheckpoint.BACKUP_RESTORED_OR_SKIPPED, canSkipSms = recoveryPassword != null, isReRegister = true)
}
}
@ -232,7 +232,7 @@ class RegistrationViewModel : ViewModel() {
val e164 = state.phoneNumber?.toE164() ?: return bail { Log.i(TAG, "Phone number was null after confirmation.") }
if (!state.userSkippedReregistration) {
if (hasRecoveryPassword() && matchesSavedE164(e164)) {
if (SignalStore.svr.recoveryPassword != null && matchesSavedE164(e164)) {
// Re-registration when the local database is intact.
Log.d(TAG, "Has recovery password, and therefore can skip SMS verification.")
store.update {
@ -598,12 +598,6 @@ class RegistrationViewModel : ViewModel() {
}
}
private fun setRecoveryPassword(recoveryPassword: String?) {
store.update {
it.copy(recoveryPassword = recoveryPassword)
}
}
private fun updateSvrTriesRemaining(remainingTries: Int) {
store.update {
it.copy(svrTriesRemaining = remainingTries)
@ -631,7 +625,6 @@ class RegistrationViewModel : ViewModel() {
SignalStore.svr.masterKeyForInitialDataRestore = masterKey
SignalStore.svr.setPin(pin)
setRecoveryPassword(masterKey.deriveRegistrationRecoveryPassword())
updateSvrTriesRemaining(10)
verifyReRegisterInternal(context, pin, masterKey)
} catch (rejectedPin: SvrWrongPinException) {
@ -688,7 +681,7 @@ class RegistrationViewModel : ViewModel() {
*/
private suspend fun registerAccountInternal(context: Context, sessionId: String?, registrationData: RegistrationData, pin: String?, masterKey: MasterKey): Pair<RegisterAccountResult, Boolean> {
Log.v(TAG, "registerAccountInternal()")
var registrationResult: RegisterAccountResult = RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, pin = pin)
var registrationResult: RegisterAccountResult = RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, recoveryPassword = masterKey.deriveRegistrationRecoveryPassword(), pin = pin)
// Check if reg lock is enabled
if (registrationResult !is RegisterAccountResult.RegistrationLocked) {
@ -708,7 +701,7 @@ class RegistrationViewModel : ViewModel() {
)
}
return Pair(RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, pin = pin) { masterKey }, true)
return Pair(RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, recoveryPassword = masterKey.deriveRegistrationRecoveryPassword(), pin = pin) { masterKey }, true)
}
fun verifyCodeWithoutRegistrationLock(context: Context, code: String) {
@ -785,7 +778,7 @@ class RegistrationViewModel : ViewModel() {
if (!reglock) {
Log.d(TAG, "Registration lock not enabled, attempting to register account without master key producer.")
result = RegistrationRepository.registerAccount(context, sessionId, registrationData, pin)
result = RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, recoveryPassword = null, pin = pin)
}
if (result is RegisterAccountResult.RegistrationLocked) {
@ -795,10 +788,13 @@ class RegistrationViewModel : ViewModel() {
it.copy(lockedTimeRemaining = timeRemaining)
}
reglock = true
if (pin == null && SignalStore.svr.registrationLockToken != null) {
Log.d(TAG, "Retrying registration with stored credentials.")
result = RegistrationRepository.registerAccount(context, sessionId, registrationData, SignalStore.svr.pin) { SignalStore.svr.masterKey }
} else if (result.svr2Credentials != null || result.svr3Credentials != null) {
result = RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, recoveryPassword = null, pin = SignalStore.svr.pin) { SignalStore.svr.masterKey }
}
if (result is RegisterAccountResult.RegistrationLocked && (result.svr2Credentials != null || result.svr3Credentials != null)) {
Log.d(TAG, "Retrying registration with received credentials (svr2: ${result.svr2Credentials != null}, svr3: ${result.svr3Credentials != null}).")
val svr2Credentials = result.svr2Credentials
val svr3Credentials = result.svr3Credentials
@ -810,7 +806,7 @@ class RegistrationViewModel : ViewModel() {
if (reglock && pin.isNotNullOrBlank()) {
Log.d(TAG, "Registration lock enabled, attempting to register account restore master key from SVR (svr2: ${state.svr2AuthCredentials != null}, svr3: ${state.svr3AuthCredentials != null})")
result = RegistrationRepository.registerAccount(context, sessionId, registrationData, pin) {
result = RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, recoveryPassword = null, pin = pin) {
SvrRepository.restoreMasterKeyPreRegistration(
credentials = SvrAuthCredentialSet(
svr2Credentials = state.svr2AuthCredentials,
@ -831,7 +827,7 @@ class RegistrationViewModel : ViewModel() {
private suspend fun registerVerifiedSession(context: Context, sessionId: String) {
Log.v(TAG, "registerVerifiedSession()")
val registrationData = getRegistrationData()
val registrationResponse: RegisterAccountResult = RegistrationRepository.registerAccount(context, sessionId, registrationData)
val registrationResponse: RegisterAccountResult = RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, recoveryPassword = null)
handleRegistrationResult(context, registrationData, registrationResponse, false)
}
@ -890,10 +886,6 @@ class RegistrationViewModel : ViewModel() {
}
}
private fun hasRecoveryPassword(): Boolean {
return store.value.recoveryPassword != null
}
private fun getCurrentE164(): String? {
return store.value.phoneNumber?.toE164()
}