Add support for PNI registration ids and PNP change number.

This commit is contained in:
Cody Henthorne
2022-08-03 11:50:16 -04:00
parent 0d3ea22641
commit 83b97d274f
54 changed files with 1273 additions and 188 deletions

View File

@@ -38,6 +38,7 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal
private const val KEY_FCM_TOKEN_LAST_SET_TIME = "account.fcm_token_last_set_time"
private const val KEY_DEVICE_NAME = "account.device_name"
private const val KEY_DEVICE_ID = "account.device_id"
private const val KEY_PNI_REGISTRATION_ID = "account.pni_registration_id"
private const val KEY_ACI_IDENTITY_PUBLIC_KEY = "account.aci_identity_public_key"
private const val KEY_ACI_IDENTITY_PRIVATE_KEY = "account.aci_identity_private_key"
@@ -135,6 +136,8 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal
/** A randomly-generated value that represents this registration instance. Helps the server know if you reinstalled. */
var registrationId: Int by integerValue(KEY_REGISTRATION_ID, 0)
var pniRegistrationId: Int by integerValue(KEY_PNI_REGISTRATION_ID, 0)
/** The identity key pair for the ACI identity. */
val aciIdentityKey: IdentityKeyPair
get() {
@@ -202,7 +205,7 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal
}
/** When acting as a linked device, this method lets you store the identity keys sent from the primary device */
fun setIdentityKeysFromPrimaryDevice(aciKeys: IdentityKeyPair) {
fun setAciIdentityKeysFromPrimaryDevice(aciKeys: IdentityKeyPair) {
synchronized(this) {
require(isLinkedDevice) { "Must be a linked device!" }
store
@@ -213,6 +216,19 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal
}
}
/** Set an identity key pair for the PNI identity via change number. */
fun setPniIdentityKeyAfterChangeNumber(key: IdentityKeyPair) {
synchronized(this) {
Log.i(TAG, "Setting a new PNI identity key pair.")
store
.beginWrite()
.putBlob(KEY_PNI_IDENTITY_PUBLIC_KEY, key.publicKey.serialize())
.putBlob(KEY_PNI_IDENTITY_PRIVATE_KEY, key.privateKey.serialize())
.commit()
}
}
/** Only to be used when restoring an identity public key from an old backup */
fun restoreLegacyIdentityPublicKeyFromBackup(base64: String) {
Log.w(TAG, "Restoring legacy identity public key from backup.")

View File

@@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.keyvalue;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.database.model.databaseprotos.PendingChangeNumberMetadata;
import java.util.Collections;
import java.util.List;
@@ -17,6 +19,7 @@ public final class MiscellaneousValues extends SignalStoreValues {
private static final String OLD_DEVICE_TRANSFER_LOCKED = "misc.old_device.transfer.locked";
private static final String HAS_EVER_HAD_AN_AVATAR = "misc.has.ever.had.an.avatar";
private static final String CHANGE_NUMBER_LOCK = "misc.change_number.lock";
private static final String PENDING_CHANGE_NUMBER_METADATA = "misc.pending_change_number.metadata";
private static final String CENSORSHIP_LAST_CHECK_TIME = "misc.censorship.last_check_time";
private static final String CENSORSHIP_SERVICE_REACHABLE = "misc.censorship.service_reachable";
private static final String LAST_GV2_PROFILE_CHECK_TIME = "misc.last_gv2_profile_check_time";
@@ -117,6 +120,20 @@ public final class MiscellaneousValues extends SignalStoreValues {
putBoolean(CHANGE_NUMBER_LOCK, false);
}
public @Nullable PendingChangeNumberMetadata getPendingChangeNumberMetadata() {
return getObject(PENDING_CHANGE_NUMBER_METADATA, null, PendingChangeNumberMetadataSerializer.INSTANCE);
}
/** Store pending new PNI data to be applied after successful change number */
public void setPendingChangeNumberMetadata(@NonNull PendingChangeNumberMetadata metadata) {
putObject(PENDING_CHANGE_NUMBER_METADATA, metadata, PendingChangeNumberMetadataSerializer.INSTANCE);
}
/** Clear pending new PNI data after confirmed successful or failed change number */
public void clearPendingChangeNumberMetadata() {
remove(PENDING_CHANGE_NUMBER_METADATA);
}
public long getLastCensorshipServiceReachabilityCheckTime() {
return getLong(CENSORSHIP_LAST_CHECK_TIME, 0);
}

View File

@@ -0,0 +1,12 @@
package org.thoughtcrime.securesms.keyvalue
import org.signal.core.util.ByteSerializer
import org.thoughtcrime.securesms.database.model.databaseprotos.PendingChangeNumberMetadata
/**
* Serialize [PendingChangeNumberMetadata]
*/
object PendingChangeNumberMetadataSerializer : ByteSerializer<PendingChangeNumberMetadata> {
override fun serialize(data: PendingChangeNumberMetadata): ByteArray = data.toByteArray()
override fun deserialize(data: ByteArray): PendingChangeNumberMetadata = PendingChangeNumberMetadata.parseFrom(data)
}

View File

@@ -1,9 +1,11 @@
package org.thoughtcrime.securesms.keyvalue;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.protobuf.InvalidProtocolBufferException;
import org.signal.core.util.ByteSerializer;
import org.signal.core.util.StringSerializer;
import org.thoughtcrime.securesms.database.model.databaseprotos.SignalStoreList;
@@ -51,6 +53,15 @@ abstract class SignalStoreValues {
return store.getBlob(key, defaultValue);
}
<T> T getObject(@NonNull String key, @Nullable T defaultValue, @NonNull ByteSerializer<T> serializer) {
byte[] blob = store.getBlob(key, null);
if (blob == null) {
return defaultValue;
} else {
return serializer.deserialize(blob);
}
}
<T> List<T> getList(@NonNull String key, @NonNull StringSerializer<T> serializer) {
byte[] blob = getBlob(key, null);
if (blob == null) {
@@ -94,6 +105,10 @@ abstract class SignalStoreValues {
store.beginWrite().putString(key, value).apply();
}
<T> void putObject(@NonNull String key, T value, @NonNull ByteSerializer<T> serializer) {
putBlob(key, serializer.serialize(value));
}
<T> void putList(@NonNull String key, @NonNull List<T> values, @NonNull StringSerializer<T> serializer) {
putBlob(key, SignalStoreList.newBuilder()
.addAllContents(values.stream()