Send/receive unencrypted messages.

This commit is contained in:
Anton Chekulaev 2020-12-09 22:12:40 +11:00
parent 3bc4338444
commit 45ff8fba36
3 changed files with 75 additions and 62 deletions

View File

@ -299,18 +299,18 @@ public class SignalServiceMessageSender {
boolean isClosedGroup = message.group.isPresent() && message.group.get().getGroupType() == SignalServiceGroup.GroupType.SIGNAL;
SendMessageResult result = sendMessage(messageID, recipient, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, content, false, message.getTTL(), message.getDeviceLink().isPresent(), useFallbackEncryption, isClosedGroup, false, message.hasVisibleContent());
// Loki - This shouldn't get invoked for note to self
boolean wouldSignalSendSyncMessage = (result.getSuccess() != null && result.getSuccess().isNeedsSync()) || unidentifiedAccess.isPresent();
if (wouldSignalSendSyncMessage && SyncMessagesProtocol.shared.shouldSyncMessage(message)) {
byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, Optional.of(recipient), timestamp, Collections.singletonList(result));
// Loki - Customize multi device logic
Set<String> linkedDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey);
for (String device : linkedDevices) {
SignalServiceAddress deviceAsAddress = new SignalServiceAddress(device);
boolean useFallbackEncryptionForSyncMessage = SessionManagementProtocol.shared.shouldMessageUseFallbackEncryption(syncMessage, device, store);
sendMessage(deviceAsAddress, Optional.<UnidentifiedAccess>absent(), timestamp, syncMessage, false, message.getTTL(), useFallbackEncryptionForSyncMessage, true);
}
}
// // Loki - This shouldn't get invoked for note to self
// boolean wouldSignalSendSyncMessage = (result.getSuccess() != null && result.getSuccess().isNeedsSync()) || unidentifiedAccess.isPresent();
// if (wouldSignalSendSyncMessage && SyncMessagesProtocol.shared.shouldSyncMessage(message)) {
// byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, Optional.of(recipient), timestamp, Collections.singletonList(result));
// // Loki - Customize multi device logic
// Set<String> linkedDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey);
// for (String device : linkedDevices) {
// SignalServiceAddress deviceAsAddress = new SignalServiceAddress(device);
// boolean useFallbackEncryptionForSyncMessage = SessionManagementProtocol.shared.shouldMessageUseFallbackEncryption(syncMessage, device, store);
// sendMessage(deviceAsAddress, Optional.<UnidentifiedAccess>absent(), timestamp, syncMessage, false, message.getTTL(), useFallbackEncryptionForSyncMessage, true);
// }
// }
// Loki - Start a session reset if needed
if (message.isEndSession()) {
@ -500,31 +500,31 @@ public class SignalServiceMessageSender {
{
Content.Builder container = Content.newBuilder();
if (message.getPreKeyBundle().isPresent()) {
PreKeyBundle preKeyBundle = message.getPreKeyBundle().get();
PreKeyBundleMessage.Builder preKeyBundleMessageBuilder = PreKeyBundleMessage.newBuilder()
.setDeviceId(preKeyBundle.getDeviceId())
.setIdentityKey(ByteString.copyFrom(preKeyBundle.getIdentityKey().serialize()))
.setPreKeyId(preKeyBundle.getPreKeyId())
.setPreKey(ByteString.copyFrom(preKeyBundle.getPreKey().serialize()))
.setSignedKeyId(preKeyBundle.getSignedPreKeyId())
.setSignedKey(ByteString.copyFrom(preKeyBundle.getSignedPreKey().serialize()))
.setSignature(ByteString.copyFrom(preKeyBundle.getSignedPreKeySignature()))
.setIdentityKey(ByteString.copyFrom(preKeyBundle.getIdentityKey().serialize()));
container.setPreKeyBundleMessage(preKeyBundleMessageBuilder);
}
// if (message.getPreKeyBundle().isPresent()) {
// PreKeyBundle preKeyBundle = message.getPreKeyBundle().get();
// PreKeyBundleMessage.Builder preKeyBundleMessageBuilder = PreKeyBundleMessage.newBuilder()
// .setDeviceId(preKeyBundle.getDeviceId())
// .setIdentityKey(ByteString.copyFrom(preKeyBundle.getIdentityKey().serialize()))
// .setPreKeyId(preKeyBundle.getPreKeyId())
// .setPreKey(ByteString.copyFrom(preKeyBundle.getPreKey().serialize()))
// .setSignedKeyId(preKeyBundle.getSignedPreKeyId())
// .setSignedKey(ByteString.copyFrom(preKeyBundle.getSignedPreKey().serialize()))
// .setSignature(ByteString.copyFrom(preKeyBundle.getSignedPreKeySignature()))
// .setIdentityKey(ByteString.copyFrom(preKeyBundle.getIdentityKey().serialize()));
// container.setPreKeyBundleMessage(preKeyBundleMessageBuilder);
// }
if (message.getDeviceLink().isPresent()) {
DeviceLink deviceLink = message.getDeviceLink().get();
SignalServiceProtos.DeviceLinkMessage.Builder deviceLinkMessageBuilder = SignalServiceProtos.DeviceLinkMessage.newBuilder()
.setPrimaryPublicKey(deviceLink.getMasterPublicKey())
.setSecondaryPublicKey(deviceLink.getSlavePublicKey())
.setRequestSignature(ByteString.copyFrom(Objects.requireNonNull(deviceLink.getRequestSignature())));
if (deviceLink.getAuthorizationSignature() != null) {
deviceLinkMessageBuilder.setAuthorizationSignature(ByteString.copyFrom(deviceLink.getAuthorizationSignature()));
}
container.setDeviceLinkMessage(deviceLinkMessageBuilder.build());
}
// if (message.getDeviceLink().isPresent()) {
// DeviceLink deviceLink = message.getDeviceLink().get();
// SignalServiceProtos.DeviceLinkMessage.Builder deviceLinkMessageBuilder = SignalServiceProtos.DeviceLinkMessage.newBuilder()
// .setPrimaryPublicKey(deviceLink.getMasterPublicKey())
// .setSecondaryPublicKey(deviceLink.getSlavePublicKey())
// .setRequestSignature(ByteString.copyFrom(Objects.requireNonNull(deviceLink.getRequestSignature())));
// if (deviceLink.getAuthorizationSignature() != null) {
// deviceLinkMessageBuilder.setAuthorizationSignature(ByteString.copyFrom(deviceLink.getAuthorizationSignature()));
// }
// container.setDeviceLinkMessage(deviceLinkMessageBuilder.build());
// }
DataMessage.Builder builder = DataMessage.newBuilder();
List<AttachmentPointer> pointers = createAttachmentPointers(message.getAttachments(), recipient);
@ -1365,15 +1365,19 @@ public class SignalServiceMessageSender {
if (!recipient.equals(localAddress) || unidentifiedAccess.isPresent()) {
if (sskDatabase.isSSKBasedClosedGroup(recipient.getNumber()) && unidentifiedAccess.isPresent()) {
messages.add(getSSKEncryptedMessage(recipient.getNumber(), unidentifiedAccess.get(), plaintext));
} else if (useFallbackEncryption) {
messages.add(getFallbackCipherEncryptedMessage(recipient.getNumber(), plaintext, unidentifiedAccess));
// } else if (useFallbackEncryption) {
// messages.add(getFallbackCipherEncryptedMessage(recipient.getNumber(), plaintext, unidentifiedAccess));
// } else {
// OutgoingPushMessage message = getEncryptedMessage(socket, recipient, unidentifiedAccess, plaintext, isClosedGroup);
// if (message != null) { // May be null in a closed group context
// messages.add(message);
// }
// }
} else {
OutgoingPushMessage message = getEncryptedMessage(socket, recipient, unidentifiedAccess, plaintext, isClosedGroup);
if (message != null) { // May be null in a closed group context
OutgoingPushMessage message = getFallbackCipherEncryptedMessage(recipient.getNumber(), plaintext, unidentifiedAccess);
messages.add(message);
}
}
}
return new OutgoingPushMessageList(recipient.getNumber(), timestamp, messages, online);
}
@ -1383,17 +1387,19 @@ public class SignalServiceMessageSender {
{
Log.d("Loki", "Using fallback cipher.");
int deviceID = SignalServiceAddress.DEFAULT_DEVICE_ID;
SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(publicKey, deviceID);
byte[] userPrivateKey = store.getIdentityKeyPair().getPrivateKey().serialize();
FallbackSessionCipher cipher = new FallbackSessionCipher(userPrivateKey, publicKey);
// SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(publicKey, deviceID);
// byte[] userPrivateKey = store.getIdentityKeyPair().getPrivateKey().serialize();
// FallbackSessionCipher cipher = new FallbackSessionCipher(userPrivateKey, publicKey);
PushTransportDetails transportDetails = new PushTransportDetails(FallbackSessionCipher.getSessionVersion());
byte[] bytes = cipher.encrypt(transportDetails.getPaddedMessageBody(plaintext));
if (bytes == null) { bytes = new byte[0]; }
// byte[] bytes = cipher.encrypt(transportDetails.getPaddedMessageBody(plaintext));
byte[] bytes = transportDetails.getPaddedMessageBody(plaintext);
// if (bytes == null) { bytes = new byte[0]; }
if (unidentifiedAccess.isPresent()) {
SealedSessionCipher sealedSessionCipher = new SealedSessionCipher(store, null, signalProtocolAddress);
FallbackMessage message = new FallbackMessage(bytes);
byte[] ciphertext = sealedSessionCipher.encrypt(signalProtocolAddress, unidentifiedAccess.get().getUnidentifiedCertificate(), message);
return new OutgoingPushMessage(SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE, deviceID, 0, Base64.encodeBytes(ciphertext));
// SealedSessionCipher sealedSessionCipher = new SealedSessionCipher(store, null, signalProtocolAddress);
// FallbackMessage message = new FallbackMessage(bytes);
// byte[] ciphertext = sealedSessionCipher.encrypt(signalProtocolAddress, unidentifiedAccess.get().getUnidentifiedCertificate(), message);
// return new OutgoingPushMessage(SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE, deviceID, 0, Base64.encodeBytes(ciphertext));
return new OutgoingPushMessage(SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE, deviceID, 0, Base64.encodeBytes(bytes));
} else {
return new OutgoingPushMessage(SignalServiceProtos.Envelope.Type.FALLBACK_MESSAGE_VALUE, deviceID, 0, Base64.encodeBytes(bytes));
}

View File

@ -23,7 +23,13 @@ class LokiServiceCipher(
override fun decrypt(envelope: SignalServiceEnvelope, ciphertext: ByteArray): Plaintext {
// return if (envelope.isFallbackMessage) decryptFallbackMessage(envelope, ciphertext) else super.decrypt(envelope, ciphertext)
return decryptFallbackMessage(envelope, ciphertext);
// return decryptFallbackMessage(envelope, ciphertext);
//AC: Messages come unencrypted (for refactoring time being).
val transportDetails = PushTransportDetails(FallbackSessionCipher.sessionVersion)
val unpaddedMessageBody = transportDetails.getStrippedPaddingMessageBody(ciphertext)
val metadata = Metadata(envelope.source, envelope.sourceDevice, envelope.timestamp, false)
return Plaintext(metadata, unpaddedMessageBody)
}
private fun decryptFallbackMessage(envelope: SignalServiceEnvelope, ciphertext: ByteArray): Plaintext {

View File

@ -30,10 +30,11 @@ public class SessionManagementProtocol(private val sessionResetImpl: SessionRese
// region Sending
public fun shouldMessageUseFallbackEncryption(message: Any, publicKey: String, store: SignalProtocolStore): Boolean {
if (sskDatabase.isSSKBasedClosedGroup(publicKey)) { return true } // We don't actually use fallback encryption but this indicates that we don't need a session
if (message is SignalServiceDataMessage && message.preKeyBundle.isPresent) { return true; } // This covers session requests as well as end session messages
val recipient = SignalProtocolAddress(publicKey, SignalServiceAddress.DEFAULT_DEVICE_ID)
return !store.containsSession(recipient)
// if (sskDatabase.isSSKBasedClosedGroup(publicKey)) { return true } // We don't actually use fallback encryption but this indicates that we don't need a session
// if (message is SignalServiceDataMessage && message.preKeyBundle.isPresent) { return true; } // This covers session requests as well as end session messages
// val recipient = SignalProtocolAddress(publicKey, SignalServiceAddress.DEFAULT_DEVICE_ID)
// return !store.containsSession(recipient)
return true;
}
/**