diff --git a/service/pom.xml b/service/pom.xml index 41d7f497f..30a7c6595 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -57,11 +57,6 @@ signal-client-java 0.10.0 - - org.whispersystems - curve25519-java - 0.5.0 - io.dropwizard diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/auth/CertificateGenerator.java b/service/src/main/java/org/whispersystems/textsecuregcm/auth/CertificateGenerator.java index 26b06b6b6..be372d30e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/auth/CertificateGenerator.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/auth/CertificateGenerator.java @@ -7,8 +7,8 @@ package org.whispersystems.textsecuregcm.auth; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; -import org.whispersystems.textsecuregcm.crypto.Curve; -import org.whispersystems.textsecuregcm.crypto.ECPrivateKey; +import org.whispersystems.libsignal.ecc.Curve; +import org.whispersystems.libsignal.ecc.ECPrivateKey; import org.whispersystems.textsecuregcm.entities.MessageProtos.SenderCertificate; import org.whispersystems.textsecuregcm.entities.MessageProtos.ServerCertificate; import org.whispersystems.textsecuregcm.storage.Account; @@ -46,7 +46,12 @@ public class CertificateGenerator { } byte[] certificate = builder.build().toByteArray(); - byte[] signature = Curve.calculateSignature(privateKey, certificate); + byte[] signature; + try { + signature = Curve.calculateSignature(privateKey, certificate); + } catch (org.whispersystems.libsignal.InvalidKeyException e) { + throw new InvalidKeyException(e); + } return SenderCertificate.newBuilder() .setCertificate(ByteString.copyFrom(certificate)) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/UnidentifiedDeliveryConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/UnidentifiedDeliveryConfiguration.java index eddd1d9d0..3d5c58131 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/UnidentifiedDeliveryConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/UnidentifiedDeliveryConfiguration.java @@ -8,8 +8,8 @@ package org.whispersystems.textsecuregcm.configuration; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import org.whispersystems.textsecuregcm.crypto.Curve; -import org.whispersystems.textsecuregcm.crypto.ECPrivateKey; +import org.whispersystems.libsignal.ecc.Curve; +import org.whispersystems.libsignal.ecc.ECPrivateKey; import org.whispersystems.textsecuregcm.util.ByteArrayAdapter; import javax.validation.constraints.NotNull; diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/Curve.java b/service/src/main/java/org/whispersystems/textsecuregcm/crypto/Curve.java deleted file mode 100644 index 65eb4257d..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/Curve.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.crypto; - -import org.whispersystems.curve25519.Curve25519; -import org.whispersystems.curve25519.Curve25519KeyPair; - -import java.security.InvalidKeyException; - -import static org.whispersystems.curve25519.Curve25519.BEST; - -public class Curve { - - public static final int DJB_TYPE = 0x05; - - public static ECKeyPair generateKeyPair() { - Curve25519KeyPair keyPair = Curve25519.getInstance(BEST).generateKeyPair(); - - return new ECKeyPair(new DjbECPublicKey(keyPair.getPublicKey()), - new DjbECPrivateKey(keyPair.getPrivateKey())); - } - - public static ECPublicKey decodePoint(byte[] bytes, int offset) - throws InvalidKeyException - { - if (bytes == null || bytes.length - offset < 1) { - throw new InvalidKeyException("No key type identifier"); - } - - int type = bytes[offset] & 0xFF; - - switch (type) { - case Curve.DJB_TYPE: - if (bytes.length - offset < 33) { - throw new InvalidKeyException("Bad key length: " + bytes.length); - } - - byte[] keyBytes = new byte[32]; - System.arraycopy(bytes, offset+1, keyBytes, 0, keyBytes.length); - return new DjbECPublicKey(keyBytes); - default: - throw new InvalidKeyException("Bad key type: " + type); - } - } - - public static ECPrivateKey decodePrivatePoint(byte[] bytes) { - return new DjbECPrivateKey(bytes); - } - - public static byte[] calculateAgreement(ECPublicKey publicKey, ECPrivateKey privateKey) - throws InvalidKeyException - { - if (publicKey == null) { - throw new InvalidKeyException("public value is null"); - } - - if (privateKey == null) { - throw new InvalidKeyException("private value is null"); - } - - if (publicKey.getType() != privateKey.getType()) { - throw new InvalidKeyException("Public and private keys must be of the same type!"); - } - - if (publicKey.getType() == DJB_TYPE) { - return Curve25519.getInstance(BEST) - .calculateAgreement(((DjbECPublicKey) publicKey).getPublicKey(), - ((DjbECPrivateKey) privateKey).getPrivateKey()); - } else { - throw new InvalidKeyException("Unknown type: " + publicKey.getType()); - } - } - - public static byte[] calculateSignature(ECPrivateKey signingKey, byte[] message) - throws InvalidKeyException - { - if (signingKey == null || message == null) { - throw new InvalidKeyException("Values must not be null"); - } - - if (signingKey.getType() == DJB_TYPE) { - return Curve25519.getInstance(BEST) - .calculateSignature(((DjbECPrivateKey) signingKey).getPrivateKey(), message); - } else { - throw new InvalidKeyException("Unknown type: " + signingKey.getType()); - } - } - - public static boolean verifySignature(ECPublicKey signingKey, byte[] message, byte[] signature) - throws InvalidKeyException - { - if (signingKey.getType() == DJB_TYPE) { - return Curve25519.getInstance(BEST) - .verifySignature(((DjbECPublicKey) signingKey).getPublicKey(), message, signature); - } else { - throw new InvalidKeyException("Unknown type: " + signingKey.getType()); - } - } - -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/DjbECPrivateKey.java b/service/src/main/java/org/whispersystems/textsecuregcm/crypto/DjbECPrivateKey.java deleted file mode 100644 index 47ffc84bb..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/DjbECPrivateKey.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.crypto; - -public class DjbECPrivateKey implements ECPrivateKey { - - private final byte[] privateKey; - - DjbECPrivateKey(byte[] privateKey) { - this.privateKey = privateKey; - } - - @Override - public byte[] serialize() { - return privateKey; - } - - @Override - public int getType() { - return Curve.DJB_TYPE; - } - - public byte[] getPrivateKey() { - return privateKey; - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/DjbECPublicKey.java b/service/src/main/java/org/whispersystems/textsecuregcm/crypto/DjbECPublicKey.java deleted file mode 100644 index a24a96e35..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/DjbECPublicKey.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.crypto; - -import org.whispersystems.textsecuregcm.util.ByteUtil; - -import java.math.BigInteger; -import java.util.Arrays; - -public class DjbECPublicKey implements ECPublicKey { - - private final byte[] publicKey; - - DjbECPublicKey(byte[] publicKey) { - this.publicKey = publicKey; - } - - @Override - public byte[] serialize() { - byte[] type = {Curve.DJB_TYPE}; - return ByteUtil.combine(type, publicKey); - } - - @Override - public int getType() { - return Curve.DJB_TYPE; - } - - @Override - public boolean equals(Object other) { - if (other == null) return false; - if (!(other instanceof DjbECPublicKey)) return false; - - DjbECPublicKey that = (DjbECPublicKey)other; - return Arrays.equals(this.publicKey, that.publicKey); - } - - @Override - public int hashCode() { - return Arrays.hashCode(publicKey); - } - - @Override - public int compareTo(ECPublicKey another) { - return new BigInteger(publicKey).compareTo(new BigInteger(((DjbECPublicKey)another).publicKey)); - } - - public byte[] getPublicKey() { - return publicKey; - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECKeyPair.java b/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECKeyPair.java deleted file mode 100644 index ad4120d22..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECKeyPair.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.crypto; - -public class ECKeyPair { - - private final ECPublicKey publicKey; - private final ECPrivateKey privateKey; - - ECKeyPair(ECPublicKey publicKey, ECPrivateKey privateKey) { - this.publicKey = publicKey; - this.privateKey = privateKey; - } - - public ECPublicKey getPublicKey() { - return publicKey; - } - - public ECPrivateKey getPrivateKey() { - return privateKey; - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECPrivateKey.java b/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECPrivateKey.java deleted file mode 100644 index bac0d3234..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECPrivateKey.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.crypto; - -public interface ECPrivateKey { - public byte[] serialize(); - public int getType(); -} - diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECPublicKey.java b/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECPublicKey.java deleted file mode 100644 index 5511b0aaf..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/crypto/ECPublicKey.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.crypto; - -public interface ECPublicKey extends Comparable { - - public static final int KEY_SIZE = 33; - - public byte[] serialize(); - - public int getType(); -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CertificateCommand.java b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CertificateCommand.java index f3e25ccd4..118cf0a9a 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CertificateCommand.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CertificateCommand.java @@ -10,9 +10,9 @@ import com.google.protobuf.ByteString; import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Subparser; -import org.whispersystems.textsecuregcm.crypto.Curve; -import org.whispersystems.textsecuregcm.crypto.ECKeyPair; -import org.whispersystems.textsecuregcm.crypto.ECPrivateKey; +import org.whispersystems.libsignal.ecc.Curve; +import org.whispersystems.libsignal.ecc.ECKeyPair; +import org.whispersystems.libsignal.ecc.ECPrivateKey; import org.whispersystems.textsecuregcm.entities.MessageProtos; import java.io.IOException; @@ -91,7 +91,12 @@ public class CertificateCommand extends Command { .build() .toByteArray(); - byte[] signature = Curve.calculateSignature(key, certificate); + byte[] signature; + try { + signature = Curve.calculateSignature(key, certificate); + } catch (org.whispersystems.libsignal.InvalidKeyException e) { + throw new InvalidKeyException(e); + } byte[] signedCertificate = MessageProtos.ServerCertificate.newBuilder() .setCertificate(ByteString.copyFrom(certificate)) diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/auth/CertificateGeneratorTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/auth/CertificateGeneratorTest.java index 482ec7178..f5db90382 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/auth/CertificateGeneratorTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/auth/CertificateGeneratorTest.java @@ -6,7 +6,7 @@ package org.whispersystems.textsecuregcm.auth; import org.junit.Test; -import org.whispersystems.textsecuregcm.crypto.Curve; +import org.whispersystems.libsignal.ecc.Curve; import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device; diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/CertificateControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/CertificateControllerTest.java index 1a8026b0a..c01c11f97 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/CertificateControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/CertificateControllerTest.java @@ -28,12 +28,12 @@ import org.signal.zkgroup.auth.AuthCredential; import org.signal.zkgroup.auth.AuthCredentialResponse; import org.signal.zkgroup.auth.ClientZkAuthOperations; import org.signal.zkgroup.auth.ServerZkAuthOperations; +import org.whispersystems.libsignal.ecc.Curve; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.CertificateGenerator; import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.OptionalAccess; import org.whispersystems.textsecuregcm.controllers.CertificateController; -import org.whispersystems.textsecuregcm.crypto.Curve; import org.whispersystems.textsecuregcm.entities.DeliveryCertificate; import org.whispersystems.textsecuregcm.entities.GroupCredentials; import org.whispersystems.textsecuregcm.entities.MessageProtos.SenderCertificate;