Java Code Examples for org.whispersystems.libsignal.LegacyMessageException

The following examples show how to use org.whispersystems.libsignal.LegacyMessageException. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source Project: Silence   Author: SilenceIM   File: SmsCipher.java    License: GNU General Public License v3.0 6 votes vote down vote up
public IncomingTextMessage decrypt(Context context, IncomingTextMessage message)
    throws LegacyMessageException, InvalidMessageException, DuplicateMessageException,
           NoSessionException, UntrustedIdentityException
{
  try {
    byte[]        decoded       = transportDetails.getDecodedMessage(message.getMessageBody().getBytes());
    SignalMessage signalMessage = new SignalMessage(decoded);
    SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, new SignalProtocolAddress(message.getSender(), 1));
    byte[]        padded        = sessionCipher.decrypt(signalMessage);
    byte[]        plaintext     = transportDetails.getStrippedPaddingMessageBody(padded);

    if (message.isEndSession() && "TERMINATE".equals(new String(plaintext))) {
      signalProtocolStore.deleteSession(new SignalProtocolAddress(message.getSender(), 1));
    }

    return message.withMessageBody(new String(plaintext));
  } catch (IOException | IllegalArgumentException | NullPointerException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #2
Source Project: Silence   Author: SilenceIM   File: SmsCipher.java    License: GNU General Public License v3.0 6 votes vote down vote up
public IncomingEncryptedMessage decrypt(Context context, IncomingPreKeyBundleMessage message)
    throws InvalidVersionException, InvalidMessageException, DuplicateMessageException,
           UntrustedIdentityException, LegacyMessageException
{
  try {
    byte[]              decoded       = transportDetails.getDecodedMessage(message.getMessageBody().getBytes());
    PreKeySignalMessage preKeyMessage = new PreKeySignalMessage(decoded);
    SessionCipher       sessionCipher = new SessionCipher(signalProtocolStore, new SignalProtocolAddress(message.getSender(), 1));
    byte[]              padded        = sessionCipher.decrypt(preKeyMessage);
    byte[]              plaintext     = transportDetails.getStrippedPaddingMessageBody(padded);

    return new IncomingEncryptedMessage(message, new String(plaintext));
  } catch (IOException | InvalidKeyException | InvalidKeyIdException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #3
Source Project: Silence   Author: SilenceIM   File: SmsCipher.java    License: GNU General Public License v3.0 6 votes vote down vote up
public OutgoingKeyExchangeMessage process(Context context, IncomingKeyExchangeMessage message)
    throws UntrustedIdentityException, StaleKeyExchangeException,
           InvalidVersionException, LegacyMessageException, InvalidMessageException
{
  try {
    Recipients            recipients            = RecipientFactory.getRecipientsFromString(context, message.getSender(), false);
    SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(message.getSender(), 1);
    KeyExchangeMessage    exchangeMessage       = new KeyExchangeMessage(transportDetails.getDecodedMessage(message.getMessageBody().getBytes()));
    SessionBuilder        sessionBuilder        = new SessionBuilder(signalProtocolStore, signalProtocolAddress);

    KeyExchangeMessage response        = sessionBuilder.process(exchangeMessage);

    if (response != null) {
      byte[] serializedResponse = transportDetails.getEncodedMessage(response.serialize());
      return new OutgoingKeyExchangeMessage(recipients, new String(serializedResponse), message.getSubscriptionId());
    } else {
      return null;
    }
  } catch (IOException | InvalidKeyException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #4
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipherTest.java    License: GNU General Public License v3.0 6 votes vote down vote up
public void testNoSession() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException {
    InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
    InMemorySenderKeyStore bobStore   = new InMemorySenderKeyStore();

    GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
    GroupSessionBuilder bobSessionBuilder   = new GroupSessionBuilder(bobStore);

    GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, GROUP_SENDER);
    GroupCipher bobGroupCipher   = new GroupCipher(bobStore, GROUP_SENDER);

    SenderKeyDistributionMessage sentAliceDistributionMessage     = aliceSessionBuilder.create(GROUP_SENDER);
    SenderKeyDistributionMessage receivedAliceDistributionMessage = new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());

//    bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage);

    byte[] ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert".getBytes());
    try {
      byte[] plaintextFromAlice  = bobGroupCipher.decrypt(ciphertextFromAlice);
      throw new AssertionError("Should be no session!");
    } catch (NoSessionException e) {
      // good
    }
  }
 
Example #5
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipherTest.java    License: GNU General Public License v3.0 6 votes vote down vote up
public void testBasicEncryptDecrypt()
    throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
  InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
  InMemorySenderKeyStore bobStore   = new InMemorySenderKeyStore();

  GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
  GroupSessionBuilder bobSessionBuilder   = new GroupSessionBuilder(bobStore);

  GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, GROUP_SENDER);
  GroupCipher bobGroupCipher   = new GroupCipher(bobStore, GROUP_SENDER);

  SenderKeyDistributionMessage sentAliceDistributionMessage     = aliceSessionBuilder.create(GROUP_SENDER);
  SenderKeyDistributionMessage receivedAliceDistributionMessage = new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());
  bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage);

  byte[] ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert".getBytes());
  byte[] plaintextFromAlice  = bobGroupCipher.decrypt(ciphertextFromAlice);

  assertTrue(new String(plaintextFromAlice).equals("smert ze smert"));
}
 
