Java源码示例:org.whispersystems.libsignal.LegacyMessageException

示例1
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);
  }
}
 
示例2
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);
  }
}
 
示例3
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);
  }
}
 
示例4
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
    }
  }
 
示例5
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"));
}
 
示例6
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));
}
 
示例7
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);
}
 
示例8
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);
  }
}
 
示例9
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);
}
 
示例10
private void handleXmppExchangeMessage(MasterSecret masterSecret, long messageId, long threadId,
                                       IncomingXmppExchangeMessage message)
   throws NoSessionException, DuplicateMessageException, InvalidMessageException, LegacyMessageException
{
  EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
  database.markAsXmppExchange(messageId);
}
 
示例11
/**
 * 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);
    }
  }
}
 
示例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);
  }
}
 
示例13
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);
  }
}
 
示例14
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);
  }
}
 
示例15
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);
  }
}
 
示例16
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"));
  }
}
 
示例17
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
  }
}
 
示例18
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());
}
 
示例19
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"));
}
 
示例20
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");
}
 
示例21
/**
 * 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());
}