Skip to content

Commit

Permalink
Attempt to Skip PIN Entry on Re-Registration.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholas-signal authored and alex-signal committed Jan 11, 2023
1 parent 13f4379 commit e4cc7f5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.AppCapabilities
import org.thoughtcrime.securesms.gcm.FcmUtil
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.pin.KbsRepository
import org.thoughtcrime.securesms.pin.KeyBackupSystemWrongPinException
import org.thoughtcrime.securesms.pin.TokenData
import org.thoughtcrime.securesms.push.AccountManagerFactory
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.KbsPinData
Expand Down Expand Up @@ -77,7 +75,11 @@ class VerifyAccountRepository(private val context: Application) {
}.subscribeOn(Schedulers.io())
}

fun verifyAccountWithPin(registrationData: RegistrationData, pin: String, tokenData: TokenData): Single<ServiceResponse<VerifyResponse>> {
fun verifyAccountWithReregistrationData(registrationData: RegistrationData, kbsPinDataProducer: KbsPinDataProducer): Single<ServiceResponse<VerifyResponse>> {
return verifyAccountWithPin(registrationData, "", kbsPinDataProducer)
}

fun verifyAccountWithPin(registrationData: RegistrationData, pin: String, kbsPinDataProducer: KbsPinDataProducer): Single<ServiceResponse<VerifyResponse>> {
val universalUnidentifiedAccess: Boolean = TextSecurePreferences.isUniversalUnidentifiedAccess(context)
val unidentifiedAccessKey: ByteArray = UnidentifiedAccess.deriveAccessKeyFrom(registrationData.profileKey)

Expand All @@ -90,7 +92,7 @@ class VerifyAccountRepository(private val context: Application) {

return Single.fromCallable {
try {
val kbsData: KbsPinData = KbsRepository.restoreMasterKey(pin, tokenData.enclave, tokenData.basicAuth, tokenData.tokenResponse)!!
val kbsData = kbsPinDataProducer.produceKbsPinData()
val registrationLockV2: String = kbsData.masterKey.deriveRegistrationLock()

val response: ServiceResponse<VerifyAccountResponse> = accountManager.verifyAccountWithRegistrationLockPin(
Expand All @@ -115,6 +117,11 @@ class VerifyAccountRepository(private val context: Application) {
}.subscribeOn(Schedulers.io())
}

interface KbsPinDataProducer {
@Throws(IOException::class, KeyBackupSystemWrongPinException::class, KeyBackupSystemNoDataException::class)
fun produceKbsPinData(): KbsPinData
}

enum class Mode(val isSmsRetrieverSupported: Boolean) {
SMS_WITH_LISTENER(true),
SMS_WITHOUT_LISTENER(false),
Expand All @@ -125,5 +132,4 @@ class VerifyAccountRepository(private val context: Application) {
private val TAG = Log.tag(VerifyAccountRepository::class.java)
private val PUSH_REQUEST_TIMEOUT = TimeUnit.SECONDS.toMillis(5)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,12 @@ public Single<VerifyResponseProcessor> verifyCodeWithoutRegistrationLock(@NonNul
onVerificationCodeEntered(code);

return verifyAccountWithoutRegistrationLock()
.map(VerifyResponseWithoutKbs::new)
.flatMap(processor -> {
.flatMap(response -> {
if (response.getResult().isPresent() && response.getResult().get().getKbsData() != null) {
return onVerifySuccessWithRegistrationLock(new VerifyResponseWithRegistrationLockProcessor(response, null), response.getResult().get().getPin());
}

VerifyResponseProcessor processor = new VerifyResponseWithoutKbs(response);
if (processor.hasResult()) {
return onVerifySuccess(processor);
} else if (processor.registrationLock() && !processor.isKbsLocked()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import androidx.savedstate.SavedStateRegistryOwner;

import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.pin.KbsRepository;
import org.thoughtcrime.securesms.pin.TokenData;
import org.thoughtcrime.securesms.registration.RegistrationData;
Expand All @@ -20,8 +21,11 @@
import org.thoughtcrime.securesms.registration.VerifyResponseWithRegistrationLockProcessor;
import org.thoughtcrime.securesms.registration.VerifyResponseWithoutKbs;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.api.KbsPinData;
import org.whispersystems.signalservice.internal.ServiceResponse;

import java.util.Objects;

import io.reactivex.rxjava3.core.Single;

public final class RegistrationViewModel extends BaseRegistrationViewModel {
Expand Down Expand Up @@ -104,12 +108,30 @@ public Single<RequestVerificationCodeResponseProcessor> requestVerificationCode(

@Override
protected Single<ServiceResponse<VerifyResponse>> verifyAccountWithoutRegistrationLock() {
return verifyAccountRepository.verifyAccount(getRegistrationData());
return verifyAccountRepository.verifyAccount(getRegistrationData())
.flatMap(verifyAccountWithoutKbsResponse -> {
VerifyResponseProcessor processor = new VerifyResponseWithoutKbs(verifyAccountWithoutKbsResponse);

if (processor.registrationLock() && SignalStore.kbsValues().getRegistrationLockToken() != null) {
KbsPinData pinData = new KbsPinData(SignalStore.kbsValues().getOrCreateMasterKey(), SignalStore.kbsValues().getRegistrationLockTokenResponse());

return verifyAccountRepository.verifyAccountWithReregistrationData(getRegistrationData(), () -> pinData)
.map(verifyAccountWithPinResponse -> {
if (verifyAccountWithPinResponse.getResult().isPresent() && verifyAccountWithPinResponse.getResult().get().getKbsData() != null) {
return verifyAccountWithPinResponse;
} else {
return verifyAccountWithoutKbsResponse;
}
});
} else {
return Single.just(verifyAccountWithoutKbsResponse);
}
});
}

@Override
protected Single<ServiceResponse<VerifyResponse>> verifyAccountWithRegistrationLock(@NonNull String pin, @NonNull TokenData kbsTokenData) {
return verifyAccountRepository.verifyAccountWithPin(getRegistrationData(), pin, kbsTokenData);
return verifyAccountRepository.verifyAccountWithPin(getRegistrationData(), pin, () -> Objects.requireNonNull(KbsRepository.restoreMasterKey(pin, kbsTokenData.getEnclave(), kbsTokenData.getBasicAuth(), kbsTokenData.getTokenResponse())));
}

@Override
Expand Down

0 comments on commit e4cc7f5

Please sign in to comment.