Example #6
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipherTest.java    License: GNU General Public License v3.0 6 votes vote down vote up
public void testLargeMessages() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException {
  InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
  InMemorySenderKeyStore bobStore   = new InMemorySenderKeyStore();

  GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
  GroupSessionBuilder bobSessionBuilder   = new GroupSessionBuilder(bobStore);

  GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, GROUP_SENDER);
  GroupCipher bobGroupCipher   = new GroupCipher(bobStore, GROUP_SENDER);

  SenderKeyDistributionMessage sentAliceDistributionMessage     = aliceSessionBuilder.create(GROUP_SENDER);
  SenderKeyDistributionMessage receivedAliceDistributionMessage = new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());
  bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage);

  byte[] plaintext = new byte[1024 * 1024];
  new Random().nextBytes(plaintext);

  byte[] ciphertextFromAlice = aliceGroupCipher.encrypt(plaintext);
  byte[] plaintextFromAlice  = bobGroupCipher.decrypt(ciphertextFromAlice);

  assertTrue(Arrays.equals(plaintext, plaintextFromAlice));
}
 
Example #7
Source Project: bcm-android   Author: bcmapp   File: SignalServiceCipher.java    License: GNU General Public License v3.0 5 votes vote down vote up
private byte[] decrypt(SignalServiceProtos.Envelope envelope, byte[] ciphertext)
    throws InvalidVersionException, InvalidMessageException, InvalidKeyException,
           DuplicateMessageException, InvalidKeyIdException, UntrustedIdentityException,
           LegacyMessageException, NoSessionException
{
  SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSource(), envelope.getSourceDevice());
  SessionCipher         sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress);

  byte[] paddedMessage;

  if (envelope.getType() == Type.PREKEY_BUNDLE) {
    paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext));
      //纠正remote register id
      SessionRecord sessionRecord = signalProtocolStore.loadSession(sourceAddress);
      if (sessionRecord.getSessionState().getRemoteRegistrationId() == 0) {
          sessionRecord.getSessionState().setRemoteRegistrationId(envelope.getSourceRegistration());
          signalProtocolStore.storeSession(sourceAddress, sessionRecord);
      }

  } else if (envelope.getType() == Type.CIPHERTEXT) {
    paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext));
  } else {
    throw new InvalidMessageException("Unknown type: " + envelope.getType());
  }

  PushTransportDetails transportDetails = new PushTransportDetails(sessionCipher.getSessionVersion());
  return transportDetails.getStrippedPaddingMessageBody(paddedMessage);
}
 
