Add decryption callback to group decrypt operations.

This commit is contained in:
Moxie Marlinspike 2015-04-06 12:21:54 -07:00
parent 0c98e9f80e
commit 3d9c944288
4 changed files with 35 additions and 5 deletions

View File

@ -0,0 +1,5 @@
package org.whispersystems.libaxolotl;
public interface DecryptionCallback {
public void handlePlaintext(byte[] plaintext);
}

View File

@ -455,10 +455,6 @@ public class SessionCipher {
}
}
public static interface DecryptionCallback {
public void handlePlaintext(byte[] plaintext);
}
private static class NullDecryptionCallback implements DecryptionCallback {
@Override
public void handlePlaintext(byte[] plaintext) {}

View File

@ -16,6 +16,7 @@
*/
package org.whispersystems.libaxolotl.groups;
import org.whispersystems.libaxolotl.DecryptionCallback;
import org.whispersystems.libaxolotl.DuplicateMessageException;
import org.whispersystems.libaxolotl.InvalidKeyIdException;
import org.whispersystems.libaxolotl.InvalidMessageException;
@ -101,6 +102,27 @@ public class GroupCipher {
* @throws DuplicateMessageException
*/
public byte[] decrypt(byte[] senderKeyMessageBytes)
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException
{
return decrypt(senderKeyMessageBytes, new NullDecryptionCallback());
}
/**
* 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
{
synchronized (LOCK) {
@ -115,6 +137,8 @@ public class GroupCipher {
byte[] plaintext = getPlainText(senderKey.getIv(), senderKey.getCipherKey(), senderKeyMessage.getCipherText());
callback.handlePlaintext(plaintext);
senderKeyStore.storeSenderKey(senderKeyId, record);
return plaintext;
@ -185,4 +209,9 @@ public class GroupCipher {
}
}
private static class NullDecryptionCallback implements DecryptionCallback {
@Override
public void handlePlaintext(byte[] plaintext) {}
}
}

View File

@ -135,7 +135,7 @@ public class SessionBuilderTest extends TestCase {
bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);
byte[] plaintext = bobSessionCipher.decrypt(incomingMessage, new SessionCipher.DecryptionCallback() {
byte[] plaintext = bobSessionCipher.decrypt(incomingMessage, new DecryptionCallback() {
@Override
public void handlePlaintext(byte[] plaintext) {
assertTrue(originalMessage.equals(new String(plaintext)));