From 7fc6b1e8020b05cacfe39d2fd2e085b2b793ed15 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Thu, 8 Jun 2023 17:00:08 -0400 Subject: [PATCH] Count invalid pre-keys --- .../storage/RepeatedUseSignedPreKeyStore.java | 16 +++++++++++++++- .../storage/SingleUseECPreKeyStore.java | 14 ++++++++++++++ .../storage/SingleUseKEMPreKeyStore.java | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RepeatedUseSignedPreKeyStore.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RepeatedUseSignedPreKeyStore.java index 275eba4e5..eea257dea 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RepeatedUseSignedPreKeyStore.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RepeatedUseSignedPreKeyStore.java @@ -5,12 +5,15 @@ package org.whispersystems.textsecuregcm.storage; +import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Timer; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import org.signal.libsignal.protocol.InvalidKeyException; +import org.signal.libsignal.protocol.kem.KEMPublicKey; import org.whispersystems.textsecuregcm.entities.SignedPreKey; import org.whispersystems.textsecuregcm.metrics.MetricsUtil; import org.whispersystems.textsecuregcm.util.AttributeValues; @@ -60,6 +63,9 @@ public class RepeatedUseSignedPreKeyStore { private static final String FIND_KEY_TIMER_NAME = MetricsUtil.name(RepeatedUseSignedPreKeyStore.class, "findKey"); private static final String KEY_PRESENT_TAG_NAME = "keyPresent"; + private static final Counter INVALID_KEY_COUNTER = + Metrics.counter(MetricsUtil.name(RepeatedUseSignedPreKeyStore.class, "invalidKey")); + public RepeatedUseSignedPreKeyStore(final DynamoDbAsyncClient dynamoDbAsyncClient, final String tableName) { this.dynamoDbAsyncClient = dynamoDbAsyncClient; this.tableName = tableName; @@ -220,9 +226,17 @@ public class RepeatedUseSignedPreKeyStore { } private static SignedPreKey getPreKeyFromItem(final Map item) { + final byte[] publicKeyBytes = item.get(ATTR_PUBLIC_KEY).b().asByteArray(); + + try { + new KEMPublicKey(publicKeyBytes); + } catch (final InvalidKeyException e) { + INVALID_KEY_COUNTER.increment(); + } + return new SignedPreKey( Long.parseLong(item.get(ATTR_KEY_ID).n()), - item.get(ATTR_PUBLIC_KEY).b().asByteArray(), + publicKeyBytes, item.get(ATTR_SIGNATURE).b().asByteArray()); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseECPreKeyStore.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseECPreKeyStore.java index 82ec333a9..6f7f91ae7 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseECPreKeyStore.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseECPreKeyStore.java @@ -5,7 +5,12 @@ package org.whispersystems.textsecuregcm.storage; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Metrics; +import org.signal.libsignal.protocol.InvalidKeyException; +import org.signal.libsignal.protocol.ecc.ECPublicKey; import org.whispersystems.textsecuregcm.entities.PreKey; +import org.whispersystems.textsecuregcm.metrics.MetricsUtil; import org.whispersystems.textsecuregcm.util.AttributeValues; import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; @@ -14,6 +19,9 @@ import java.util.UUID; public class SingleUseECPreKeyStore extends SingleUsePreKeyStore { + private static final Counter INVALID_KEY_COUNTER = + Metrics.counter(MetricsUtil.name(SingleUseECPreKeyStore.class, "invalidKey")); + protected SingleUseECPreKeyStore(final DynamoDbAsyncClient dynamoDbAsyncClient, final String tableName) { super(dynamoDbAsyncClient, tableName); } @@ -31,6 +39,12 @@ public class SingleUseECPreKeyStore extends SingleUsePreKeyStore { final long keyId = item.get(KEY_DEVICE_ID_KEY_ID).b().asByteBuffer().getLong(8); final byte[] publicKey = extractByteArray(item.get(ATTR_PUBLIC_KEY)); + try { + new ECPublicKey(publicKey); + } catch (final InvalidKeyException e) { + INVALID_KEY_COUNTER.increment(); + } + return new PreKey(keyId, publicKey); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseKEMPreKeyStore.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseKEMPreKeyStore.java index a35235823..ba41f0629 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseKEMPreKeyStore.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/SingleUseKEMPreKeyStore.java @@ -5,7 +5,12 @@ package org.whispersystems.textsecuregcm.storage; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Metrics; +import org.signal.libsignal.protocol.InvalidKeyException; +import org.signal.libsignal.protocol.kem.KEMPublicKey; import org.whispersystems.textsecuregcm.entities.SignedPreKey; +import org.whispersystems.textsecuregcm.metrics.MetricsUtil; import org.whispersystems.textsecuregcm.util.AttributeValues; import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; @@ -14,6 +19,9 @@ import java.util.UUID; public class SingleUseKEMPreKeyStore extends SingleUsePreKeyStore { + private static final Counter INVALID_KEY_COUNTER = + Metrics.counter(MetricsUtil.name(SingleUseKEMPreKeyStore.class, "invalidKey")); + protected SingleUseKEMPreKeyStore(final DynamoDbAsyncClient dynamoDbAsyncClient, final String tableName) { super(dynamoDbAsyncClient, tableName); } @@ -33,6 +41,12 @@ public class SingleUseKEMPreKeyStore extends SingleUsePreKeyStore final byte[] publicKey = extractByteArray(item.get(ATTR_PUBLIC_KEY)); final byte[] signature = extractByteArray(item.get(ATTR_SIGNATURE)); + try { + new KEMPublicKey(publicKey); + } catch (final InvalidKeyException e) { + INVALID_KEY_COUNTER.increment(); + } + return new SignedPreKey(keyId, publicKey, signature); } }