Example #8
Source Project: Silence   Author: SilenceIM   File: KeyExchangeMessage.java    License: GNU General Public License v3.0 5 votes vote down vote up
public KeyExchangeMessage(byte[] serialized)
    throws InvalidMessageException, InvalidVersionException, LegacyMessageException
{
  try {
    byte[][] parts        = ByteUtil.split(serialized, 1, serialized.length - 1);
    this.version          = ByteUtil.highBitsToInt(parts[0][0]);
    this.supportedVersion = ByteUtil.lowBitsToInt(parts[0][0]);

    if (this.version < CiphertextMessage.CURRENT_VERSION) {
      throw new LegacyMessageException("Unsupported legacy version: " + this.version);
    }

    if (this.version > CiphertextMessage.CURRENT_VERSION) {
      throw new InvalidVersionException("Unknown version: " + this.version);
    }

    SignalProtos.KeyExchangeMessage message = SignalProtos.KeyExchangeMessage.parseFrom(parts[1]);

    if (!message.hasId()           || !message.hasBaseKey()     ||
        !message.hasRatchetKey()   || !message.hasIdentityKey() ||
        !message.hasBaseKeySignature())
    {
      throw new InvalidMessageException("Some required fields missing!");
    }

    this.sequence         = message.getId() >> 5;
    this.flags            = message.getId() & 0x1f;
    this.serialized       = serialized;
    this.baseKey          = Curve.decodePoint(message.getBaseKey().toByteArray(), 0);
    this.baseKeySignature = message.getBaseKeySignature().toByteArray();
    this.ratchetKey       = Curve.decodePoint(message.getRatchetKey().toByteArray(), 0);
    this.identityKey      = new IdentityKey(message.getIdentityKey().toByteArray(), 0);
  } catch (InvalidKeyException | IOException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #9
Source Project: Silence   Author: SilenceIM   File: SmsDecryptJob.java    License: GNU General Public License v3.0 5 votes vote down vote up
private void handleSecureMessage(MasterSecret masterSecret, long messageId, long threadId,
                                 IncomingTextMessage message)
    throws NoSessionException, DuplicateMessageException,
           InvalidMessageException, LegacyMessageException,
           UntrustedIdentityException
{
  EncryptingSmsDatabase database  = DatabaseFactory.getEncryptingSmsDatabase(context);
  SmsCipher             cipher    = new SmsCipher(new SilenceSignalProtocolStore(context, masterSecret, message.getSubscriptionId()));
  IncomingTextMessage   plaintext = cipher.decrypt(context, message);

  database.updateMessageBody(masterSecret, messageId, plaintext.getMessageBody());

  if (message.isEndSession()) SecurityEvent.broadcastSecurityUpdateEvent(context, threadId);
}
 
Example #10
Source Project: Silence   Author: SilenceIM   File: SmsDecryptJob.java    License: GNU General Public License v3.0 5 votes vote down vote up
private void handleXmppExchangeMessage(MasterSecret masterSecret, long messageId, long threadId,
                                       IncomingXmppExchangeMessage message)
   throws NoSessionException, DuplicateMessageException, InvalidMessageException, LegacyMessageException
{
  EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
  database.markAsXmppExchange(messageId);
}
 
Example #11
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipher.java    License: GNU General Public License v3.0 5 votes vote down vote up
/**
 * Decrypt a SenderKey group message.
 *
 * @param senderKeyMessageBytes The received ciphertext.
 * @param callback   A callback that is triggered after decryption is complete,
 *                    but before the updated session state has been committed to the session
 *                    DB.  This allows some implementations to store the committed plaintext
 *                    to a DB first, in case they are concerned with a crash happening between
 *                    the time the session state is updated but before they're able to store
 *                    the plaintext to disk.
 * @return Plaintext
 * @throws LegacyMessageException
 * @throws InvalidMessageException
 * @throws DuplicateMessageException
 */
public byte[] decrypt(byte[] senderKeyMessageBytes, DecryptionCallback callback)
    throws LegacyMessageException, InvalidMessageException, DuplicateMessageException,
           NoSessionException
{
  synchronized (LOCK) {
    try {
      SenderKeyRecord record = senderKeyStore.loadSenderKey(senderKeyId);

      if (record.isEmpty()) {
        throw new NoSessionException("No sender key for: " + senderKeyId);
      }

      SenderKeyMessage senderKeyMessage = new SenderKeyMessage(senderKeyMessageBytes);
      SenderKeyState   senderKeyState   = record.getSenderKeyState(senderKeyMessage.getKeyId());

      senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());

      SenderMessageKey senderKey = getSenderKey(senderKeyState, senderKeyMessage.getIteration());

      byte[] plaintext = getPlainText(senderKey.getIv(), senderKey.getCipherKey(), senderKeyMessage.getCipherText());

      callback.handlePlaintext(plaintext);

      senderKeyStore.storeSenderKey(senderKeyId, record);

      return plaintext;
    } catch (org.whispersystems.libsignal.InvalidKeyException | InvalidKeyIdException e) {
      throw new InvalidMessageException(e);
    }
  }
}
 
Example #12
public SenderKeyDistributionMessage(byte[] serialized) throws LegacyMessageException, InvalidMessageException {
  try {
    byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1);
    byte     version      = messageParts[0][0];
    byte[]   message      = messageParts[1];

    if (ByteUtil.highBitsToInt(version) < CiphertextMessage.CURRENT_VERSION) {
      throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
    }

    if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
      throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
    }

    SignalProtos.SenderKeyDistributionMessage distributionMessage = SignalProtos.SenderKeyDistributionMessage.parseFrom(message);

    if (!distributionMessage.hasId()        ||
        !distributionMessage.hasIteration() ||
        !distributionMessage.hasChainKey()  ||
        !distributionMessage.hasSigningKey())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized   = serialized;
    this.id           = distributionMessage.getId();
    this.iteration    = distributionMessage.getIteration();
    this.chainKey     = distributionMessage.getChainKey().toByteArray();
    this.signatureKey = Curve.decodePoint(distributionMessage.getSigningKey().toByteArray(), 0);
  } catch (InvalidProtocolBufferException | InvalidKeyException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #13
Source Project: libsignal-protocol-java   Author: signalapp   File: PreKeySignalMessage.java    License: GNU General Public License v3.0 5 votes vote down vote up
public PreKeySignalMessage(byte[] serialized)
    throws InvalidMessageException, InvalidVersionException
{
  try {
    this.version = ByteUtil.highBitsToInt(serialized[0]);

    if (this.version > CiphertextMessage.CURRENT_VERSION) {
      throw new InvalidVersionException("Unknown version: " + this.version);
    }

    if (this.version < CiphertextMessage.CURRENT_VERSION) {
      throw new LegacyMessageException("Legacy version: " + this.version);
    }

    SignalProtos.PreKeySignalMessage preKeyWhisperMessage
        = SignalProtos.PreKeySignalMessage.parseFrom(ByteString.copyFrom(serialized, 1,
                                                                         serialized.length-1));

    if (!preKeyWhisperMessage.hasSignedPreKeyId()  ||
        !preKeyWhisperMessage.hasBaseKey()         ||
        !preKeyWhisperMessage.hasIdentityKey()     ||
        !preKeyWhisperMessage.hasMessage())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized     = serialized;
    this.registrationId = preKeyWhisperMessage.getRegistrationId();
    this.preKeyId       = preKeyWhisperMessage.hasPreKeyId() ? Optional.of(preKeyWhisperMessage.getPreKeyId()) : Optional.<Integer>absent();
    this.signedPreKeyId = preKeyWhisperMessage.hasSignedPreKeyId() ? preKeyWhisperMessage.getSignedPreKeyId() : -1;
    this.baseKey        = Curve.decodePoint(preKeyWhisperMessage.getBaseKey().toByteArray(), 0);
    this.identityKey    = new IdentityKey(Curve.decodePoint(preKeyWhisperMessage.getIdentityKey().toByteArray(), 0));
    this.message        = new SignalMessage(preKeyWhisperMessage.getMessage().toByteArray());
  } catch (InvalidProtocolBufferException | InvalidKeyException | LegacyMessageException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #14
Source Project: libsignal-protocol-java   Author: signalapp   File: SenderKeyMessage.java    License: GNU General Public License v3.0 5 votes vote down vote up
public SenderKeyMessage(byte[] serialized) throws InvalidMessageException, LegacyMessageException {
  try {
    byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1 - SIGNATURE_LENGTH, SIGNATURE_LENGTH);
    byte     version      = messageParts[0][0];
    byte[]   message      = messageParts[1];
    byte[]   signature    = messageParts[2];

    if (ByteUtil.highBitsToInt(version) < 3) {
      throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
    }

    if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
      throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
    }

    SignalProtos.SenderKeyMessage senderKeyMessage = SignalProtos.SenderKeyMessage.parseFrom(message);

    if (!senderKeyMessage.hasId() ||
        !senderKeyMessage.hasIteration() ||
        !senderKeyMessage.hasCiphertext())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized     = serialized;
    this.messageVersion = ByteUtil.highBitsToInt(version);
    this.keyId          = senderKeyMessage.getId();
    this.iteration      = senderKeyMessage.getIteration();
    this.ciphertext     = senderKeyMessage.getCiphertext().toByteArray();
  } catch (InvalidProtocolBufferException | ParseException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #15
Source Project: libsignal-protocol-java   Author: signalapp   File: SignalMessage.java    License: GNU General Public License v3.0 5 votes vote down vote up
public SignalMessage(byte[] serialized) throws InvalidMessageException, LegacyMessageException {
  try {
    byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1 - MAC_LENGTH, MAC_LENGTH);
    byte     version      = messageParts[0][0];
    byte[]   message      = messageParts[1];
    byte[]   mac          = messageParts[2];

    if (ByteUtil.highBitsToInt(version) < CURRENT_VERSION) {
      throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
    }

    if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
      throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
    }

    SignalProtos.SignalMessage whisperMessage = SignalProtos.SignalMessage.parseFrom(message);

    if (!whisperMessage.hasCiphertext() ||
        !whisperMessage.hasCounter() ||
        !whisperMessage.hasRatchetKey())
    {
      throw new InvalidMessageException("Incomplete message.");
    }

    this.serialized       = serialized;
    this.senderRatchetKey = Curve.decodePoint(whisperMessage.getRatchetKey().toByteArray(), 0);
    this.messageVersion   = ByteUtil.highBitsToInt(version);
    this.counter          = whisperMessage.getCounter();
    this.previousCounter  = whisperMessage.getPreviousCounter();
    this.ciphertext       = whisperMessage.getCiphertext().toByteArray();
  } catch (InvalidProtocolBufferException | InvalidKeyException | ParseException e) {
    throw new InvalidMessageException(e);
  }
}
 
Example #16
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipherTest.java    License: GNU General Public License v3.0 5 votes vote down vote up
public void testOutOfOrder()
    throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
  InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
  InMemorySenderKeyStore bobStore   = new InMemorySenderKeyStore();

  GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
  GroupSessionBuilder bobSessionBuilder   = new GroupSessionBuilder(bobStore);

  SenderKeyName aliceName = GROUP_SENDER;

  GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);
  GroupCipher bobGroupCipher   = new GroupCipher(bobStore, aliceName);

  SenderKeyDistributionMessage aliceDistributionMessage =
      aliceSessionBuilder.create(aliceName);

  bobSessionBuilder.process(aliceName, aliceDistributionMessage);

  ArrayList<byte[]> ciphertexts = new ArrayList<>(100);

  for (int i=0;i<100;i++) {
    ciphertexts.add(aliceGroupCipher.encrypt("up the punks".getBytes()));
  }

  while (ciphertexts.size() > 0) {
    int    index      = randomInt() % ciphertexts.size();
    byte[] ciphertext = ciphertexts.remove(index);
    byte[] plaintext  = bobGroupCipher.decrypt(ciphertext);

    assertTrue(new String(plaintext).equals("up the punks"));
  }
}
 
