Add support for UUIDs.
This commit is contained in:
parent
2b96d348c3
commit
cad43f6fe3
@ -28,12 +28,13 @@ import org.whispersystems.libsignal.protocol.PreKeySignalMessage;
|
||||
import org.whispersystems.libsignal.protocol.SignalMessage;
|
||||
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||
import org.whispersystems.libsignal.util.ByteUtil;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.ParseException;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
@ -45,14 +46,22 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class SealedSessionCipher {
|
||||
|
||||
private final SignalProtocolStore signalProtocolStore;
|
||||
private final SignalProtocolAddress localAddress;
|
||||
private static final String TAG = SealedSessionCipher.class.getSimpleName();
|
||||
|
||||
private final SignalProtocolStore signalProtocolStore;
|
||||
private final String localE164Address;
|
||||
private final String localUuidAddress;
|
||||
private final int localDeviceId;
|
||||
|
||||
public SealedSessionCipher(SignalProtocolStore signalProtocolStore,
|
||||
SignalProtocolAddress localAddress)
|
||||
UUID localUuid,
|
||||
String localE164Address,
|
||||
int localDeviceId)
|
||||
{
|
||||
this.signalProtocolStore = signalProtocolStore;
|
||||
this.localAddress = localAddress;
|
||||
this.localUuidAddress = localUuid != null ? localUuid.toString() : null;
|
||||
this.localE164Address = localE164Address;
|
||||
this.localDeviceId = localDeviceId;
|
||||
}
|
||||
|
||||
public byte[] encrypt(SignalProtocolAddress destinationAddress, SenderCertificate senderCertificate, byte[] paddedPlaintext)
|
||||
@ -75,7 +84,7 @@ public class SealedSessionCipher {
|
||||
return new UnidentifiedSenderMessage(ephemeral.getPublicKey(), staticKeyCiphertext, messageBytes).getSerialized();
|
||||
}
|
||||
|
||||
public Pair<SignalProtocolAddress, byte[]> decrypt(CertificateValidator validator, byte[] ciphertext, long timestamp)
|
||||
public DecryptionResult decrypt(CertificateValidator validator, byte[] ciphertext, long timestamp)
|
||||
throws
|
||||
InvalidMetadataMessageException, InvalidMetadataVersionException,
|
||||
ProtocolInvalidMessageException, ProtocolInvalidKeyException,
|
||||
@ -105,9 +114,10 @@ public class SealedSessionCipher {
|
||||
throw new InvalidKeyException("Sender's certificate key does not match key used in message");
|
||||
}
|
||||
|
||||
if (content.getSenderCertificate().getSender().equals(localAddress.getName()) &&
|
||||
content.getSenderCertificate().getSenderDeviceId() == localAddress.getDeviceId())
|
||||
{
|
||||
boolean isLocalE164 = localE164Address != null && localE164Address.equals(content.getSenderCertificate().getSenderE164().orNull());
|
||||
boolean isLocalUuid = localUuidAddress != null && localUuidAddress.equals(content.getSenderCertificate().getSenderUuid().orNull());
|
||||
|
||||
if ((isLocalE164 || isLocalUuid) && content.getSenderCertificate().getSenderDeviceId() == localDeviceId) {
|
||||
throw new SelfSendException();
|
||||
}
|
||||
} catch (InvalidKeyException | InvalidMacException | InvalidCertificateException e) {
|
||||
@ -115,9 +125,10 @@ public class SealedSessionCipher {
|
||||
}
|
||||
|
||||
try {
|
||||
return new Pair<>(new SignalProtocolAddress(content.getSenderCertificate().getSender(),
|
||||
content.getSenderCertificate().getSenderDeviceId()),
|
||||
decrypt(content));
|
||||
return new DecryptionResult(content.getSenderCertificate().getSenderUuid(),
|
||||
content.getSenderCertificate().getSenderE164(),
|
||||
content.getSenderCertificate().getSenderDeviceId(),
|
||||
decrypt(content));
|
||||
} catch (InvalidMessageException e) {
|
||||
throw new ProtocolInvalidMessageException(e, content.getSenderCertificate().getSender(), content.getSenderCertificate().getSenderDeviceId());
|
||||
} catch (InvalidKeyException e) {
|
||||
@ -172,8 +183,7 @@ public class SealedSessionCipher {
|
||||
private byte[] decrypt(UnidentifiedSenderMessageContent message)
|
||||
throws InvalidVersionException, InvalidMessageException, InvalidKeyException, DuplicateMessageException, InvalidKeyIdException, UntrustedIdentityException, LegacyMessageException, NoSessionException
|
||||
{
|
||||
|
||||
SignalProtocolAddress sender = new SignalProtocolAddress(message.getSenderCertificate().getSender(), message.getSenderCertificate().getSenderDeviceId());
|
||||
SignalProtocolAddress sender = getPreferredAddress(signalProtocolStore, message.getSenderCertificate());
|
||||
|
||||
switch (message.getType()) {
|
||||
case CiphertextMessage.WHISPER_TYPE: return new SessionCipher(signalProtocolStore, sender).decrypt(new SignalMessage(message.getContent()));
|
||||
@ -228,6 +238,48 @@ public class SealedSessionCipher {
|
||||
}
|
||||
}
|
||||
|
||||
private static SignalProtocolAddress getPreferredAddress(SignalProtocolStore store, SenderCertificate certificate) {
|
||||
SignalProtocolAddress uuidAddress = certificate.getSenderUuid().isPresent() ? new SignalProtocolAddress(certificate.getSenderUuid().get(), certificate.getSenderDeviceId()) : null;
|
||||
SignalProtocolAddress e164Address = certificate.getSenderE164().isPresent() ? new SignalProtocolAddress(certificate.getSenderE164().get(), certificate.getSenderDeviceId()) : null;
|
||||
|
||||
if (uuidAddress != null && store.containsSession(uuidAddress)) {
|
||||
return uuidAddress;
|
||||
} else if (e164Address != null && store.containsSession(e164Address)) {
|
||||
return e164Address;
|
||||
} else {
|
||||
return new SignalProtocolAddress(certificate.getSender(), certificate.getSenderDeviceId());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DecryptionResult {
|
||||
private final Optional<String> senderUuid;
|
||||
private final Optional<String> senderE164;
|
||||
private final int deviceId;
|
||||
private final byte[] paddedMessage;
|
||||
|
||||
private DecryptionResult(Optional<String> senderUuid, Optional<String> senderE164, int deviceId, byte[] paddedMessage) {
|
||||
this.senderUuid = senderUuid;
|
||||
this.senderE164 = senderE164;
|
||||
this.deviceId = deviceId;
|
||||
this.paddedMessage = paddedMessage;
|
||||
}
|
||||
|
||||
public Optional<String> getSenderUuid() {
|
||||
return senderUuid;
|
||||
}
|
||||
|
||||
public Optional<String> getSenderE164() {
|
||||
return senderE164;
|
||||
}
|
||||
|
||||
public int getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public byte[] getPaddedMessage() {
|
||||
return paddedMessage;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EphemeralKeys {
|
||||
private final byte[] chainKey;
|
||||
|
||||
@ -1097,20 +1097,35 @@ public final class SignalProtos {
|
||||
public interface CertificateOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
// optional string sender = 1;
|
||||
// optional string senderE164 = 1;
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
boolean hasSender();
|
||||
boolean hasSenderE164();
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
java.lang.String getSender();
|
||||
java.lang.String getSenderE164();
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getSenderBytes();
|
||||
getSenderE164Bytes();
|
||||
|
||||
// optional string senderUuid = 6;
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
boolean hasSenderUuid();
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
java.lang.String getSenderUuid();
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getSenderUuidBytes();
|
||||
|
||||
// optional uint32 senderDevice = 2;
|
||||
/**
|
||||
@ -1209,27 +1224,27 @@ public final class SignalProtos {
|
||||
}
|
||||
case 10: {
|
||||
bitField0_ |= 0x00000001;
|
||||
sender_ = input.readBytes();
|
||||
senderE164_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
bitField0_ |= 0x00000002;
|
||||
bitField0_ |= 0x00000004;
|
||||
senderDevice_ = input.readUInt32();
|
||||
break;
|
||||
}
|
||||
case 25: {
|
||||
bitField0_ |= 0x00000004;
|
||||
bitField0_ |= 0x00000008;
|
||||
expires_ = input.readFixed64();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
bitField0_ |= 0x00000008;
|
||||
bitField0_ |= 0x00000010;
|
||||
identityKey_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 42: {
|
||||
org.signal.libsignal.metadata.SignalProtos.ServerCertificate.Builder subBuilder = null;
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
if (((bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
subBuilder = signer_.toBuilder();
|
||||
}
|
||||
signer_ = input.readMessage(org.signal.libsignal.metadata.SignalProtos.ServerCertificate.PARSER, extensionRegistry);
|
||||
@ -1237,7 +1252,12 @@ public final class SignalProtos {
|
||||
subBuilder.mergeFrom(signer_);
|
||||
signer_ = subBuilder.buildPartial();
|
||||
}
|
||||
bitField0_ |= 0x00000010;
|
||||
bitField0_ |= 0x00000020;
|
||||
break;
|
||||
}
|
||||
case 50: {
|
||||
bitField0_ |= 0x00000002;
|
||||
senderUuid_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1280,20 +1300,20 @@ public final class SignalProtos {
|
||||
}
|
||||
|
||||
private int bitField0_;
|
||||
// optional string sender = 1;
|
||||
public static final int SENDER_FIELD_NUMBER = 1;
|
||||
private java.lang.Object sender_;
|
||||
// optional string senderE164 = 1;
|
||||
public static final int SENDERE164_FIELD_NUMBER = 1;
|
||||
private java.lang.Object senderE164_;
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public boolean hasSender() {
|
||||
public boolean hasSenderE164() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public java.lang.String getSender() {
|
||||
java.lang.Object ref = sender_;
|
||||
public java.lang.String getSenderE164() {
|
||||
java.lang.Object ref = senderE164_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
return (java.lang.String) ref;
|
||||
} else {
|
||||
@ -1301,22 +1321,65 @@ public final class SignalProtos {
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
java.lang.String s = bs.toStringUtf8();
|
||||
if (bs.isValidUtf8()) {
|
||||
sender_ = s;
|
||||
senderE164_ = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getSenderBytes() {
|
||||
java.lang.Object ref = sender_;
|
||||
getSenderE164Bytes() {
|
||||
java.lang.Object ref = senderE164_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
sender_ = b;
|
||||
senderE164_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
// optional string senderUuid = 6;
|
||||
public static final int SENDERUUID_FIELD_NUMBER = 6;
|
||||
private java.lang.Object senderUuid_;
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public boolean hasSenderUuid() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public java.lang.String getSenderUuid() {
|
||||
java.lang.Object ref = senderUuid_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
return (java.lang.String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
java.lang.String s = bs.toStringUtf8();
|
||||
if (bs.isValidUtf8()) {
|
||||
senderUuid_ = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getSenderUuidBytes() {
|
||||
java.lang.Object ref = senderUuid_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
senderUuid_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
@ -1330,7 +1393,7 @@ public final class SignalProtos {
|
||||
* <code>optional uint32 senderDevice = 2;</code>
|
||||
*/
|
||||
public boolean hasSenderDevice() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
/**
|
||||
* <code>optional uint32 senderDevice = 2;</code>
|
||||
@ -1346,7 +1409,7 @@ public final class SignalProtos {
|
||||
* <code>optional fixed64 expires = 3;</code>
|
||||
*/
|
||||
public boolean hasExpires() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
}
|
||||
/**
|
||||
* <code>optional fixed64 expires = 3;</code>
|
||||
@ -1362,7 +1425,7 @@ public final class SignalProtos {
|
||||
* <code>optional bytes identityKey = 4;</code>
|
||||
*/
|
||||
public boolean hasIdentityKey() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes identityKey = 4;</code>
|
||||
@ -1378,7 +1441,7 @@ public final class SignalProtos {
|
||||
* <code>optional .signal.ServerCertificate signer = 5;</code>
|
||||
*/
|
||||
public boolean hasSigner() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
return ((bitField0_ & 0x00000020) == 0x00000020);
|
||||
}
|
||||
/**
|
||||
* <code>optional .signal.ServerCertificate signer = 5;</code>
|
||||
@ -1394,7 +1457,8 @@ public final class SignalProtos {
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
sender_ = "";
|
||||
senderE164_ = "";
|
||||
senderUuid_ = "";
|
||||
senderDevice_ = 0;
|
||||
expires_ = 0L;
|
||||
identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
@ -1413,20 +1477,23 @@ public final class SignalProtos {
|
||||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
output.writeBytes(1, getSenderBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeUInt32(2, senderDevice_);
|
||||
output.writeBytes(1, getSenderE164Bytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
output.writeFixed64(3, expires_);
|
||||
output.writeUInt32(2, senderDevice_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
output.writeBytes(4, identityKey_);
|
||||
output.writeFixed64(3, expires_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
output.writeBytes(4, identityKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
output.writeMessage(5, signer_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeBytes(6, getSenderUuidBytes());
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
@ -1438,24 +1505,28 @@ public final class SignalProtos {
|
||||
size = 0;
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(1, getSenderBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeUInt32Size(2, senderDevice_);
|
||||
.computeBytesSize(1, getSenderE164Bytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeFixed64Size(3, expires_);
|
||||
.computeUInt32Size(2, senderDevice_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(4, identityKey_);
|
||||
.computeFixed64Size(3, expires_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(4, identityKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeMessageSize(5, signer_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(6, getSenderUuidBytes());
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
@ -1573,20 +1644,22 @@ public final class SignalProtos {
|
||||
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
sender_ = "";
|
||||
senderE164_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
senderDevice_ = 0;
|
||||
senderUuid_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
expires_ = 0L;
|
||||
senderDevice_ = 0;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
expires_ = 0L;
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
if (signerBuilder_ == null) {
|
||||
signer_ = org.signal.libsignal.metadata.SignalProtos.ServerCertificate.getDefaultInstance();
|
||||
} else {
|
||||
signerBuilder_.clear();
|
||||
}
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
bitField0_ = (bitField0_ & ~0x00000020);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1618,22 +1691,26 @@ public final class SignalProtos {
|
||||
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
to_bitField0_ |= 0x00000001;
|
||||
}
|
||||
result.sender_ = sender_;
|
||||
result.senderE164_ = senderE164_;
|
||||
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
to_bitField0_ |= 0x00000002;
|
||||
}
|
||||
result.senderDevice_ = senderDevice_;
|
||||
result.senderUuid_ = senderUuid_;
|
||||
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
to_bitField0_ |= 0x00000004;
|
||||
}
|
||||
result.expires_ = expires_;
|
||||
result.senderDevice_ = senderDevice_;
|
||||
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
to_bitField0_ |= 0x00000008;
|
||||
}
|
||||
result.identityKey_ = identityKey_;
|
||||
result.expires_ = expires_;
|
||||
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
to_bitField0_ |= 0x00000010;
|
||||
}
|
||||
result.identityKey_ = identityKey_;
|
||||
if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
to_bitField0_ |= 0x00000020;
|
||||
}
|
||||
if (signerBuilder_ == null) {
|
||||
result.signer_ = signer_;
|
||||
} else {
|
||||
@ -1655,9 +1732,14 @@ public final class SignalProtos {
|
||||
|
||||
public Builder mergeFrom(org.signal.libsignal.metadata.SignalProtos.SenderCertificate.Certificate other) {
|
||||
if (other == org.signal.libsignal.metadata.SignalProtos.SenderCertificate.Certificate.getDefaultInstance()) return this;
|
||||
if (other.hasSender()) {
|
||||
if (other.hasSenderE164()) {
|
||||
bitField0_ |= 0x00000001;
|
||||
sender_ = other.sender_;
|
||||
senderE164_ = other.senderE164_;
|
||||
onChanged();
|
||||
}
|
||||
if (other.hasSenderUuid()) {
|
||||
bitField0_ |= 0x00000002;
|
||||
senderUuid_ = other.senderUuid_;
|
||||
onChanged();
|
||||
}
|
||||
if (other.hasSenderDevice()) {
|
||||
@ -1699,76 +1781,150 @@ public final class SignalProtos {
|
||||
}
|
||||
private int bitField0_;
|
||||
|
||||
// optional string sender = 1;
|
||||
private java.lang.Object sender_ = "";
|
||||
// optional string senderE164 = 1;
|
||||
private java.lang.Object senderE164_ = "";
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public boolean hasSender() {
|
||||
public boolean hasSenderE164() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public java.lang.String getSender() {
|
||||
java.lang.Object ref = sender_;
|
||||
public java.lang.String getSenderE164() {
|
||||
java.lang.Object ref = senderE164_;
|
||||
if (!(ref instanceof java.lang.String)) {
|
||||
java.lang.String s = ((com.google.protobuf.ByteString) ref)
|
||||
.toStringUtf8();
|
||||
sender_ = s;
|
||||
senderE164_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (java.lang.String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getSenderBytes() {
|
||||
java.lang.Object ref = sender_;
|
||||
getSenderE164Bytes() {
|
||||
java.lang.Object ref = senderE164_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
sender_ = b;
|
||||
senderE164_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public Builder setSender(
|
||||
public Builder setSenderE164(
|
||||
java.lang.String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
sender_ = value;
|
||||
senderE164_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public Builder clearSender() {
|
||||
public Builder clearSenderE164() {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
sender_ = getDefaultInstance().getSender();
|
||||
senderE164_ = getDefaultInstance().getSenderE164();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string sender = 1;</code>
|
||||
* <code>optional string senderE164 = 1;</code>
|
||||
*/
|
||||
public Builder setSenderBytes(
|
||||
public Builder setSenderE164Bytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
sender_ = value;
|
||||
senderE164_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional string senderUuid = 6;
|
||||
private java.lang.Object senderUuid_ = "";
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public boolean hasSenderUuid() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public java.lang.String getSenderUuid() {
|
||||
java.lang.Object ref = senderUuid_;
|
||||
if (!(ref instanceof java.lang.String)) {
|
||||
java.lang.String s = ((com.google.protobuf.ByteString) ref)
|
||||
.toStringUtf8();
|
||||
senderUuid_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (java.lang.String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getSenderUuidBytes() {
|
||||
java.lang.Object ref = senderUuid_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
senderUuid_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public Builder setSenderUuid(
|
||||
java.lang.String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000002;
|
||||
senderUuid_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public Builder clearSenderUuid() {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
senderUuid_ = getDefaultInstance().getSenderUuid();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string senderUuid = 6;</code>
|
||||
*/
|
||||
public Builder setSenderUuidBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000002;
|
||||
senderUuid_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
@ -1779,7 +1935,7 @@ public final class SignalProtos {
|
||||
* <code>optional uint32 senderDevice = 2;</code>
|
||||
*/
|
||||
public boolean hasSenderDevice() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
/**
|
||||
* <code>optional uint32 senderDevice = 2;</code>
|
||||
@ -1791,7 +1947,7 @@ public final class SignalProtos {
|
||||
* <code>optional uint32 senderDevice = 2;</code>
|
||||
*/
|
||||
public Builder setSenderDevice(int value) {
|
||||
bitField0_ |= 0x00000002;
|
||||
bitField0_ |= 0x00000004;
|
||||
senderDevice_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
@ -1800,7 +1956,7 @@ public final class SignalProtos {
|
||||
* <code>optional uint32 senderDevice = 2;</code>
|
||||
*/
|
||||
public Builder clearSenderDevice() {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
senderDevice_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
@ -1812,7 +1968,7 @@ public final class SignalProtos {
|
||||
* <code>optional fixed64 expires = 3;</code>
|
||||
*/
|
||||
public boolean hasExpires() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
}
|
||||
/**
|
||||
* <code>optional fixed64 expires = 3;</code>
|
||||
@ -1824,7 +1980,7 @@ public final class SignalProtos {
|
||||
* <code>optional fixed64 expires = 3;</code>
|
||||
*/
|
||||
public Builder setExpires(long value) {
|
||||
bitField0_ |= 0x00000004;
|
||||
bitField0_ |= 0x00000008;
|
||||
expires_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
@ -1833,7 +1989,7 @@ public final class SignalProtos {
|
||||
* <code>optional fixed64 expires = 3;</code>
|
||||
*/
|
||||
public Builder clearExpires() {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
expires_ = 0L;
|
||||
onChanged();
|
||||
return this;
|
||||
@ -1845,7 +2001,7 @@ public final class SignalProtos {
|
||||
* <code>optional bytes identityKey = 4;</code>
|
||||
*/
|
||||
public boolean hasIdentityKey() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes identityKey = 4;</code>
|
||||
@ -1860,7 +2016,7 @@ public final class SignalProtos {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000008;
|
||||
bitField0_ |= 0x00000010;
|
||||
identityKey_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
@ -1869,7 +2025,7 @@ public final class SignalProtos {
|
||||
* <code>optional bytes identityKey = 4;</code>
|
||||
*/
|
||||
public Builder clearIdentityKey() {
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
identityKey_ = getDefaultInstance().getIdentityKey();
|
||||
onChanged();
|
||||
return this;
|
||||
@ -1883,7 +2039,7 @@ public final class SignalProtos {
|
||||
* <code>optional .signal.ServerCertificate signer = 5;</code>
|
||||
*/
|
||||
public boolean hasSigner() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
return ((bitField0_ & 0x00000020) == 0x00000020);
|
||||
}
|
||||
/**
|
||||
* <code>optional .signal.ServerCertificate signer = 5;</code>
|
||||
@ -1908,7 +2064,7 @@ public final class SignalProtos {
|
||||
} else {
|
||||
signerBuilder_.setMessage(value);
|
||||
}
|
||||
bitField0_ |= 0x00000010;
|
||||
bitField0_ |= 0x00000020;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
@ -1922,7 +2078,7 @@ public final class SignalProtos {
|
||||
} else {
|
||||
signerBuilder_.setMessage(builderForValue.build());
|
||||
}
|
||||
bitField0_ |= 0x00000010;
|
||||
bitField0_ |= 0x00000020;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
@ -1930,7 +2086,7 @@ public final class SignalProtos {
|
||||
*/
|
||||
public Builder mergeSigner(org.signal.libsignal.metadata.SignalProtos.ServerCertificate value) {
|
||||
if (signerBuilder_ == null) {
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010) &&
|
||||
if (((bitField0_ & 0x00000020) == 0x00000020) &&
|
||||
signer_ != org.signal.libsignal.metadata.SignalProtos.ServerCertificate.getDefaultInstance()) {
|
||||
signer_ =
|
||||
org.signal.libsignal.metadata.SignalProtos.ServerCertificate.newBuilder(signer_).mergeFrom(value).buildPartial();
|
||||
@ -1941,7 +2097,7 @@ public final class SignalProtos {
|
||||
} else {
|
||||
signerBuilder_.mergeFrom(value);
|
||||
}
|
||||
bitField0_ |= 0x00000010;
|
||||
bitField0_ |= 0x00000020;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
@ -1954,14 +2110,14 @@ public final class SignalProtos {
|
||||
} else {
|
||||
signerBuilder_.clear();
|
||||
}
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
bitField0_ = (bitField0_ & ~0x00000020);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional .signal.ServerCertificate signer = 5;</code>
|
||||
*/
|
||||
public org.signal.libsignal.metadata.SignalProtos.ServerCertificate.Builder getSignerBuilder() {
|
||||
bitField0_ |= 0x00000010;
|
||||
bitField0_ |= 0x00000020;
|
||||
onChanged();
|
||||
return getSignerFieldBuilder().getBuilder();
|
||||
}
|
||||
@ -3735,20 +3891,21 @@ public final class SignalProtos {
|
||||
"\n\032UnidentifiedDelivery.proto\022\006signal\"c\n\021" +
|
||||
"ServerCertificate\022\023\n\013certificate\030\001 \001(\014\022\021" +
|
||||
"\n\tsignature\030\002 \001(\014\032&\n\013Certificate\022\n\n\002id\030\001" +
|
||||
" \001(\r\022\013\n\003key\030\002 \001(\014\"\302\001\n\021SenderCertificate\022" +
|
||||
" \001(\r\022\013\n\003key\030\002 \001(\014\"\332\001\n\021SenderCertificate\022" +
|
||||
"\023\n\013certificate\030\001 \001(\014\022\021\n\tsignature\030\002 \001(\014\032" +
|
||||
"\204\001\n\013Certificate\022\016\n\006sender\030\001 \001(\t\022\024\n\014sende" +
|
||||
"rDevice\030\002 \001(\r\022\017\n\007expires\030\003 \001(\006\022\023\n\013identi" +
|
||||
"tyKey\030\004 \001(\014\022)\n\006signer\030\005 \001(\0132\031.signal.Ser" +
|
||||
"verCertificate\"\241\002\n\031UnidentifiedSenderMes" +
|
||||
"sage\022\027\n\017ephemeralPublic\030\001 \001(\014\022\027\n\017encrypt",
|
||||
"edStatic\030\002 \001(\014\022\030\n\020encryptedMessage\030\003 \001(\014" +
|
||||
"\032\267\001\n\007Message\022<\n\004type\030\001 \001(\0162..signal.Unid" +
|
||||
"entifiedSenderMessage.Message.Type\0224\n\021se" +
|
||||
"nderCertificate\030\002 \001(\0132\031.signal.SenderCer" +
|
||||
"tificate\022\017\n\007content\030\003 \001(\014\"\'\n\004Type\022\022\n\016PRE" +
|
||||
"KEY_MESSAGE\020\001\022\013\n\007MESSAGE\020\002B-\n\035org.signal" +
|
||||
".libsignal.metadataB\014SignalProtos"
|
||||
"\234\001\n\013Certificate\022\022\n\nsenderE164\030\001 \001(\t\022\022\n\ns" +
|
||||
"enderUuid\030\006 \001(\t\022\024\n\014senderDevice\030\002 \001(\r\022\017\n" +
|
||||
"\007expires\030\003 \001(\006\022\023\n\013identityKey\030\004 \001(\014\022)\n\006s" +
|
||||
"igner\030\005 \001(\0132\031.signal.ServerCertificate\"\241" +
|
||||
"\002\n\031UnidentifiedSenderMessage\022\027\n\017ephemera",
|
||||
"lPublic\030\001 \001(\014\022\027\n\017encryptedStatic\030\002 \001(\014\022\030" +
|
||||
"\n\020encryptedMessage\030\003 \001(\014\032\267\001\n\007Message\022<\n\004" +
|
||||
"type\030\001 \001(\0162..signal.UnidentifiedSenderMe" +
|
||||
"ssage.Message.Type\0224\n\021senderCertificate\030" +
|
||||
"\002 \001(\0132\031.signal.SenderCertificate\022\017\n\007cont" +
|
||||
"ent\030\003 \001(\014\"\'\n\004Type\022\022\n\016PREKEY_MESSAGE\020\001\022\013\n" +
|
||||
"\007MESSAGE\020\002B-\n\035org.signal.libsignal.metad" +
|
||||
"ataB\014SignalProtos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@ -3778,7 +3935,7 @@ public final class SignalProtos {
|
||||
internal_static_signal_SenderCertificate_Certificate_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_signal_SenderCertificate_Certificate_descriptor,
|
||||
new java.lang.String[] { "Sender", "SenderDevice", "Expires", "IdentityKey", "Signer", });
|
||||
new java.lang.String[] { "SenderE164", "SenderUuid", "SenderDevice", "Expires", "IdentityKey", "Signer", });
|
||||
internal_static_signal_UnidentifiedSenderMessage_descriptor =
|
||||
getDescriptor().getMessageTypes().get(2);
|
||||
internal_static_signal_UnidentifiedSenderMessage_fieldAccessorTable = new
|
||||
|
||||
@ -7,6 +7,7 @@ import org.signal.libsignal.metadata.SignalProtos;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.libsignal.ecc.Curve;
|
||||
import org.whispersystems.libsignal.ecc.ECPublicKey;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
|
||||
public class SenderCertificate {
|
||||
@ -14,7 +15,8 @@ public class SenderCertificate {
|
||||
private final ServerCertificate signer;
|
||||
private final ECPublicKey key;
|
||||
private final int senderDeviceId;
|
||||
private final String sender;
|
||||
private final Optional<String> senderUuid;
|
||||
private final Optional<String> senderE164;
|
||||
private final long expiration;
|
||||
|
||||
private final byte[] serialized;
|
||||
@ -31,13 +33,19 @@ public class SenderCertificate {
|
||||
|
||||
SignalProtos.SenderCertificate.Certificate certificate = SignalProtos.SenderCertificate.Certificate.parseFrom(wrapper.getCertificate());
|
||||
|
||||
if (!certificate.hasSigner() || !certificate.hasIdentityKey() || !certificate.hasSenderDevice() || !certificate.hasExpires() || !certificate.hasSender()) {
|
||||
if (!certificate.hasSigner() ||
|
||||
!certificate.hasIdentityKey() ||
|
||||
!certificate.hasSenderDevice() ||
|
||||
!certificate.hasExpires() ||
|
||||
(!certificate.hasSenderUuid() && !certificate.hasSenderE164()))
|
||||
{
|
||||
throw new InvalidCertificateException("Missing fields");
|
||||
}
|
||||
|
||||
this.signer = new ServerCertificate(certificate.getSigner().toByteArray());
|
||||
this.key = Curve.decodePoint(certificate.getIdentityKey().toByteArray(), 0);
|
||||
this.sender = certificate.getSender();
|
||||
this.senderUuid = certificate.hasSenderUuid() ? Optional.of(certificate.getSenderUuid()) : Optional.<String>absent();
|
||||
this.senderE164 = certificate.hasSenderE164() ? Optional.of(certificate.getSenderE164()) : Optional.<String>absent();
|
||||
this.senderDeviceId = certificate.getSenderDevice();
|
||||
this.expiration = certificate.getExpires();
|
||||
|
||||
@ -62,8 +70,16 @@ public class SenderCertificate {
|
||||
return senderDeviceId;
|
||||
}
|
||||
|
||||
public Optional<String> getSenderUuid() {
|
||||
return senderUuid;
|
||||
}
|
||||
|
||||
public Optional<String> getSenderE164() {
|
||||
return senderE164;
|
||||
}
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
return senderUuid.or(senderE164).orNull();
|
||||
}
|
||||
|
||||
public long getExpiration() {
|
||||
|
||||
@ -15,7 +15,8 @@ message ServerCertificate {
|
||||
|
||||
message SenderCertificate {
|
||||
message Certificate {
|
||||
optional string sender = 1;
|
||||
optional string senderE164 = 1;
|
||||
optional string senderUuid = 6;
|
||||
optional uint32 senderDevice = 2;
|
||||
optional fixed64 expires = 3;
|
||||
optional bytes identityKey = 4;
|
||||
|
||||
@ -6,7 +6,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile 'junit:junit:3.8.2'
|
||||
testCompile 'junit:junit:4.12'
|
||||
|
||||
compile project(':java')
|
||||
}
|
||||
@ -5,6 +5,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.signal.libsignal.metadata.SealedSessionCipher.DecryptionResult;
|
||||
import org.signal.libsignal.metadata.certificate.CertificateValidator;
|
||||
import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
|
||||
import org.signal.libsignal.metadata.certificate.SenderCertificate;
|
||||
@ -23,6 +24,8 @@ import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.libsignal.util.KeyHelper;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class SealedSessionCipherTest extends TestCase {
|
||||
|
||||
public void testEncryptDecrypt() throws UntrustedIdentityException, InvalidKeyException, InvalidCertificateException, InvalidProtocolBufferException, InvalidMetadataMessageException, ProtocolDuplicateMessageException, ProtocolUntrustedIdentityException, ProtocolLegacyMessageException, ProtocolInvalidKeyException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolInvalidMessageException, ProtocolInvalidKeyIdException, ProtocolNoSessionException, SelfSendException {
|
||||
@ -32,20 +35,21 @@ public class SealedSessionCipherTest extends TestCase {
|
||||
initializeSessions(aliceStore, bobStore);
|
||||
|
||||
ECKeyPair trustRoot = Curve.generateKeyPair();
|
||||
SenderCertificate senderCertificate = createCertificateFor(trustRoot, "+14151111111", 1, aliceStore.getIdentityKeyPair().getPublicKey().getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, new SignalProtocolAddress("+14151111111", 1));
|
||||
SenderCertificate senderCertificate = createCertificateFor(trustRoot, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1, aliceStore.getIdentityKeyPair().getPublicKey().getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1);
|
||||
|
||||
byte[] ciphertext = aliceCipher.encrypt(new SignalProtocolAddress("+14152222222", 1),
|
||||
senderCertificate, "smert za smert".getBytes());
|
||||
|
||||
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, new SignalProtocolAddress("+14152222222", 1));
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, UUID.fromString("e80f7bbe-5b94-471e-bd8c-2173654ea3d1"), "+14152222222", 1);
|
||||
|
||||
Pair<SignalProtocolAddress, byte[]> plaintext = bobCipher.decrypt(new CertificateValidator(trustRoot.getPublicKey()), ciphertext, 31335);
|
||||
DecryptionResult plaintext = bobCipher.decrypt(new CertificateValidator(trustRoot.getPublicKey()), ciphertext, 31335);
|
||||
|
||||
assertEquals(new String(plaintext.second()), "smert za smert");
|
||||
assertEquals(plaintext.first().getName(), "+14151111111");
|
||||
assertEquals(plaintext.first().getDeviceId(), 1);
|
||||
assertEquals(new String(plaintext.getPaddedMessage()), "smert za smert");
|
||||
assertEquals(plaintext.getSenderUuid().get(), "9d0652a3-dcc3-4d11-975f-74d61598733f");
|
||||
assertEquals(plaintext.getSenderE164().get(), "+14151111111");
|
||||
assertEquals(plaintext.getDeviceId(), 1);
|
||||
}
|
||||
|
||||
public void testEncryptDecryptUntrusted() throws Exception {
|
||||
@ -56,13 +60,13 @@ public class SealedSessionCipherTest extends TestCase {
|
||||
|
||||
ECKeyPair trustRoot = Curve.generateKeyPair();
|
||||
ECKeyPair falseTrustRoot = Curve.generateKeyPair();
|
||||
SenderCertificate senderCertificate = createCertificateFor(falseTrustRoot, "+14151111111", 1, aliceStore.getIdentityKeyPair().getPublicKey().getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, new SignalProtocolAddress("+14151111111", 1));
|
||||
SenderCertificate senderCertificate = createCertificateFor(falseTrustRoot, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1, aliceStore.getIdentityKeyPair().getPublicKey().getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1);
|
||||
|
||||
byte[] ciphertext = aliceCipher.encrypt(new SignalProtocolAddress("+14152222222", 1),
|
||||
senderCertificate, "и вот я".getBytes());
|
||||
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, new SignalProtocolAddress("+14152222222",1));
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, UUID.fromString("e80f7bbe-5b94-471e-bd8c-2173654ea3d1"), "+14152222222", 1);
|
||||
|
||||
try {
|
||||
bobCipher.decrypt(new CertificateValidator(trustRoot.getPublicKey()), ciphertext, 31335);
|
||||
@ -79,13 +83,13 @@ public class SealedSessionCipherTest extends TestCase {
|
||||
initializeSessions(aliceStore, bobStore);
|
||||
|
||||
ECKeyPair trustRoot = Curve.generateKeyPair();
|
||||
SenderCertificate senderCertificate = createCertificateFor(trustRoot, "+14151111111", 1, aliceStore.getIdentityKeyPair().getPublicKey().getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, new SignalProtocolAddress("+14151111111", 1));
|
||||
SenderCertificate senderCertificate = createCertificateFor(trustRoot, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1, aliceStore.getIdentityKeyPair().getPublicKey().getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1);
|
||||
|
||||
byte[] ciphertext = aliceCipher.encrypt(new SignalProtocolAddress("+14152222222", 1),
|
||||
senderCertificate, "и вот я".getBytes());
|
||||
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, new SignalProtocolAddress("+14152222222", 1));
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, UUID.fromString("e80f7bbe-5b94-471e-bd8c-2173654ea3d1"), "+14152222222", 1);
|
||||
|
||||
try {
|
||||
bobCipher.decrypt(new CertificateValidator(trustRoot.getPublicKey()), ciphertext, 31338);
|
||||
@ -103,14 +107,14 @@ public class SealedSessionCipherTest extends TestCase {
|
||||
|
||||
ECKeyPair trustRoot = Curve.generateKeyPair();
|
||||
ECKeyPair randomKeyPair = Curve.generateKeyPair();
|
||||
SenderCertificate senderCertificate = createCertificateFor(trustRoot, "+14151111111", 1, randomKeyPair.getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, new SignalProtocolAddress("+14151111111", 1));
|
||||
SenderCertificate senderCertificate = createCertificateFor(trustRoot, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1, randomKeyPair.getPublicKey(), 31337);
|
||||
SealedSessionCipher aliceCipher = new SealedSessionCipher(aliceStore, UUID.fromString("9d0652a3-dcc3-4d11-975f-74d61598733f"), "+14151111111", 1);
|
||||
|
||||
byte[] ciphertext = aliceCipher.encrypt(new SignalProtocolAddress("+14152222222", 1),
|
||||
senderCertificate, "smert za smert".getBytes());
|
||||
|
||||
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, new SignalProtocolAddress("+14152222222", 1));
|
||||
SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, UUID.fromString("e80f7bbe-5b94-471e-bd8c-2173654ea3d1"), "+14152222222", 1);
|
||||
|
||||
try {
|
||||
bobCipher.decrypt(new CertificateValidator(trustRoot.getPublicKey()), ciphertext, 31335);
|
||||
@ -121,7 +125,7 @@ public class SealedSessionCipherTest extends TestCase {
|
||||
|
||||
|
||||
|
||||
private SenderCertificate createCertificateFor(ECKeyPair trustRoot, String sender, int deviceId, ECPublicKey identityKey, long expires)
|
||||
private SenderCertificate createCertificateFor(ECKeyPair trustRoot, UUID uuid, String e164, int deviceId, ECPublicKey identityKey, long expires)
|
||||
throws InvalidKeyException, InvalidCertificateException, InvalidProtocolBufferException {
|
||||
ECKeyPair serverKey = Curve.generateKeyPair();
|
||||
|
||||
@ -140,7 +144,8 @@ public class SealedSessionCipherTest extends TestCase {
|
||||
.toByteArray());
|
||||
|
||||
byte[] senderCertificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
|
||||
.setSender(sender)
|
||||
.setSenderUuid(uuid.toString())
|
||||
.setSenderE164(e164)
|
||||
.setSenderDevice(deviceId)
|
||||
.setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
|
||||
.setExpires(expires)
|
||||
|
||||
@ -19,7 +19,8 @@ public class SenderCertificateTest extends TestCase {
|
||||
ECKeyPair key = Curve.generateKeyPair();
|
||||
|
||||
byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
|
||||
.setSender("+14152222222")
|
||||
.setSenderUuid("9d0652a3-dcc3-4d11-975f-74d61598733f")
|
||||
.setSenderE164("+14152222222")
|
||||
.setSenderDevice(1)
|
||||
.setExpires(31337)
|
||||
.setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
|
||||
@ -43,7 +44,8 @@ public class SenderCertificateTest extends TestCase {
|
||||
ECKeyPair key = Curve.generateKeyPair();
|
||||
|
||||
byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
|
||||
.setSender("+14152222222")
|
||||
.setSenderUuid("9d0652a3-dcc3-4d11-975f-74d61598733f")
|
||||
.setSenderE164("+14152222222")
|
||||
.setSenderDevice(1)
|
||||
.setExpires(31337)
|
||||
.setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
|
||||
@ -72,7 +74,8 @@ public class SenderCertificateTest extends TestCase {
|
||||
ECKeyPair key = Curve.generateKeyPair();
|
||||
|
||||
byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
|
||||
.setSender("+14152222222")
|
||||
.setSenderUuid("9d0652a3-dcc3-4d11-975f-74d61598733f")
|
||||
.setSenderE164("+14152222222")
|
||||
.setSenderDevice(1)
|
||||
.setExpires(31337)
|
||||
.setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user