mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 01:01:15 +01:00
Check structural validity of prekeys at upload time
This commit is contained in:
committed by
GitHub
parent
0ab66f2f14
commit
ecd207f0a1
@@ -18,6 +18,8 @@ import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey.PreKeyType;
|
||||
|
||||
public record ChangeNumberRequest(
|
||||
@Schema(description="""
|
||||
@@ -49,7 +51,7 @@ public record ChangeNumberRequest(
|
||||
@Schema(description="""
|
||||
A new signed elliptic-curve prekey for each enabled device on the account, including this one.
|
||||
Each must be accompanied by a valid signature from the new identity key in this request.""")
|
||||
@NotNull @Valid Map<Long, @NotNull @Valid SignedPreKey> devicePniSignedPrekeys,
|
||||
@NotNull @Valid Map<Long, @NotNull @Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> devicePniSignedPrekeys,
|
||||
|
||||
@Schema(description="""
|
||||
A new signed post-quantum last-resort prekey for each enabled device on the account, including this one.
|
||||
@@ -57,7 +59,7 @@ public record ChangeNumberRequest(
|
||||
If present, must contain one prekey per enabled device including this one.
|
||||
Prekeys for devices that did not previously have any post-quantum prekeys stored will be silently dropped.
|
||||
Each must be accompanied by a valid signature from the new identity key in this request.""")
|
||||
@Valid Map<Long, @NotNull @Valid SignedPreKey> devicePniPqLastResortPrekeys,
|
||||
@Valid Map<Long, @NotNull @Valid @ValidPreKey(type=PreKeyType.KYBER) SignedPreKey> devicePniPqLastResortPrekeys,
|
||||
|
||||
@Schema(description="the new phone-number-identity registration ID for each enabled device on the account, including this one")
|
||||
@NotNull Map<Long, Integer> pniRegistrationIds) implements PhoneVerificationRequest {
|
||||
|
||||
@@ -18,6 +18,8 @@ import javax.annotation.Nullable;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey.PreKeyType;
|
||||
|
||||
public record ChangePhoneNumberRequest(
|
||||
@Schema(description="the new phone number for this account")
|
||||
@@ -42,7 +44,7 @@ public record ChangePhoneNumberRequest(
|
||||
@Schema(description="""
|
||||
A new signed elliptic-curve prekey for each enabled device on the account, including this one.
|
||||
Each must be accompanied by a valid signature from the new identity key in this request.""")
|
||||
@Nullable Map<Long, SignedPreKey> devicePniSignedPrekeys,
|
||||
@Nullable Map<Long, @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> devicePniSignedPrekeys,
|
||||
|
||||
@Schema(description="""
|
||||
A new signed post-quantum last-resort prekey for each enabled device on the account, including this one.
|
||||
@@ -50,7 +52,7 @@ public record ChangePhoneNumberRequest(
|
||||
If present, must contain one prekey per enabled device including this one.
|
||||
Prekeys for devices that did not previously have any post-quantum prekeys stored will be silently dropped.
|
||||
Each must be accompanied by a valid signature from the new identity key in this request.""")
|
||||
@Nullable @Valid Map<Long, @NotNull @Valid SignedPreKey> devicePniPqLastResortPrekeys,
|
||||
@Nullable @Valid Map<Long, @NotNull @Valid @ValidPreKey(type=PreKeyType.KYBER) SignedPreKey> devicePniPqLastResortPrekeys,
|
||||
|
||||
@Schema(description="the new phone-number-identity registration ID for each enabled device on the account, including this one")
|
||||
@Nullable Map<Long, Integer> pniRegistrationIds) {
|
||||
|
||||
@@ -3,6 +3,10 @@ package org.whispersystems.textsecuregcm.entities;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey.PreKeyType;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public record DeviceActivationRequest(@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = """
|
||||
@@ -10,28 +14,28 @@ public record DeviceActivationRequest(@Schema(requiredMode = Schema.RequiredMode
|
||||
will be created "atomically," and all other properties needed for atomic account
|
||||
creation must also be present.
|
||||
""")
|
||||
Optional<@Valid SignedPreKey> aciSignedPreKey,
|
||||
Optional<@Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> aciSignedPreKey,
|
||||
|
||||
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = """
|
||||
A signed EC pre-key to be associated with this account's PNI. If provided, an account
|
||||
will be created "atomically," and all other properties needed for atomic account
|
||||
creation must also be present.
|
||||
""")
|
||||
Optional<@Valid SignedPreKey> pniSignedPreKey,
|
||||
Optional<@Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> pniSignedPreKey,
|
||||
|
||||
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = """
|
||||
A signed Kyber-1024 "last resort" pre-key to be associated with this account's ACI. If
|
||||
provided, an account will be created "atomically," and all other properties needed for
|
||||
atomic account creation must also be present.
|
||||
""")
|
||||
Optional<@Valid SignedPreKey> aciPqLastResortPreKey,
|
||||
Optional<@Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> aciPqLastResortPreKey,
|
||||
|
||||
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = """
|
||||
A signed Kyber-1024 "last resort" pre-key to be associated with this account's PNI. If
|
||||
provided, an account will be created "atomically," and all other properties needed for
|
||||
atomic account creation must also be present.
|
||||
""")
|
||||
Optional<@Valid SignedPreKey> pniPqLastResortPreKey,
|
||||
Optional<@Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> pniPqLastResortPreKey,
|
||||
|
||||
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = """
|
||||
An APNs token set for the account's primary device. If provided, the account's primary
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -15,7 +14,12 @@ import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
|
||||
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey.PreKeyType;
|
||||
|
||||
public record PhoneNumberIdentityKeyDistributionRequest(
|
||||
@NotEmpty
|
||||
@@ -36,7 +40,7 @@ public record PhoneNumberIdentityKeyDistributionRequest(
|
||||
@Schema(description="""
|
||||
A new signed elliptic-curve prekey for each enabled device on the account, including this one.
|
||||
Each must be accompanied by a valid signature from the new identity key in this request.""")
|
||||
Map<Long, @NotNull @Valid SignedPreKey> devicePniSignedPrekeys,
|
||||
Map<Long, @NotNull @Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> devicePniSignedPrekeys,
|
||||
|
||||
@Schema(description="""
|
||||
A new signed post-quantum last-resort prekey for each enabled device on the account, including this one.
|
||||
@@ -44,7 +48,7 @@ public record PhoneNumberIdentityKeyDistributionRequest(
|
||||
If present, must contain one prekey per enabled device including this one.
|
||||
Prekeys for devices that did not previously have any post-quantum prekeys stored will be silently dropped.
|
||||
Each must be accompanied by a valid signature from the new identity key in this request.""")
|
||||
@Valid Map<Long, @NotNull @Valid SignedPreKey> devicePniPqLastResortPrekeys,
|
||||
@Valid Map<Long, @NotNull @Valid @ValidPreKey(type=PreKeyType.KYBER) SignedPreKey> devicePniPqLastResortPrekeys,
|
||||
|
||||
@NotNull
|
||||
@Valid
|
||||
|
||||
@@ -16,6 +16,8 @@ import javax.validation.Valid;
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey.PreKeyType;
|
||||
|
||||
public class PreKeyState {
|
||||
|
||||
@@ -24,10 +26,11 @@ public class PreKeyState {
|
||||
@Schema(description="A list of unsigned elliptic-curve prekeys to use for this device. " +
|
||||
"If present and not empty, replaces all stored unsigned EC prekeys for the device; " +
|
||||
"if absent or empty, any stored unsigned EC prekeys for the device are not deleted.")
|
||||
private List<PreKey> preKeys;
|
||||
private List<@ValidPreKey(type=PreKeyType.ECC) PreKey> preKeys;
|
||||
|
||||
@JsonProperty
|
||||
@Valid
|
||||
@ValidPreKey(type=PreKeyType.ECC)
|
||||
@Schema(description="An optional signed elliptic-curve prekey to use for this device. " +
|
||||
"If present, replaces the stored signed elliptic-curve prekey for the device; " +
|
||||
"if absent, the stored signed prekey is not deleted. " +
|
||||
@@ -40,10 +43,11 @@ public class PreKeyState {
|
||||
"Each key must have a valid signature from the identity key in this request. " +
|
||||
"If present and not empty, replaces all stored unsigned PQ prekeys for the device; " +
|
||||
"if absent or empty, any stored unsigned PQ prekeys for the device are not deleted.")
|
||||
private List<SignedPreKey> pqPreKeys;
|
||||
private List<@ValidPreKey(type=PreKeyType.KYBER) SignedPreKey> pqPreKeys;
|
||||
|
||||
@JsonProperty
|
||||
@Valid
|
||||
@ValidPreKey(type=PreKeyType.KYBER)
|
||||
@Schema(description="An optional signed last-resort post-quantum prekey to use for this device. " +
|
||||
"If present, replaces the stored signed post-quantum last-resort prekey for the device; " +
|
||||
"if absent, a stored last-resort prekey will *not* be deleted. " +
|
||||
@@ -110,4 +114,5 @@ public class PreKeyState {
|
||||
}
|
||||
return spks.isEmpty() || PreKeySignatureValidator.validatePreKeySignatures(identityKey, spks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
|
||||
import org.whispersystems.textsecuregcm.util.OptionalBase64ByteArrayDeserializer;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey;
|
||||
import org.whispersystems.textsecuregcm.util.ValidPreKey.PreKeyType;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
@@ -73,17 +75,17 @@ public record RegistrationRequest(@Schema(requiredMode = Schema.RequiredMode.NOT
|
||||
@JsonCreator
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public RegistrationRequest(@JsonProperty("sessionId") String sessionId,
|
||||
@JsonProperty("recoveryPassword") byte[] recoveryPassword,
|
||||
@JsonProperty("accountAttributes") AccountAttributes accountAttributes,
|
||||
@JsonProperty("skipDeviceTransfer") boolean skipDeviceTransfer,
|
||||
@JsonProperty("aciIdentityKey") Optional<byte[]> aciIdentityKey,
|
||||
@JsonProperty("pniIdentityKey") Optional<byte[]> pniIdentityKey,
|
||||
@JsonProperty("aciSignedPreKey") Optional<@Valid SignedPreKey> aciSignedPreKey,
|
||||
@JsonProperty("pniSignedPreKey") Optional<@Valid SignedPreKey> pniSignedPreKey,
|
||||
@JsonProperty("aciPqLastResortPreKey") Optional<@Valid SignedPreKey> aciPqLastResortPreKey,
|
||||
@JsonProperty("pniPqLastResortPreKey") Optional<@Valid SignedPreKey> pniPqLastResortPreKey,
|
||||
@JsonProperty("apnToken") Optional<@Valid ApnRegistrationId> apnToken,
|
||||
@JsonProperty("gcmToken") Optional<@Valid GcmRegistrationId> gcmToken) {
|
||||
@JsonProperty("recoveryPassword") byte[] recoveryPassword,
|
||||
@JsonProperty("accountAttributes") AccountAttributes accountAttributes,
|
||||
@JsonProperty("skipDeviceTransfer") boolean skipDeviceTransfer,
|
||||
@JsonProperty("aciIdentityKey") Optional<byte[]> aciIdentityKey,
|
||||
@JsonProperty("pniIdentityKey") Optional<byte[]> pniIdentityKey,
|
||||
@JsonProperty("aciSignedPreKey") Optional<@Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> aciSignedPreKey,
|
||||
@JsonProperty("pniSignedPreKey") Optional<@Valid @ValidPreKey(type=PreKeyType.ECC) SignedPreKey> pniSignedPreKey,
|
||||
@JsonProperty("aciPqLastResortPreKey") Optional<@Valid @ValidPreKey(type=PreKeyType.KYBER) SignedPreKey> aciPqLastResortPreKey,
|
||||
@JsonProperty("pniPqLastResortPreKey") Optional<@Valid @ValidPreKey(type=PreKeyType.KYBER) SignedPreKey> pniPqLastResortPreKey,
|
||||
@JsonProperty("apnToken") Optional<@Valid ApnRegistrationId> apnToken,
|
||||
@JsonProperty("gcmToken") Optional<@Valid GcmRegistrationId> gcmToken) {
|
||||
|
||||
// This may seem a little verbose, but at the time of writing, Jackson struggles with `@JsonUnwrapped` members in
|
||||
// records, and this is a workaround. Please see
|
||||
|
||||
Reference in New Issue
Block a user