Example #17
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipherTest.java    License: GNU General Public License v3.0 5 votes vote down vote up
public void testTooFarInFuture() throws DuplicateMessageException, InvalidMessageException, LegacyMessageException, NoSessionException {
  InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
  InMemorySenderKeyStore bobStore   = new InMemorySenderKeyStore();

  GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
  GroupSessionBuilder bobSessionBuilder   = new GroupSessionBuilder(bobStore);

  SenderKeyName aliceName = GROUP_SENDER;

  GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);
  GroupCipher bobGroupCipher   = new GroupCipher(bobStore, aliceName);

  SenderKeyDistributionMessage aliceDistributionMessage = aliceSessionBuilder.create(aliceName);

  bobSessionBuilder.process(aliceName, aliceDistributionMessage);

  for (int i=0;i<2001;i++) {
    aliceGroupCipher.encrypt("up the punks".getBytes());
  }

  byte[] tooFarCiphertext = aliceGroupCipher.encrypt("notta gonna worka".getBytes());
  try {
    bobGroupCipher.decrypt(tooFarCiphertext);
    throw new AssertionError("Should have failed!");
  } catch (InvalidMessageException e) {
    // good
  }
}
 
Example #18
Source Project: Silence   Author: SilenceIM   File: MmsDownloadJob.java    License: GNU General Public License v3.0 4 votes vote down vote up
private void storeRetrievedMms(MasterSecret masterSecret, String contentLocation,
                               long messageId, long threadId, EncodedStringValue pduFrom, 
                               EncodedStringValue[] pduTo, EncodedStringValue[] pduCc, PduBody pduBody,
                               long date, boolean isSecure, int subscriptionId)
    throws MmsException, NoSessionException, DuplicateMessageException, InvalidMessageException,
           LegacyMessageException
{
  MmsDatabase           database    = DatabaseFactory.getMmsDatabase(context);
  SingleUseBlobProvider provider    = SingleUseBlobProvider.getInstance();
  String                from        = null;
  List<String>          to          = new LinkedList<>();
  List<String>          cc          = new LinkedList<>();
  String                body        = null;
  List<Attachment>      attachments = new LinkedList<>();

  if (pduFrom != null) {
    from = Util.toIsoString(pduFrom.getTextString());
  }

  if (pduTo != null) {
    for (EncodedStringValue toValue : pduTo) {
      to.add(Util.toIsoString(toValue.getTextString()));
    }
  }

  if (pduCc != null) {
    for (EncodedStringValue ccValue : pduCc) {
      cc.add(Util.toIsoString(ccValue.getTextString()));
    }
  }

  if (pduBody != null) {
    body = PartParser.getMessageText(pduBody);
    PduBody media = PartParser.getSupportedMediaParts(pduBody);

    for (int i=0;i<media.getPartsNum();i++) {
      PduPart part = media.getPart(i);

      if (part.getData() != null) {
        byte[]  decodedDigest = null;

        if (isSecure) {
          PduPart digestPart  = pduBody.getPartByName(Util.toIsoString(part.getName()) + ".digest");
          byte[]  digestBytes = null;

          if (digestPart != null) {
            digestBytes = digestPart.getData();
          }

          if (digestBytes != null) {
            decodedDigest = Base64.decode(digestBytes, Base64.NO_WRAP);
          }

          if (decodedDigest != null) {
            Log.w(TAG, "Available digest for part name " + Util.toIsoString(part.getName()) + " (content id " + Util.toIsoString(part.getContentId()) + "): " + Hex.toString(decodedDigest));
          } else {
            Log.w(TAG, "No available digest for part name " + Util.toIsoString(part.getName()) + " (content id " + Util.toIsoString(part.getContentId()) + ")");
          }
        }

        Uri uri = provider.createUri(part.getData());
        attachments.add(new UriAttachment(uri, Util.toIsoString(part.getContentType()),
                                          AttachmentDatabase.TRANSFER_PROGRESS_DONE,
                                          part.getData().length, decodedDigest));
      }
    }
  }

  IncomingMediaMessage message = new IncomingMediaMessage(from, to, cc, body, date * 1000L, attachments, subscriptionId);

  Pair<Long, Long> messageAndThreadId;

  if (isSecure) {
    messageAndThreadId = database.insertSecureDecryptedMessageInbox(masterSecret, message,
                                                                    threadId);
  } else {
    messageAndThreadId = database.insertMessageInbox(masterSecret, message,
                                                     contentLocation, threadId);
  }

  database.delete(messageId);
  MessageNotifier.updateNotification(context, masterSecret, message.getSubscriptionId());
}
 
