Represent pre-key public keys and signatures as byte arrays in DAOs

This commit is contained in:
Jon Chambers
2023-05-19 10:02:14 -04:00
committed by Jon Chambers
parent 4a8ad3103c
commit 217b68a1e0
16 changed files with 141 additions and 112 deletions

View File

@@ -6,8 +6,14 @@
package org.whispersystems.textsecuregcm.entities;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.Objects;
public class PreKey {
@@ -16,22 +22,24 @@ public class PreKey {
private long keyId;
@JsonProperty
@JsonSerialize(using = ByteArrayAdapter.Serializing.class)
@JsonDeserialize(using = ByteArrayAdapter.Deserializing.class)
@NotEmpty
private String publicKey;
private byte[] publicKey;
public PreKey() {}
public PreKey(long keyId, String publicKey)
public PreKey(long keyId, byte[] publicKey)
{
this.keyId = keyId;
this.publicKey = publicKey;
}
public String getPublicKey() {
public byte[] getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
public void setPublicKey(byte[] publicKey) {
this.publicKey = publicKey;
}
@@ -44,23 +52,17 @@ public class PreKey {
}
@Override
public boolean equals(Object object) {
if (object == null || !(object instanceof PreKey)) return false;
PreKey that = (PreKey)object;
if (publicKey == null) {
return this.keyId == that.keyId && that.publicKey == null;
} else {
return this.keyId == that.keyId && this.publicKey.equals(that.publicKey);
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PreKey preKey = (PreKey) o;
return keyId == preKey.keyId && Arrays.equals(publicKey, preKey.publicKey);
}
@Override
public int hashCode() {
if (publicKey == null) {
return (int)this.keyId;
} else {
return ((int)this.keyId) ^ publicKey.hashCode();
}
int result = Objects.hash(keyId);
result = 31 * result + Arrays.hashCode(publicKey);
return result;
}
}

View File

@@ -18,17 +18,13 @@ public abstract class PreKeySignatureValidator {
public static final Counter INVALID_SIGNATURE_COUNTER =
Metrics.counter(name(PreKeySignatureValidator.class, "invalidPreKeySignature"));
public static final boolean validatePreKeySignatures(final String identityKeyB64, final Collection<SignedPreKey> spks) {
public static boolean validatePreKeySignatures(final String identityKeyB64, final Collection<SignedPreKey> spks) {
try {
final byte[] identityKeyBytes = Base64.getDecoder().decode(identityKeyB64);
final ECPublicKey identityKey = Curve.decodePoint(identityKeyBytes, 0);
final boolean success = spks.stream().allMatch(spk -> {
final byte[] prekeyBytes = Base64.getDecoder().decode(spk.getPublicKey());
final byte[] prekeySignatureBytes = Base64.getDecoder().decode(spk.getSignature());
return identityKey.verifySignature(prekeyBytes, prekeySignatureBytes);
});
final boolean success = spks.stream()
.allMatch(spk -> identityKey.verifySignature(spk.getPublicKey(), spk.getSignature()));
if (!success) {
INVALID_SIGNATURE_COUNTER.increment();

View File

@@ -6,43 +6,45 @@
package org.whispersystems.textsecuregcm.entities;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
public class SignedPreKey extends PreKey {
@JsonProperty
@JsonSerialize(using = ByteArrayAdapter.Serializing.class)
@JsonDeserialize(using = ByteArrayAdapter.Deserializing.class)
@NotEmpty
private String signature;
private byte[] signature;
public SignedPreKey() {}
public SignedPreKey(long keyId, String publicKey, String signature) {
public SignedPreKey(long keyId, byte[] publicKey, byte[] signature) {
super(keyId, publicKey);
this.signature = signature;
}
public String getSignature() {
public byte[] getSignature() {
return signature;
}
@Override
public boolean equals(Object object) {
if (object == null || !(object instanceof SignedPreKey)) return false;
SignedPreKey that = (SignedPreKey) object;
if (signature == null) {
return super.equals(object) && that.signature == null;
} else {
return super.equals(object) && this.signature.equals(that.signature);
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
SignedPreKey that = (SignedPreKey) o;
return Arrays.equals(signature, that.signature);
}
@Override
public int hashCode() {
if (signature == null) {
return super.hashCode();
} else {
return super.hashCode() ^ signature.hashCode();
}
int result = super.hashCode();
result = 31 * result + Arrays.hashCode(signature);
return result;
}
}