mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 13:08:05 +01:00
Add debugging context to signature validation failures
This commit is contained in:
committed by
Jon Chambers
parent
8a587d1d12
commit
a733f5c615
@@ -68,8 +68,7 @@ public record ChangeNumberRequest(
|
||||
@Schema(description="the new phone-number-identity registration ID for each enabled device on the account, including this one")
|
||||
@NotNull Map<Byte, Integer> pniRegistrationIds) implements PhoneVerificationRequest {
|
||||
|
||||
@AssertTrue
|
||||
public boolean isSignatureValidOnEachSignedPreKey() {
|
||||
public boolean isSignatureValidOnEachSignedPreKey(@Nullable final String userAgent) {
|
||||
List<SignedPreKey<?>> spks = new ArrayList<>();
|
||||
if (devicePniSignedPrekeys != null) {
|
||||
spks.addAll(devicePniSignedPrekeys.values());
|
||||
@@ -77,7 +76,7 @@ public record ChangeNumberRequest(
|
||||
if (devicePniPqLastResortPrekeys != null) {
|
||||
spks.addAll(devicePniPqLastResortPrekeys.values());
|
||||
}
|
||||
return spks.isEmpty() || PreKeySignatureValidator.validatePreKeySignatures(pniIdentityKey, spks);
|
||||
return spks.isEmpty() || PreKeySignatureValidator.validatePreKeySignatures(pniIdentityKey, spks, userAgent, "change-number");
|
||||
}
|
||||
|
||||
@AssertTrue
|
||||
|
||||
@@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.NotNull;
|
||||
@@ -53,13 +54,12 @@ public record PhoneNumberIdentityKeyDistributionRequest(
|
||||
@Schema(description="The new registration ID to use for the phone-number identity of each device, including this one.")
|
||||
Map<Byte, Integer> pniRegistrationIds) {
|
||||
|
||||
@AssertTrue
|
||||
public boolean isSignatureValidOnEachSignedPreKey() {
|
||||
public boolean isSignatureValidOnEachSignedPreKey(@Nullable final String userAgent) {
|
||||
List<SignedPreKey<?>> spks = new ArrayList<>(devicePniSignedPrekeys.values());
|
||||
if (devicePniPqLastResortPrekeys != null) {
|
||||
spks.addAll(devicePniPqLastResortPrekeys.values());
|
||||
}
|
||||
return spks.isEmpty() || PreKeySignatureValidator.validatePreKeySignatures(pniIdentityKey, spks);
|
||||
return spks.isEmpty() || PreKeySignatureValidator.validatePreKeySignatures(pniIdentityKey, spks, userAgent, "distribute-pni-keys");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,22 +4,31 @@
|
||||
*/
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import static com.codahale.metrics.MetricRegistry.name;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import java.util.Collection;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import org.signal.libsignal.protocol.IdentityKey;
|
||||
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
|
||||
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class PreKeySignatureValidator {
|
||||
public static final Counter INVALID_SIGNATURE_COUNTER =
|
||||
Metrics.counter(name(PreKeySignatureValidator.class, "invalidPreKeySignature"));
|
||||
public static final String INVALID_SIGNATURE_COUNTER_NAME =
|
||||
MetricsUtil.name(PreKeySignatureValidator.class, "invalidPreKeySignature");
|
||||
|
||||
public static boolean validatePreKeySignatures(final IdentityKey identityKey, final Collection<SignedPreKey<?>> spks) {
|
||||
final boolean success = spks.stream().allMatch(spk -> spk.signatureValid(identityKey));
|
||||
public static boolean validatePreKeySignatures(final IdentityKey identityKey,
|
||||
final Collection<SignedPreKey<?>> signedPreKeys,
|
||||
@Nullable final String userAgent,
|
||||
final String context) {
|
||||
|
||||
final boolean success = signedPreKeys.stream().allMatch(signedPreKey -> signedPreKey.signatureValid(identityKey));
|
||||
|
||||
if (!success) {
|
||||
INVALID_SIGNATURE_COUNTER.increment();
|
||||
Metrics.counter(INVALID_SIGNATURE_COUNTER_NAME,
|
||||
Tags.of(UserAgentTagUtil.getPlatformTag(userAgent), Tag.of("context", context)))
|
||||
.increment();
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.NotNull;
|
||||
@@ -96,8 +97,7 @@ public record RegistrationRequest(@Schema(requiredMode = Schema.RequiredMode.NOT
|
||||
new DeviceActivationRequest(aciSignedPreKey, pniSignedPreKey, aciPqLastResortPreKey, pniPqLastResortPreKey, apnToken, gcmToken));
|
||||
}
|
||||
|
||||
@AssertTrue
|
||||
public boolean isEverySignedKeyValid() {
|
||||
public boolean isEverySignedKeyValid(@Nullable final String userAgent) {
|
||||
if (deviceActivationRequest().aciSignedPreKey() == null ||
|
||||
deviceActivationRequest().pniSignedPreKey() == null ||
|
||||
deviceActivationRequest().aciPqLastResortPreKey() == null ||
|
||||
@@ -105,8 +105,8 @@ public record RegistrationRequest(@Schema(requiredMode = Schema.RequiredMode.NOT
|
||||
return false;
|
||||
}
|
||||
|
||||
return PreKeySignatureValidator.validatePreKeySignatures(aciIdentityKey(), List.of(deviceActivationRequest().aciSignedPreKey(), deviceActivationRequest().aciPqLastResortPreKey()))
|
||||
&& PreKeySignatureValidator.validatePreKeySignatures(pniIdentityKey(), List.of(deviceActivationRequest().pniSignedPreKey(), deviceActivationRequest().pniPqLastResortPreKey()));
|
||||
return PreKeySignatureValidator.validatePreKeySignatures(aciIdentityKey(), List.of(deviceActivationRequest().aciSignedPreKey(), deviceActivationRequest().aciPqLastResortPreKey()), userAgent, "register")
|
||||
&& PreKeySignatureValidator.validatePreKeySignatures(pniIdentityKey(), List.of(deviceActivationRequest().pniSignedPreKey(), deviceActivationRequest().pniPqLastResortPreKey()), userAgent, "register");
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
Reference in New Issue
Block a user