Example #19
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipherTest.java    License: GNU General Public License v3.0 4 votes vote down vote up
public void testBasicRatchet()
    throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
  InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
  InMemorySenderKeyStore bobStore   = new InMemorySenderKeyStore();

  GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
  GroupSessionBuilder bobSessionBuilder   = new GroupSessionBuilder(bobStore);

  SenderKeyName aliceName = GROUP_SENDER;

  GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);
  GroupCipher bobGroupCipher   = new GroupCipher(bobStore, aliceName);

  SenderKeyDistributionMessage sentAliceDistributionMessage =
      aliceSessionBuilder.create(aliceName);
  SenderKeyDistributionMessage receivedAliceDistributionMessage =
      new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());

  bobSessionBuilder.process(aliceName, receivedAliceDistributionMessage);

  byte[] ciphertextFromAlice  = aliceGroupCipher.encrypt("smert ze smert".getBytes());
  byte[] ciphertextFromAlice2 = aliceGroupCipher.encrypt("smert ze smert2".getBytes());
  byte[] ciphertextFromAlice3 = aliceGroupCipher.encrypt("smert ze smert3".getBytes());

  byte[] plaintextFromAlice   = bobGroupCipher.decrypt(ciphertextFromAlice);

  try {
    bobGroupCipher.decrypt(ciphertextFromAlice);
    throw new AssertionError("Should have ratcheted forward!");
  } catch (DuplicateMessageException dme) {
    // good
  }

  byte[] plaintextFromAlice2  = bobGroupCipher.decrypt(ciphertextFromAlice2);
  byte[] plaintextFromAlice3  = bobGroupCipher.decrypt(ciphertextFromAlice3);

  assertTrue(new String(plaintextFromAlice).equals("smert ze smert"));
  assertTrue(new String(plaintextFromAlice2).equals("smert ze smert2"));
  assertTrue(new String(plaintextFromAlice3).equals("smert ze smert3"));
}
 
