mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-27 14:40:22 +00:00
Fix atomic registrations when not using session ID.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package org.thoughtcrime.securesms.registration
|
||||
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey
|
||||
import org.whispersystems.signalservice.api.account.PreKeyCollections
|
||||
import org.whispersystems.signalservice.api.account.PreKeyCollection
|
||||
|
||||
data class RegistrationData(
|
||||
val code: String,
|
||||
@@ -9,7 +9,8 @@ data class RegistrationData(
|
||||
val password: String,
|
||||
val registrationId: Int,
|
||||
val profileKey: ProfileKey,
|
||||
val preKeyCollections: PreKeyCollections,
|
||||
val aciPreKeyCollection: PreKeyCollection,
|
||||
val pniPreKeyCollection: PreKeyCollection,
|
||||
val fcmToken: String?,
|
||||
val pniRegistrationId: Int,
|
||||
val recoveryPassword: String?
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.signal.libsignal.protocol.state.PreKeyRecord;
|
||||
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;
|
||||
@@ -40,8 +39,6 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.KbsPinData;
|
||||
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;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
@@ -148,11 +145,11 @@ public final class RegistrationRepository {
|
||||
SenderKeyUtil.clearAllState();
|
||||
|
||||
SignalServiceAccountDataStoreImpl aciProtocolStore = ApplicationDependencies.getProtocolStore().aci();
|
||||
PreKeyCollection aciPreKeyCollection = registrationData.getPreKeyCollections().getAciPreKeyCollection();
|
||||
PreKeyCollection aciPreKeyCollection = registrationData.getAciPreKeyCollection();
|
||||
PreKeyMetadataStore aciMetadataStore = SignalStore.account().aciPreKeys();
|
||||
|
||||
SignalServiceAccountDataStoreImpl pniProtocolStore = ApplicationDependencies.getProtocolStore().pni();
|
||||
PreKeyCollection pniPreKeyCollection = registrationData.getPreKeyCollections().getPniPreKeyCollection();
|
||||
PreKeyCollection pniPreKeyCollection = registrationData.getPniPreKeyCollection();
|
||||
PreKeyMetadataStore pniMetadataStore = SignalStore.account().pniPreKeys();
|
||||
|
||||
storePreKeys(aciProtocolStore, aciMetadataStore, aciPreKeyCollection);
|
||||
@@ -189,23 +186,24 @@ public final class RegistrationRepository {
|
||||
ApplicationDependencies.getIncomingMessageObserver();
|
||||
}
|
||||
|
||||
public static @Nullable PreKeyCollections generatePreKeys() {
|
||||
final IdentityKeyPair keyPair = IdentityKeyUtil.generateIdentityKeyPair();
|
||||
final PreKeyMetadataStore aciMetadataStore = SignalStore.account().aciPreKeys();
|
||||
final PreKeyMetadataStore pniMetadataStore = SignalStore.account().pniPreKeys();
|
||||
|
||||
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;
|
||||
public static PreKeyCollection generatePreKeysForType(ServiceIdType serviceIdType) {
|
||||
IdentityKeyPair keyPair;
|
||||
PreKeyMetadataStore metadataStore;
|
||||
if (serviceIdType == ServiceIdType.ACI) {
|
||||
if (!SignalStore.account().hasAciIdentityKey()) {
|
||||
SignalStore.account().generateAciIdentityKeyIfNecessary();
|
||||
}
|
||||
keyPair = SignalStore.account().getAciIdentityKey();
|
||||
metadataStore = SignalStore.account().aciPreKeys();
|
||||
} else if (serviceIdType == ServiceIdType.PNI) {
|
||||
if (!SignalStore.account().hasPniIdentityKey()) {
|
||||
SignalStore.account().generatePniIdentityKeyIfNecessary();
|
||||
}
|
||||
keyPair = SignalStore.account().getPniIdentityKey();
|
||||
metadataStore = SignalStore.account().pniPreKeys();
|
||||
} else {
|
||||
throw new IllegalArgumentException("serviceIdType is not one of {ACI, PNI}");
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
@@ -222,6 +220,7 @@ public final class RegistrationRepository {
|
||||
List<KyberPreKeyRecord> oneTimeKyberPreKeys = PreKeyUtil.generateOneTimeKyberPreKeyRecords(oneTimeKyberPreKeyIdOffset, keyPair.getPrivateKey());
|
||||
|
||||
return new PreKeyCollection(
|
||||
keyPair,
|
||||
nextSignedPreKeyId,
|
||||
ecOneTimePreKeyIdOffset,
|
||||
nextKyberPreKeyId,
|
||||
|
||||
@@ -186,7 +186,7 @@ class VerifyAccountRepository(private val context: Application) {
|
||||
)
|
||||
|
||||
return Single.fromCallable {
|
||||
val response = accountManager.registerAccount(sessionId, registrationData.recoveryPassword, accountAttributes, registrationData.preKeyCollections, registrationData.fcmToken, true)
|
||||
val response = accountManager.registerAccount(sessionId, registrationData.recoveryPassword, accountAttributes, registrationData.aciPreKeyCollection, registrationData.pniPreKeyCollection, registrationData.fcmToken, true)
|
||||
VerifyResponse.from(response, kbsData, pin)
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.signalservice.api.KbsPinData;
|
||||
import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException;
|
||||
import org.whispersystems.signalservice.api.kbs.PinHashUtil;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.IncorrectCodeException;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
import org.whispersystems.signalservice.internal.contacts.entities.TokenResponse;
|
||||
@@ -235,7 +236,8 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel {
|
||||
getRegistrationSecret(),
|
||||
registrationRepository.getRegistrationId(),
|
||||
registrationRepository.getProfileKey(getNumber().getE164Number()),
|
||||
Objects.requireNonNull(RegistrationRepository.generatePreKeys()),
|
||||
RegistrationRepository.generatePreKeysForType(ServiceIdType.ACI),
|
||||
RegistrationRepository.generatePreKeysForType(ServiceIdType.PNI),
|
||||
getFcmToken(),
|
||||
registrationRepository.getPniRegistrationId(),
|
||||
getSessionId() != null ? null : getRecoveryPassword());
|
||||
|
||||
Reference in New Issue
Block a user