Skip to content
This repository was archived by the owner on Feb 12, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import org.whispersystems.libsignal.DecryptionCallback;
import org.whispersystems.libsignal.DuplicateMessageException;
import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.InvalidKeyIdException;
import org.whispersystems.libsignal.InvalidMessageException;
import org.whispersystems.libsignal.LegacyMessageException;
import org.whispersystems.libsignal.NoSessionException;
import org.whispersystems.libsignal.ecc.ECPrivateKey;
import org.whispersystems.libsignal.groups.ratchet.SenderChainKey;
import org.whispersystems.libsignal.groups.ratchet.SenderMessageKey;
import org.whispersystems.libsignal.groups.state.SenderKeyRecord;
Expand Down Expand Up @@ -56,19 +58,25 @@ public GroupCipher(SenderKeyStore senderKeyStore, SenderKeyName senderKeyId) {
* @param paddedPlaintext The plaintext message bytes, optionally padded.
* @return Ciphertext.
* @throws NoSessionException
* @throws InvalidKeyException
*/
public byte[] encrypt(byte[] paddedPlaintext) throws NoSessionException {
public byte[] encrypt(byte[] paddedPlaintext) throws NoSessionException, InvalidKeyException {
synchronized (LOCK) {
try {
SenderKeyRecord record = senderKeyStore.loadSenderKey(senderKeyId);
SenderKeyState senderKeyState = record.getSenderKeyState();
SenderMessageKey senderKey = senderKeyState.getSenderChainKey().getSenderMessageKey();
ECPrivateKey signatureKey = senderKeyState.getSigningKeyPrivate();
byte[] ciphertext = getCipherText(senderKey.getIv(), senderKey.getCipherKey(), paddedPlaintext);

if (signatureKey == null) {
throw new InvalidKeyException("Session missing signature key!");
}

SenderKeyMessage senderKeyMessage = new SenderKeyMessage(senderKeyState.getKeyId(),
senderKey.getIteration(),
ciphertext,
senderKeyState.getSigningKeyPrivate());
signatureKey);

senderKeyState.setSenderChainKey(senderKeyState.getSenderChainKey().getNext());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,13 @@ public ECPublicKey getSigningKeyPublic() throws InvalidKeyException {
}

public ECPrivateKey getSigningKeyPrivate() {
return Curve.decodePrivatePoint(senderKeyStateStructure.getSenderSigningKey()
.getPrivate().toByteArray());
if (senderKeyStateStructure.hasSenderSigningKey() &&
senderKeyStateStructure.getSenderSigningKey().hasPrivate()) {
return Curve.decodePrivatePoint(senderKeyStateStructure.getSenderSigningKey()
.getPrivate().toByteArray());
} else {
return null;
}
}

public boolean hasSenderMessageKey(int iteration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import junit.framework.TestCase;

import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.DuplicateMessageException;
import org.whispersystems.libsignal.InvalidMessageException;
Expand All @@ -22,7 +23,7 @@ public class GroupCipherTest extends TestCase {
private static final SignalProtocolAddress SENDER_ADDRESS = new SignalProtocolAddress("+14150001111", 1);
private static final SenderKeyName GROUP_SENDER = new SenderKeyName("nihilist history reading group", SENDER_ADDRESS);

public void testNoSession() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException {
public void testNoSession() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException, InvalidKeyException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();

Expand All @@ -47,7 +48,7 @@ public void testNoSession() throws InvalidMessageException, LegacyMessageExcepti
}

public void testBasicEncryptDecrypt()
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException, InvalidKeyException
{
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
Expand All @@ -68,7 +69,7 @@ public void testBasicEncryptDecrypt()
assertTrue(new String(plaintextFromAlice).equals("smert ze smert"));
}

public void testLargeMessages() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException {
public void testLargeMessages() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException, InvalidKeyException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();

Expand All @@ -92,7 +93,7 @@ public void testLargeMessages() throws InvalidMessageException, LegacyMessageExc
}

public void testBasicRatchet()
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException, InvalidKeyException
{
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
Expand Down Expand Up @@ -133,7 +134,7 @@ public void testBasicRatchet()
assertTrue(new String(plaintextFromAlice3).equals("smert ze smert3"));
}

public void testLateJoin() throws NoSessionException, InvalidMessageException, LegacyMessageException, DuplicateMessageException {
public void testLateJoin() throws NoSessionException, InvalidMessageException, LegacyMessageException, DuplicateMessageException, InvalidKeyException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();

Expand Down Expand Up @@ -168,7 +169,7 @@ public void testLateJoin() throws NoSessionException, InvalidMessageException, L


public void testOutOfOrder()
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException, InvalidKeyException
{
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
Expand Down Expand Up @@ -201,7 +202,7 @@ public void testOutOfOrder()
}
}

public void testEncryptNoSession() {
public void testEncryptNoSession() throws InvalidKeyException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, new SenderKeyName("coolio groupio", new SignalProtocolAddress("+10002223333", 1)));
try {
Expand All @@ -213,7 +214,7 @@ public void testEncryptNoSession() {
}


public void testTooFarInFuture() throws DuplicateMessageException, InvalidMessageException, LegacyMessageException, NoSessionException {
public void testTooFarInFuture() throws DuplicateMessageException, InvalidMessageException, LegacyMessageException, NoSessionException, InvalidKeyException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();

Expand Down Expand Up @@ -275,6 +276,27 @@ public void testMessageKeyLimit() throws Exception {
}
}

public void testInvalidSignatureKey()
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();

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

GroupCipher bobGroupCipher = new GroupCipher(bobStore, GROUP_SENDER);

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

try {
bobGroupCipher.encrypt("smert ze smert".getBytes());
} catch (InvalidKeyException e) {
// good
}
}

private int randomInt() {
try {
Expand Down