Support PNI prekeys.

This commit is contained in:
Greyson Parrelli
2022-02-01 14:09:04 -05:00
parent db534cd376
commit e8ad1e8ed1
32 changed files with 808 additions and 532 deletions

View File

@@ -97,9 +97,10 @@ public class ApplicationMigrations {
static final int FIX_EMOJI_QUALITY = 53;
static final int CHANGE_NUMBER_CAPABILITY_4 = 54;
static final int KBS_MIGRATION = 55;
static final int PNI_IDENTITY = 56;
}
public static final int CURRENT_VERSION = 55;
public static final int CURRENT_VERSION = 56;
/**
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
@@ -421,6 +422,10 @@ public class ApplicationMigrations {
jobs.put(Version.KBS_MIGRATION, new KbsEnclaveMigrationJob());
}
if (lastSeenVersion < Version.PNI_IDENTITY) {
jobs.put(Version.PNI_IDENTITY, new PniAccountInitializationMigrationJob());
}
return jobs;
}

View File

@@ -130,7 +130,7 @@ public class LegacyMigrationJob extends MigrationJob {
}
if (lastSeenVersion < SIGNED_PREKEY_VERSION) {
ApplicationDependencies.getJobManager().add(new CreateSignedPreKeyJob(context));
CreateSignedPreKeyJob.enqueueIfNeeded();
}
if (lastSeenVersion < NO_DECRYPT_QUEUE_VERSION) {

View File

@@ -0,0 +1,89 @@
package org.thoughtcrime.securesms.migrations;
import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.jobs.KbsEnclaveMigrationWorkerJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.libsignal.state.PreKeyRecord;
import org.whispersystems.libsignal.state.SignalProtocolStore;
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.PNI;
import java.io.IOException;
import java.util.List;
/**
* Initializes various aspects of the PNI identity. Notably:
* - Creates an identity key
* - Creates and uploads one-time prekeys
* - Creates and uploads signed prekeys
*/
public class PniAccountInitializationMigrationJob extends MigrationJob {
private static final String TAG = Log.tag(PniAccountInitializationMigrationJob.class);
public static final String KEY = "PniAccountInitializationMigrationJob";
PniAccountInitializationMigrationJob() {
this(new Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.build());
}
private PniAccountInitializationMigrationJob(@NonNull Parameters parameters) {
super(parameters);
}
@Override
public boolean isUiBlocking() {
return false;
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
public void performMigration() throws IOException {
PNI pni = SignalStore.account().getPni();
if (!Recipient.self().isRegistered() || pni == null) {
Log.w(TAG, "Not yet registered! No need to perform this migration.");
return;
}
SignalStore.account().generatePniIdentityKey();
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
SignalProtocolStore protocolStore = ApplicationDependencies.getProtocolStore().pni();
PreKeyMetadataStore metadataStore = SignalStore.account().pniPreKeys();
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, true);
List<PreKeyRecord> oneTimePreKeys = PreKeyUtil.generateAndStoreOneTimePreKeys(protocolStore, metadataStore);
accountManager.setPreKeys(pni, protocolStore.getIdentityKeyPair().getPublicKey(), signedPreKey, oneTimePreKeys);
metadataStore.setSignedPreKeyRegistered(true);
}
@Override
boolean shouldRetry(@NonNull Exception e) {
return e instanceof IOException;
}
public static class Factory implements Job.Factory<PniAccountInitializationMigrationJob> {
@Override
public @NonNull PniAccountInitializationMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new PniAccountInitializationMigrationJob(parameters);
}
}
}