Consolidate odds and ends from reg v1 into reg v2.

This commit is contained in:
Nicholas Tinsley 2024-09-05 15:01:51 -04:00 committed by Cody Henthorne
parent c9746b59ed
commit bf46e5bc24
5 changed files with 24 additions and 107 deletions

View file

@ -5,23 +5,23 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.Base64;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.AppCapabilities;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode;
import org.thoughtcrime.securesms.keyvalue.SvrValues;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.registration.RegistrationRepository;
import org.thoughtcrime.securesms.keyvalue.SvrValues;
import org.thoughtcrime.securesms.registration.data.RegistrationRepository;
import org.thoughtcrime.securesms.registration.secondary.DeviceNameCipher;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.account.AccountAttributes;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.push.exceptions.NetworkFailureException;
import org.signal.core.util.Base64;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -91,7 +91,7 @@ public class RefreshAttributesJob extends BaseJob {
boolean universalUnidentifiedAccess = TextSecurePreferences.isUniversalUnidentifiedAccess(context);
String registrationLockV2 = null;
SvrValues svrValues = SignalStore.svr();
int pniRegistrationId = new RegistrationRepository().getPniRegistrationId();
int pniRegistrationId = RegistrationRepository.getPniRegistrationId();
String recoveryPassword = svrValues.getRecoveryPassword();
if (svrValues.isRegistrationLockEnabled()) {

View file

@ -1,80 +0,0 @@
package org.thoughtcrime.securesms.registration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.IdentityKeyPair;
import org.signal.libsignal.protocol.state.KyberPreKeyRecord;
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
import org.signal.libsignal.protocol.util.KeyHelper;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.whispersystems.signalservice.api.account.PreKeyCollection;
import java.util.Optional;
/**
* Operations required for finalizing the registration of an account. This is
* to be used after verifying the code and registration lock (if necessary) with
* the server and being issued a UUID.
*/
public final class RegistrationRepository {
private static final String TAG = Log.tag(RegistrationRepository.class);
public RegistrationRepository() {
}
public int getPniRegistrationId() {
int pniRegistrationId = SignalStore.account().getPniRegistrationId();
if (pniRegistrationId == 0) {
pniRegistrationId = KeyHelper.generateRegistrationId(false);
SignalStore.account().setPniRegistrationId(pniRegistrationId);
}
return pniRegistrationId;
}
public @NonNull ProfileKey getProfileKey(@NonNull String e164) {
ProfileKey profileKey = findExistingProfileKey(e164);
if (profileKey == null) {
profileKey = ProfileKeyUtil.createNew();
Log.i(TAG, "No profile key found, created a new one");
}
return profileKey;
}
public static PreKeyCollection generateSignedAndLastResortPreKeys(IdentityKeyPair identity, PreKeyMetadataStore metadataStore) {
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateSignedPreKey(metadataStore.getNextSignedPreKeyId(), identity.getPrivateKey());
KyberPreKeyRecord lastResortKyberPreKey = PreKeyUtil.generateLastResortKyberPreKey(metadataStore.getNextKyberPreKeyId(), identity.getPrivateKey());
return new PreKeyCollection(
identity.getPublicKey(),
signedPreKey,
lastResortKyberPreKey
);
}
@WorkerThread
private static @Nullable ProfileKey findExistingProfileKey(@NonNull String e164number) {
RecipientTable recipientTable = SignalDatabase.recipients();
Optional<RecipientId> recipient = recipientTable.getByE164(e164number);
if (recipient.isPresent()) {
return ProfileKeyUtil.profileKeyOrNull(Recipient.resolved(recipient.get()).getProfileKey());
}
return null;
}
}

View file

@ -1,17 +0,0 @@
package org.thoughtcrime.securesms.registration
import org.thoughtcrime.securesms.pin.SvrWrongPinException
import org.whispersystems.signalservice.api.SvrNoDataException
import org.whispersystems.signalservice.api.kbs.MasterKey
import java.io.IOException
/**
* Request SMS/Phone verification codes to help prove ownership of a phone number.
*/
class VerifyAccountRepository {
fun interface MasterKeyProducer {
@Throws(IOException::class, SvrWrongPinException::class, SvrNoDataException::class)
fun produceMasterKey(): MasterKey
}
}

View file

@ -41,4 +41,3 @@ class VerifyResponseWithoutKbs(response: ServiceResponse<VerifyResponse>) : Veri
return registrationLock() && getLockedException().svr2Credentials == null
}
}

View file

@ -45,7 +45,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.registration.PushChallengeRequest
import org.thoughtcrime.securesms.registration.RegistrationData
import org.thoughtcrime.securesms.registration.VerifyAccountRepository
import org.thoughtcrime.securesms.registration.data.LocalRegistrationMetadataUtil.getAciIdentityKeyPair
import org.thoughtcrime.securesms.registration.data.LocalRegistrationMetadataUtil.getAciPreKeyCollection
import org.thoughtcrime.securesms.registration.data.LocalRegistrationMetadataUtil.getPniIdentityKeyPair
@ -393,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: VerifyAccountRepository.MasterKeyProducer? = null): RegisterAccountResult =
suspend fun registerAccount(context: Context, sessionId: String?, registrationData: RegistrationData, 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
@ -434,8 +433,8 @@ object RegistrationRepository {
SignalStore.account.generatePniIdentityKeyIfNecessary()
val pniIdentity: IdentityKeyPair = SignalStore.account.pniIdentityKey
val aciPreKeyCollection = org.thoughtcrime.securesms.registration.RegistrationRepository.generateSignedAndLastResortPreKeys(aciIdentity, SignalStore.account.aciPreKeys)
val pniPreKeyCollection = org.thoughtcrime.securesms.registration.RegistrationRepository.generateSignedAndLastResortPreKeys(pniIdentity, SignalStore.account.pniPreKeys)
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)
.map { accountRegistrationResponse: VerifyAccountResponse ->
@ -589,6 +588,22 @@ object RegistrationRepository {
return started == true
}
private fun generateSignedAndLastResortPreKeys(identity: IdentityKeyPair, metadataStore: PreKeyMetadataStore): PreKeyCollection {
val signedPreKey = PreKeyUtil.generateSignedPreKey(metadataStore.nextSignedPreKeyId, identity.privateKey)
val lastResortKyberPreKey = PreKeyUtil.generateLastResortKyberPreKey(metadataStore.nextKyberPreKeyId, identity.privateKey)
return PreKeyCollection(
identity.publicKey,
signedPreKey,
lastResortKyberPreKey
)
}
fun interface MasterKeyProducer {
@Throws(IOException::class, SvrWrongPinException::class, SvrNoDataException::class)
fun produceMasterKey(): MasterKey
}
enum class Mode(val isSmsRetrieverSupported: Boolean, val transport: PushServiceSocket.VerificationCodeTransport) {
SMS_WITH_LISTENER(true, PushServiceSocket.VerificationCodeTransport.SMS),
SMS_WITHOUT_LISTENER(false, PushServiceSocket.VerificationCodeTransport.SMS),