Example #20
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipherTest.java    License: GNU General Public License v3.0 3 votes vote down vote up
public void testLateJoin() throws NoSessionException, InvalidMessageException, LegacyMessageException, DuplicateMessageException {
  InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
  InMemorySenderKeyStore bobStore   = new InMemorySenderKeyStore();

  GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);


  SenderKeyName aliceName = GROUP_SENDER;

  GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);


  SenderKeyDistributionMessage aliceDistributionMessage = aliceSessionBuilder.create(aliceName);
  // Send off to some people.

  for (int i=0;i<100;i++) {
    aliceGroupCipher.encrypt("up the punks up the punks up the punks".getBytes());
  }

  // Now Bob Joins.
  GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
  GroupCipher         bobGroupCipher    = new GroupCipher(bobStore, aliceName);


  SenderKeyDistributionMessage distributionMessageToBob = aliceSessionBuilder.create(aliceName);
  bobSessionBuilder.process(aliceName, new SenderKeyDistributionMessage(distributionMessageToBob.serialize()));

  byte[] ciphertext = aliceGroupCipher.encrypt("welcome to the group".getBytes());
  byte[] plaintext  = bobGroupCipher.decrypt(ciphertext);

  assertEquals(new String(plaintext), "welcome to the group");
}
 
Example #21
Source Project: libsignal-protocol-java   Author: signalapp   File: GroupCipher.java    License: GNU General Public License v3.0 2 votes vote down vote up
/**
 * Decrypt a SenderKey group message.
 *
 * @param senderKeyMessageBytes The received ciphertext.
 * @return Plaintext
 * @throws LegacyMessageException
 * @throws InvalidMessageException
 * @throws DuplicateMessageException
 */
public byte[] decrypt(byte[] senderKeyMessageBytes)
    throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
  return decrypt(senderKeyMessageBytes, new NullDecryptionCallback());
}