Skip to content

Commit

Permalink
Fix for 'bad encrypted message' errors.
Browse files Browse the repository at this point in the history
1) There was a regression in the outgoing multipart transport
   logic, such that the same 'identifier' byte would be used
   for all messages (0).  This now works correctly.

2) Added some additional heuristics on the receiving side.
   Now mutlipart containers are only valid for 1hr, and are
   considered invalid if the container size is different from
   the multipart message size.
  • Loading branch information
moxie0 committed Jul 22, 2013
1 parent 4281df7 commit 7d07d56
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 21 deletions.
32 changes: 32 additions & 0 deletions src/org/thoughtcrime/securesms/sms/MultipartSmsIdentifier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.thoughtcrime.securesms.sms;


import java.util.HashMap;

public class MultipartSmsIdentifier {

private static final MultipartSmsIdentifier instance = new MultipartSmsIdentifier();

public static MultipartSmsIdentifier getInstance() {
return instance;
}

private final HashMap<String, Integer> idMap = new HashMap<String, Integer>();

public synchronized byte getIdForRecipient(String recipient) {
Integer currentId;

if (idMap.containsKey(recipient)) {
currentId = idMap.get(recipient);
idMap.remove(recipient);
} else {
currentId = 0;
}

byte id = currentId.byteValue();
idMap.put(recipient, (currentId + 1) % 255);

return id;
}

}
29 changes: 9 additions & 20 deletions src/org/thoughtcrime/securesms/sms/MultipartSmsMessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ public class MultipartSmsMessageHandler {
private final HashMap<String, MultipartSmsTransportMessageFragments> partialMessages =
new HashMap<String, MultipartSmsTransportMessageFragments>();

private final HashMap<String, Integer> idMap = new HashMap<String, Integer>();

private IncomingTextMessage processMultipartMessage(MultipartSmsTransportMessage message) {
Log.w("MultipartSmsMessageHandler", "Processing multipart message...");
Log.w("MultipartSmsMessageHandler", "Multipart Count: " + message.getMultipartCount());
Log.w("MultipartSmsMessageHandler", "Multipart ID: " + message.getIdentifier());
Log.w("MultipartSmsMessageHandler", "Multipart Key: " + message.getKey());
MultipartSmsTransportMessageFragments container = partialMessages.get(message.getKey());

if (container == null) {
Log.w("MultipartSmsMessageHandler", "Found multipart container: " + container);

if (container == null || container.getSize() != message.getMultipartCount() || container.isExpired()) {
Log.w("MultipartSmsMessageHandler", "Constructing new container...");
container = new MultipartSmsTransportMessageFragments(message.getMultipartCount());
partialMessages.put(message.getKey(), container);
}
Expand Down Expand Up @@ -81,24 +85,9 @@ public IncomingTextMessage processPotentialMultipartMessage(IncomingTextMessage
}
}

private byte getIdForRecipient(String recipient) {
Integer currentId;

if (idMap.containsKey(recipient)) {
currentId = idMap.get(recipient);
idMap.remove(recipient);
} else {
currentId = 0;
}

byte id = currentId.byteValue();
idMap.put(recipient, (currentId + 1) % 255);

return id;
}

public ArrayList<String> divideMessage(OutgoingTextMessage message) {
byte identifier = getIdForRecipient(message.getRecipients().getPrimaryRecipient().getNumber());
String number = message.getRecipients().getPrimaryRecipient().getNumber();
byte identifier = MultipartSmsIdentifier.getInstance().getIdForRecipient(number);
return MultipartSmsTransportMessage.getEncoded(message, identifier);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@

public class MultipartSmsTransportMessageFragments {

private static final long VALID_TIME = 60 * 60 * 1000; // 1 Hour

private final byte[][] fragments;
private final long initializedTime;

public MultipartSmsTransportMessageFragments(int count) {
this.fragments = new byte[count][];
this.fragments = new byte[count][];
this.initializedTime = System.currentTimeMillis();
}

public void add(MultipartSmsTransportMessage fragment) {
this.fragments[fragment.getMultipartIndex()] = fragment.getStrippedMessage();
}

public int getSize() {
return this.fragments.length;
}

public boolean isExpired() {
return (System.currentTimeMillis() - initializedTime) >= VALID_TIME;
}

public boolean isComplete() {
for (int i=0;i<fragments.length;i++)
if (fragments[i] == null) return false;
Expand All @@ -37,4 +49,9 @@ public byte[] getJoined() {
return totalMessage;
}

@Override
public String toString() {
return String.format("[Size: %d, Initialized: %d, Exipired: %s, Complete: %s]",
fragments.length, initializedTime, isExpired()+"", isComplete()+"");
}
}

0 comments on commit 7d07d56

Please sign in to comment.