Add kyber support for change number.

This commit is contained in:
Greyson Parrelli 2023-05-24 07:42:13 -07:00 committed by Cody Henthorne
parent e2ef8e2ef9
commit 0aca03a919
3 changed files with 40 additions and 12 deletions

View file

@ -7,7 +7,9 @@ import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.logging.Log
import org.signal.libsignal.protocol.IdentityKeyPair
import org.signal.libsignal.protocol.SignalProtocolAddress
import org.signal.libsignal.protocol.state.KyberPreKeyRecord
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.protocol.util.Medium
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
@ -38,6 +40,7 @@ import org.whispersystems.signalservice.api.push.ServiceIdType
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.api.push.SignedPreKeyEntity
import org.whispersystems.signalservice.internal.ServiceResponse
import org.whispersystems.signalservice.internal.push.KyberPreKeyEntity
import org.whispersystems.signalservice.internal.push.OutgoingPushMessage
import org.whispersystems.signalservice.internal.push.RegistrationSessionMetadataResponse
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.SyncMessage
@ -320,6 +323,7 @@ class ChangeNumberRepository(
val pniIdentity: IdentityKeyPair = if (pniUpdateMode) SignalStore.account().pniIdentityKey else IdentityKeyUtil.generateIdentityKeyPair()
val deviceMessages = mutableListOf<OutgoingPushMessage>()
val devicePniSignedPreKeys = mutableMapOf<Int, SignedPreKeyEntity>()
val devicePniLastResortKyberPreKeys = mutableMapOf<Int, KyberPreKeyEntity>()
val pniRegistrationIds = mutableMapOf<Int, Int>()
val primaryDeviceId: Int = SignalServiceAddress.DEFAULT_DEVICE_ID
@ -329,7 +333,7 @@ class ChangeNumberRepository(
.filter { it == primaryDeviceId || aciProtocolStore.containsSession(SignalProtocolAddress(selfIdentifier, it)) }
.forEach { deviceId ->
// Signed Prekeys
val signedPreKeyRecord = if (deviceId == primaryDeviceId) {
val signedPreKeyRecord: SignedPreKeyRecord = if (deviceId == primaryDeviceId) {
if (pniUpdateMode) {
ApplicationDependencies.getProtocolStore().pni().loadSignedPreKey(SignalStore.account().pniPreKeys.activeSignedPreKeyId)
} else {
@ -340,6 +344,18 @@ class ChangeNumberRepository(
}
devicePniSignedPreKeys[deviceId] = SignedPreKeyEntity(signedPreKeyRecord.id, signedPreKeyRecord.keyPair.publicKey, signedPreKeyRecord.signature)
// Last-resort kyber prekeys
val lastResortKyberPreKeyRecord: KyberPreKeyRecord = if (deviceId == primaryDeviceId) {
if (pniUpdateMode) {
ApplicationDependencies.getProtocolStore().pni().loadKyberPreKey(SignalStore.account().pniPreKeys.lastResortKyberPreKeyId)
} else {
PreKeyUtil.generateAndStoreLastResortKyberPreKey(ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys, pniIdentity.privateKey)
}
} else {
PreKeyUtil.generateKyberPreKey(SecureRandom().nextInt(Medium.MAX_VALUE), pniIdentity.privateKey)
}
devicePniLastResortKyberPreKeys[deviceId] = KyberPreKeyEntity(lastResortKyberPreKeyRecord.id, lastResortKyberPreKeyRecord.keyPair.publicKey, lastResortKyberPreKeyRecord.signature)
// Registration Ids
var pniRegistrationId = if (deviceId == primaryDeviceId && pniUpdateMode) {
SignalStore.account().pniRegistrationId
@ -357,7 +373,9 @@ class ChangeNumberRepository(
val pniChangeNumber = SyncMessage.PniChangeNumber.newBuilder()
.setIdentityKeyPair(pniIdentity.serialize().toProtoByteString())
.setSignedPreKey(signedPreKeyRecord.serialize().toProtoByteString())
.setLastResortKyberPreKey(lastResortKyberPreKeyRecord.serialize().toProtoByteString())
.setRegistrationId(pniRegistrationId)
.setNewE164(newE164)
.build()
deviceMessages += messageSender.getEncryptedSyncPniChangeNumberMessage(deviceId, pniChangeNumber)
@ -372,6 +390,7 @@ class ChangeNumberRepository(
pniIdentity.publicKey,
deviceMessages,
devicePniSignedPreKeys.mapKeys { it.key.toString() },
devicePniLastResortKyberPreKeys.mapKeys { it.key.toString() },
pniRegistrationIds.mapKeys { it.key.toString() }
)

View file

@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.signal.libsignal.protocol.IdentityKey;
import org.whispersystems.signalservice.api.push.SignedPreKeyEntity;
import org.whispersystems.signalservice.internal.push.KyberPreKeyEntity;
import org.whispersystems.signalservice.internal.push.OutgoingPushMessage;
import org.whispersystems.signalservice.internal.util.JsonUtil;
@ -36,6 +37,9 @@ public final class ChangePhoneNumberRequest {
@JsonProperty
private Map<String, SignedPreKeyEntity> devicePniSignedPrekeys;
@JsonProperty("devicePniPqLastResortPrekeys")
private Map<String, KyberPreKeyEntity> devicePniLastResortKyberPrekeys;
@JsonProperty
private Map<String, Integer> pniRegistrationIds;
@ -49,16 +53,18 @@ public final class ChangePhoneNumberRequest {
IdentityKey pniIdentityKey,
List<OutgoingPushMessage> deviceMessages,
Map<String, SignedPreKeyEntity> devicePniSignedPrekeys,
Map<String, KyberPreKeyEntity> devicePniLastResortKyberPrekeys,
Map<String, Integer> pniRegistrationIds)
{
this.sessionId = sessionId;
this.recoveryPassword = recoveryPassword;
this.number = number;
this.registrationLock = registrationLock;
this.pniIdentityKey = pniIdentityKey;
this.deviceMessages = deviceMessages;
this.devicePniSignedPrekeys = devicePniSignedPrekeys;
this.pniRegistrationIds = pniRegistrationIds;
this.sessionId = sessionId;
this.recoveryPassword = recoveryPassword;
this.number = number;
this.registrationLock = registrationLock;
this.pniIdentityKey = pniIdentityKey;
this.deviceMessages = deviceMessages;
this.devicePniSignedPrekeys = devicePniSignedPrekeys;
this.devicePniLastResortKyberPrekeys = devicePniLastResortKyberPrekeys;
this.pniRegistrationIds = pniRegistrationIds;
}
public String getNumber() {

View file

@ -590,9 +590,12 @@ message SyncMessage {
}
message PniChangeNumber {
optional bytes identityKeyPair = 1; // Serialized libsignal-client IdentityKeyPair
optional bytes signedPreKey = 2; // Serialized libsignal-client SignedPreKeyRecord
optional uint32 registrationId = 3;
optional bytes identityKeyPair = 1; // Serialized libsignal-client IdentityKeyPair
optional bytes signedPreKey = 2; // Serialized libsignal-client SignedPreKeyRecord
optional bytes lastResortKyberPreKey = 5; // Serialized libsignal-client KyberPreKeyRecord
optional uint32 registrationId = 3;
optional string newE164 = 4; // The e164 we have changed our number to
// Next ID: 6
}
message CallEvent {