mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-28 02:37:46 +00:00
Add padding for push messages.
1) Use 'bit padding.' 1) By default, pad at 160 byte increments.
This commit is contained in:
parent
fcaa3f0d73
commit
07fd17ccda
@ -168,6 +168,13 @@ public class SessionCipher {
|
||||
}
|
||||
|
||||
WhisperMessage ciphertextMessage = new WhisperMessage(decodedMessage);
|
||||
|
||||
if (ciphertextMessage.getMessageVersion() != sessionState.getSessionVersion()) {
|
||||
throw new InvalidMessageException(String.format("Message version %d, but session version %d",
|
||||
ciphertextMessage.getMessageVersion(),
|
||||
sessionState.getSessionVersion()));
|
||||
}
|
||||
|
||||
ECPublicKey theirEphemeral = ciphertextMessage.getSenderEphemeral();
|
||||
int counter = ciphertextMessage.getCounter();
|
||||
ChainKey chainKey = getOrCreateChainKey(sessionState, theirEphemeral);
|
||||
|
@ -16,20 +16,53 @@
|
||||
*/
|
||||
package org.whispersystems.textsecure.push;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.whispersystems.textsecure.crypto.TransportDetails;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PushTransportDetails implements TransportDetails {
|
||||
|
||||
private final int messageVersion;
|
||||
|
||||
public PushTransportDetails(int messageVersion) {
|
||||
this.messageVersion = messageVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getStrippedPaddingMessageBody(byte[] messageWithPadding) {
|
||||
return messageWithPadding;
|
||||
if (messageVersion < 2) throw new AssertionError("Unknown version: " + messageVersion);
|
||||
else if (messageVersion == 2) return messageWithPadding;
|
||||
|
||||
int paddingStart = 0;
|
||||
|
||||
for (int i=messageWithPadding.length-1;i>=0;i--) {
|
||||
if (messageWithPadding[i] == (byte)0x80) {
|
||||
paddingStart = i;
|
||||
break;
|
||||
} else if (messageWithPadding[i] != (byte)0x00) {
|
||||
Log.w("PushTransportDetails", "Padding byte is malformed, returning unstripped padding.");
|
||||
return messageWithPadding;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] strippedMessage = new byte[messageWithPadding.length - paddingStart];
|
||||
System.arraycopy(messageWithPadding, 0, strippedMessage, 0, strippedMessage.length);
|
||||
|
||||
return strippedMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getPaddedMessageBody(byte[] messageBody) {
|
||||
return messageBody;
|
||||
if (messageVersion < 2) throw new AssertionError("Unknown version: " + messageVersion);
|
||||
else if (messageVersion == 2) return messageBody;
|
||||
|
||||
byte[] paddedMessage = new byte[getPaddedMessageLength(messageBody.length)];
|
||||
System.arraycopy(messageBody, 0, paddedMessage, 0, messageBody.length);
|
||||
paddedMessage[messageBody.length] = (byte)0x80;
|
||||
|
||||
return paddedMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,4 +74,15 @@ public class PushTransportDetails implements TransportDetails {
|
||||
public byte[] getDecodedMessage(byte[] encodedMessageBytes) throws IOException {
|
||||
return encodedMessageBytes;
|
||||
}
|
||||
|
||||
private int getPaddedMessageLength(int messageLength) {
|
||||
int messageLengthWithTerminator = messageLength + 1;
|
||||
int messagePartCount = messageLengthWithTerminator / 160;
|
||||
|
||||
if (messageLengthWithTerminator % 160 != 0) {
|
||||
messagePartCount++;
|
||||
}
|
||||
|
||||
return messagePartCount * 160;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,17 @@ import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
||||
public class SessionUtil {
|
||||
|
||||
public static int getSessionVersion(Context context,
|
||||
MasterSecret masterSecret,
|
||||
RecipientDevice recipient)
|
||||
{
|
||||
return
|
||||
new TextSecureSessionStore(context, masterSecret)
|
||||
.loadSession(recipient.getRecipientId(), recipient.getDeviceId())
|
||||
.getSessionState()
|
||||
.getSessionVersion();
|
||||
}
|
||||
|
||||
public static boolean hasEncryptCapableSession(Context context,
|
||||
MasterSecret masterSecret,
|
||||
CanonicalRecipient recipient)
|
||||
|
@ -52,8 +52,11 @@ import org.whispersystems.libaxolotl.protocol.WhisperMessage;
|
||||
import org.whispersystems.libaxolotl.state.SessionStore;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.SessionCipherFactory;
|
||||
import org.whispersystems.textsecure.crypto.TransportDetails;
|
||||
import org.whispersystems.textsecure.push.IncomingPushMessage;
|
||||
import org.whispersystems.textsecure.push.PushTransportDetails;
|
||||
import org.whispersystems.textsecure.storage.RecipientDevice;
|
||||
import org.whispersystems.textsecure.storage.SessionUtil;
|
||||
import org.whispersystems.textsecure.storage.TextSecureSessionStore;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
import org.whispersystems.textsecure.util.Hex;
|
||||
@ -210,10 +213,12 @@ public class DecryptingQueue {
|
||||
return;
|
||||
}
|
||||
|
||||
SessionCipher sessionCipher = SessionCipherFactory.getInstance(context, masterSecret, recipientDevice);
|
||||
byte[] plaintextBody = sessionCipher.decrypt(message.getBody());
|
||||
int sessionVersion = SessionUtil.getSessionVersion(context, masterSecret, recipientDevice);
|
||||
SessionCipher sessionCipher = SessionCipherFactory.getInstance(context, masterSecret, recipientDevice);
|
||||
byte[] plaintextBody = sessionCipher.decrypt(message.getBody());
|
||||
TransportDetails transport = new PushTransportDetails(sessionVersion);
|
||||
|
||||
message = message.withBody(plaintextBody);
|
||||
message = message.withBody(transport.getStrippedPaddingMessageBody(plaintextBody));
|
||||
sendResult(PushReceiver.RESULT_OK);
|
||||
} catch (InvalidMessageException | LegacyMessageException | RecipientFormattingException e) {
|
||||
Log.w("DecryptionQueue", e);
|
||||
|
@ -52,6 +52,7 @@ import org.whispersystems.textsecure.push.PushAttachmentPointer;
|
||||
import org.whispersystems.textsecure.push.PushBody;
|
||||
import org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent;
|
||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||
import org.whispersystems.textsecure.push.PushTransportDetails;
|
||||
import org.whispersystems.textsecure.push.StaleDevices;
|
||||
import org.whispersystems.textsecure.push.StaleDevicesException;
|
||||
import org.whispersystems.textsecure.push.UnregisteredUserException;
|
||||
@ -344,8 +345,10 @@ public class PushTransport extends BaseTransport {
|
||||
}
|
||||
}
|
||||
|
||||
int sessionVersion = SessionUtil.getSessionVersion(context, masterSecret, pushAddress);
|
||||
SessionCipher cipher = SessionCipherFactory.getInstance(context, masterSecret, pushAddress);
|
||||
CiphertextMessage message = cipher.encrypt(plaintext);
|
||||
byte[] paddedPlaintext = new PushTransportDetails(sessionVersion).getPaddedMessageBody(plaintext);
|
||||
CiphertextMessage message = cipher.encrypt(paddedPlaintext);
|
||||
int remoteRegistrationId = cipher.getRemoteRegistrationId();
|
||||
|
||||
if (message.getType() == CiphertextMessage.PREKEY_TYPE) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user