mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Create account in single network request.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms.registration
|
||||
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey
|
||||
import org.whispersystems.signalservice.api.account.PreKeyCollections
|
||||
|
||||
data class RegistrationData(
|
||||
val code: String,
|
||||
@@ -8,6 +9,7 @@ data class RegistrationData(
|
||||
val password: String,
|
||||
val registrationId: Int,
|
||||
val profileKey: ProfileKey,
|
||||
val preKeyCollections: PreKeyCollections,
|
||||
val fcmToken: String?,
|
||||
val pniRegistrationId: Int,
|
||||
val recoveryPassword: String?
|
||||
|
||||
@@ -9,12 +9,13 @@ import androidx.annotation.WorkerThread;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
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.PreKeyRecord;
|
||||
import org.signal.libsignal.protocol.state.SignalProtocolStore;
|
||||
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.IdentityKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.SenderKeyUtil;
|
||||
@@ -37,8 +38,9 @@ import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
|
||||
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.KbsPinData;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountDataStore;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.account.PreKeyCollection;
|
||||
import org.whispersystems.signalservice.api.account.PreKeyCollections;
|
||||
import org.whispersystems.signalservice.api.account.PreKeyUpload;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
@@ -145,16 +147,17 @@ public final class RegistrationRepository {
|
||||
ApplicationDependencies.getProtocolStore().pni().sessions().archiveAllSessions();
|
||||
SenderKeyUtil.clearAllState();
|
||||
|
||||
SignalServiceAccountManager accountManager = AccountManagerFactory.getInstance().createAuthenticated(context, aci, pni, registrationData.getE164(), SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.getPassword());
|
||||
SignalServiceAccountDataStoreImpl aciProtocolStore = ApplicationDependencies.getProtocolStore().aci();
|
||||
SignalServiceAccountDataStoreImpl pniProtocolStore = ApplicationDependencies.getProtocolStore().pni();
|
||||
SignalServiceAccountDataStoreImpl aciProtocolStore = ApplicationDependencies.getProtocolStore().aci();
|
||||
PreKeyCollection aciPreKeyCollection = registrationData.getPreKeyCollections().getAciPreKeyCollection();
|
||||
PreKeyMetadataStore aciMetadataStore = SignalStore.account().aciPreKeys();
|
||||
|
||||
generateAndRegisterPreKeys(ServiceIdType.ACI, accountManager, aciProtocolStore, SignalStore.account().aciPreKeys());
|
||||
generateAndRegisterPreKeys(ServiceIdType.PNI, accountManager, pniProtocolStore, SignalStore.account().pniPreKeys());
|
||||
SignalServiceAccountDataStoreImpl pniProtocolStore = ApplicationDependencies.getProtocolStore().pni();
|
||||
PreKeyCollection pniPreKeyCollection = registrationData.getPreKeyCollections().getPniPreKeyCollection();
|
||||
PreKeyMetadataStore pniMetadataStore = SignalStore.account().pniPreKeys();
|
||||
|
||||
storePreKeys(aciProtocolStore, aciMetadataStore, aciPreKeyCollection);
|
||||
storePreKeys(pniProtocolStore, pniMetadataStore, pniPreKeyCollection);
|
||||
|
||||
if (registrationData.isFcm()) {
|
||||
accountManager.setGcmId(Optional.ofNullable(registrationData.getFcmToken()));
|
||||
}
|
||||
|
||||
RecipientTable recipientTable = SignalDatabase.recipients();
|
||||
RecipientId selfId = Recipient.trustedPush(aci, pni, registrationData.getE164()).getId();
|
||||
@@ -186,24 +189,57 @@ public final class RegistrationRepository {
|
||||
ApplicationDependencies.getIncomingMessageObserver();
|
||||
}
|
||||
|
||||
private void generateAndRegisterPreKeys(@NonNull ServiceIdType serviceIdType,
|
||||
@NonNull SignalServiceAccountManager accountManager,
|
||||
@NonNull SignalServiceAccountDataStore protocolStore,
|
||||
@NonNull PreKeyMetadataStore metadataStore)
|
||||
throws IOException
|
||||
{
|
||||
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore);
|
||||
List<PreKeyRecord> oneTimeEcPreKeys = PreKeyUtil.generateAndStoreOneTimeEcPreKeys(protocolStore, metadataStore);
|
||||
KyberPreKeyRecord lastResortKyberPreKey = PreKeyUtil.generateAndStoreLastResortKyberPreKey(protocolStore, metadataStore);
|
||||
List<KyberPreKeyRecord> oneTimeKyberPreKeys = PreKeyUtil.generateAndStoreOneTimeKyberPreKeys(protocolStore, metadataStore);
|
||||
public static @Nullable PreKeyCollections generatePreKeys() {
|
||||
final IdentityKeyPair keyPair = IdentityKeyUtil.generateIdentityKeyPair();
|
||||
final PreKeyMetadataStore aciMetadataStore = SignalStore.account().aciPreKeys();
|
||||
final PreKeyMetadataStore pniMetadataStore = SignalStore.account().pniPreKeys();
|
||||
|
||||
accountManager.setPreKeys(new PreKeyUpload(serviceIdType,
|
||||
protocolStore.getIdentityKeyPair().getPublicKey(),
|
||||
signedPreKey,
|
||||
oneTimeEcPreKeys,
|
||||
lastResortKyberPreKey,
|
||||
oneTimeKyberPreKeys));
|
||||
try {
|
||||
return new PreKeyCollections(keyPair,
|
||||
generatePreKeysForType(ServiceIdType.ACI, keyPair, aciMetadataStore),
|
||||
generatePreKeysForType(ServiceIdType.PNI, keyPair, pniMetadataStore)
|
||||
);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to generate prekeys!", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static PreKeyCollection generatePreKeysForType(ServiceIdType serviceIdType, IdentityKeyPair keyPair, PreKeyMetadataStore metadataStore) throws IOException {
|
||||
int nextSignedPreKeyId = metadataStore.getNextSignedPreKeyId();
|
||||
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateSignedPreKey(nextSignedPreKeyId, keyPair.getPrivateKey());
|
||||
metadataStore.setActiveSignedPreKeyId(signedPreKey.getId());
|
||||
|
||||
int ecOneTimePreKeyIdOffset = metadataStore.getNextEcOneTimePreKeyId();
|
||||
List<PreKeyRecord> oneTimeEcPreKeys = PreKeyUtil.generateOneTimeEcPreKeys(ecOneTimePreKeyIdOffset);
|
||||
|
||||
|
||||
int nextKyberPreKeyId = metadataStore.getNextKyberPreKeyId();
|
||||
KyberPreKeyRecord lastResortKyberPreKey = PreKeyUtil.generateKyberPreKey(nextKyberPreKeyId, keyPair.getPrivateKey());
|
||||
metadataStore.setLastResortKyberPreKeyId(nextKyberPreKeyId);
|
||||
|
||||
int oneTimeKyberPreKeyIdOffset = metadataStore.getNextKyberPreKeyId();
|
||||
List<KyberPreKeyRecord> oneTimeKyberPreKeys = PreKeyUtil.generateOneTimeKyberPreKeyRecords(oneTimeKyberPreKeyIdOffset, keyPair.getPrivateKey());
|
||||
|
||||
return new PreKeyCollection(
|
||||
nextSignedPreKeyId,
|
||||
ecOneTimePreKeyIdOffset,
|
||||
nextKyberPreKeyId,
|
||||
oneTimeKyberPreKeyIdOffset,
|
||||
serviceIdType,
|
||||
keyPair.getPublicKey(),
|
||||
signedPreKey,
|
||||
oneTimeEcPreKeys,
|
||||
lastResortKyberPreKey,
|
||||
oneTimeKyberPreKeys
|
||||
);
|
||||
}
|
||||
|
||||
private static void storePreKeys(SignalServiceAccountDataStoreImpl protocolStore, PreKeyMetadataStore metadataStore, PreKeyCollection preKeyCollection) {
|
||||
PreKeyUtil.storeSignedPreKey(protocolStore, metadataStore, preKeyCollection.getNextSignedPreKeyId(), preKeyCollection.getSignedPreKey());
|
||||
PreKeyUtil.storeOneTimeEcPreKeys(protocolStore, metadataStore, preKeyCollection.getEcOneTimePreKeyIdOffset(), preKeyCollection.getOneTimeEcPreKeys());
|
||||
PreKeyUtil.storeLastResortKyberPreKey(protocolStore, metadataStore, preKeyCollection.getLastResortKyberPreKeyId(), preKeyCollection.getLastResortKyberPreKey());
|
||||
PreKeyUtil.storeOneTimeKyberPreKeys(protocolStore, metadataStore, preKeyCollection.getOneTimeKyberPreKeyIdOffset(), preKeyCollection.getOneTimeKyberPreKeys());
|
||||
metadataStore.setSignedPreKeyRegistered(true);
|
||||
}
|
||||
|
||||
@@ -239,4 +275,5 @@ public final class RegistrationRepository {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ class VerifyAccountRepository(private val context: Application) {
|
||||
)
|
||||
|
||||
return Single.fromCallable {
|
||||
val response = accountManager.registerAccount(sessionId, registrationData.recoveryPassword, accountAttributes, true)
|
||||
val response = accountManager.registerAccount(sessionId, registrationData.recoveryPassword, accountAttributes, registrationData.preKeyCollections, registrationData.fcmToken, true)
|
||||
VerifyResponse.from(response, kbsData, pin)
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
@@ -235,6 +235,7 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel {
|
||||
getRegistrationSecret(),
|
||||
registrationRepository.getRegistrationId(),
|
||||
registrationRepository.getProfileKey(getNumber().getE164Number()),
|
||||
Objects.requireNonNull(RegistrationRepository.generatePreKeys()),
|
||||
getFcmToken(),
|
||||
registrationRepository.getPniRegistrationId(),
|
||||
getSessionId() != null ? null : getRecoveryPassword());
|
||||
|
||||
Reference in New Issue
Block a user