mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-22 01:40:13 +01:00
Use strongly-typed pre-keys
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import org.signal.libsignal.protocol.InvalidKeyException;
|
||||
import org.signal.libsignal.protocol.ecc.ECPublicKey;
|
||||
|
||||
public class ECPublicKeyAdapter {
|
||||
|
||||
public static class Serializer extends JsonSerializer<ECPublicKey> {
|
||||
|
||||
@Override
|
||||
public void serialize(final ECPublicKey ecPublicKey,
|
||||
final JsonGenerator jsonGenerator,
|
||||
final SerializerProvider serializers) throws IOException {
|
||||
|
||||
jsonGenerator.writeString(Base64.getEncoder().encodeToString(ecPublicKey.serialize()));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Deserializer extends JsonDeserializer<ECPublicKey> {
|
||||
|
||||
@Override
|
||||
public ECPublicKey deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
|
||||
final byte[] ecPublicKeyBytes;
|
||||
|
||||
try {
|
||||
ecPublicKeyBytes = Base64.getDecoder().decode(parser.getValueAsString());
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new JsonParseException(parser, "Could not parse EC public key as a base64-encoded value", e);
|
||||
}
|
||||
|
||||
try {
|
||||
return new ECPublicKey(ecPublicKeyBytes);
|
||||
} catch (final InvalidKeyException e) {
|
||||
throw new JsonParseException(parser, "Could not interpret key bytes as an EC public key", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import org.signal.libsignal.protocol.InvalidKeyException;
|
||||
import org.signal.libsignal.protocol.kem.KEMPublicKey;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class KEMPublicKeyAdapter {
|
||||
|
||||
public static class Serializer extends JsonSerializer<KEMPublicKey> {
|
||||
|
||||
@Override
|
||||
public void serialize(final KEMPublicKey kemPublicKey,
|
||||
final JsonGenerator jsonGenerator,
|
||||
final SerializerProvider serializers) throws IOException {
|
||||
|
||||
jsonGenerator.writeString(Base64.getEncoder().encodeToString(kemPublicKey.serialize()));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Deserializer extends JsonDeserializer<KEMPublicKey> {
|
||||
|
||||
@Override
|
||||
public KEMPublicKey deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
|
||||
final byte[] kemPublicKeyBytes;
|
||||
|
||||
try {
|
||||
kemPublicKeyBytes = Base64.getDecoder().decode(parser.getValueAsString());
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new JsonParseException(parser, "Could not parse KEM public key as a base64-encoded value", e);
|
||||
}
|
||||
|
||||
try {
|
||||
return new KEMPublicKey(kemPublicKeyBytes);
|
||||
} catch (final InvalidKeyException e) {
|
||||
throw new JsonParseException(parser, "Could not interpret key bytes as a KEM public key", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.util;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
|
||||
@Target({FIELD, PARAMETER, TYPE_USE})
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = {ValidPreKeyValidator.class})
|
||||
@Documented
|
||||
public @interface ValidPreKey {
|
||||
|
||||
public enum PreKeyType {
|
||||
ECC,
|
||||
KYBER
|
||||
}
|
||||
|
||||
PreKeyType type();
|
||||
|
||||
String message() default "{org.whispersystems.textsecuregcm.util.ValidPreKey.message}";
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.util;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import org.signal.libsignal.protocol.InvalidKeyException;
|
||||
import org.signal.libsignal.protocol.ecc.Curve;
|
||||
import org.signal.libsignal.protocol.kem.KEMPublicKey;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKey;
|
||||
|
||||
public class ValidPreKeyValidator implements ConstraintValidator<ValidPreKey, PreKey> {
|
||||
private ValidPreKey.PreKeyType type;
|
||||
|
||||
@Override
|
||||
public void initialize(ValidPreKey annotation) {
|
||||
type = annotation.type();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(PreKey value, ConstraintValidatorContext context) {
|
||||
if (value == null) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
switch (type) {
|
||||
case ECC -> Curve.decodePoint(value.getPublicKey(), 0);
|
||||
case KYBER -> new KEMPublicKey(value.getPublicKey());
|
||||
}
|
||||
} catch (IllegalArgumentException | InvalidKeyException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user