UnidentifiedSenderMessage

This commit is contained in:
Jack Lloyd
2020-11-13 17:27:59 -05:00
parent 4a8705dce1
commit ddda1a3635
7 changed files with 156 additions and 65 deletions

View File

@@ -222,4 +222,12 @@ public final class Native {
public static native long UnidentifiedSenderMessageContent_GetSenderCert(long handle);
public static native byte[] UnidentifiedSenderMessageContent_GetSerialized(long handle);
public static native long UnidentifiedSenderMessageContent_New(int msgType, long sender, byte[] contents);
public static native long UnidentifiedSenderMessage_Deserialize(byte[] data);
public static native void UnidentifiedSenderMessage_Destroy(long handle);
public static native byte[] UnidentifiedSenderMessage_GetEncryptedMessage(long handle);
public static native byte[] UnidentifiedSenderMessage_GetEncryptedStatic(long handle);
public static native long UnidentifiedSenderMessage_GetEphemeralPublic(long handle);
public static native byte[] UnidentifiedSenderMessage_GetSerialized(long handle);
public static native long UnidentifiedSenderMessage_New(long publicKey, byte[] encryptedStatic, byte[] encryptedMessage);
}

View File

@@ -1,87 +1,43 @@
package org.signal.libsignal.metadata.protocol;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import org.signal.client.internal.Native;
import org.signal.libsignal.metadata.InvalidMetadataMessageException;
import org.signal.libsignal.metadata.InvalidMetadataVersionException;
import org.signal.libsignal.metadata.SignalProtos;
import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.InvalidMessageException;
import org.whispersystems.libsignal.InvalidVersionException;
import org.whispersystems.libsignal.ecc.Curve;
import org.whispersystems.libsignal.ecc.ECPublicKey;
import org.whispersystems.libsignal.util.ByteUtil;
public class UnidentifiedSenderMessage {
private final long handle;
private static final int CIPHERTEXT_VERSION = 1;
@Override
protected void finalize() {
Native.UnidentifiedSenderMessage_Destroy(this.handle);
}
private final int version;
private final ECPublicKey ephemeral;
private final byte[] encryptedStatic;
private final byte[] encryptedMessage;
private final byte[] serialized;
public UnidentifiedSenderMessage(byte[] serialized)
throws InvalidMetadataMessageException, InvalidMetadataVersionException
{
public UnidentifiedSenderMessage(byte[] serialized) throws InvalidMetadataMessageException {
try {
this.version = ByteUtil.highBitsToInt(serialized[0]);
if (version > CIPHERTEXT_VERSION) {
throw new InvalidMetadataVersionException("Unknown version: " + this.version);
}
SignalProtos.UnidentifiedSenderMessage unidentifiedSenderMessage = SignalProtos.UnidentifiedSenderMessage.parseFrom(ByteString.copyFrom(serialized, 1, serialized.length - 1));
if (!unidentifiedSenderMessage.hasEphemeralPublic() ||
!unidentifiedSenderMessage.hasEncryptedStatic() ||
!unidentifiedSenderMessage.hasEncryptedMessage())
{
throw new InvalidMetadataMessageException("Missing fields");
}
this.ephemeral = Curve.decodePoint(unidentifiedSenderMessage.getEphemeralPublic().toByteArray(), 0);
this.encryptedStatic = unidentifiedSenderMessage.getEncryptedStatic().toByteArray();
this.encryptedMessage = unidentifiedSenderMessage.getEncryptedMessage().toByteArray();
this.serialized = serialized;
} catch (InvalidProtocolBufferException | InvalidKeyException e) {
this.handle = Native.UnidentifiedSenderMessage_Deserialize(serialized);
} catch (Exception e) {
throw new InvalidMetadataMessageException(e);
}
}
public UnidentifiedSenderMessage(ECPublicKey ephemeral, byte[] encryptedStatic, byte[] encryptedMessage) {
this.version = CIPHERTEXT_VERSION;
this.ephemeral = ephemeral;
this.encryptedStatic = encryptedStatic;
this.encryptedMessage = encryptedMessage;
byte[] versionBytes = {ByteUtil.intsToByteHighAndLow(CIPHERTEXT_VERSION, CIPHERTEXT_VERSION)};
byte[] messageBytes = SignalProtos.UnidentifiedSenderMessage.newBuilder()
.setEncryptedMessage(ByteString.copyFrom(encryptedMessage))
.setEncryptedStatic(ByteString.copyFrom(encryptedStatic))
.setEphemeralPublic(ByteString.copyFrom(ephemeral.serialize()))
.build()
.toByteArray();
this.serialized = ByteUtil.combine(versionBytes, messageBytes);
this.handle = Native.UnidentifiedSenderMessage_New(ephemeral.nativeHandle(), encryptedStatic, encryptedMessage);
}
public ECPublicKey getEphemeral() {
return ephemeral;
return new ECPublicKey(Native.UnidentifiedSenderMessage_GetEphemeralPublic(this.handle));
}
public byte[] getEncryptedStatic() {
return encryptedStatic;
return Native.UnidentifiedSenderMessage_GetEncryptedStatic(this.handle);
}
public byte[] getEncryptedMessage() {
return encryptedMessage;
return Native.UnidentifiedSenderMessage_GetEncryptedMessage(this.handle);
}
public byte[] getSerialized() {
return serialized;
return Native.UnidentifiedSenderMessage_GetSerialized(this.handle);
}
}

View File

@@ -7,7 +7,6 @@ import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
import org.signal.libsignal.metadata.certificate.SenderCertificate;
public class UnidentifiedSenderMessageContent {
private final long handle;
@Override