diff options
Diffstat (limited to 'src/main/java/org/whispersystems/libaxolotl/groups')
7 files changed, 0 insertions, 485 deletions
diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/GroupCipher.java b/src/main/java/org/whispersystems/libaxolotl/groups/GroupCipher.java deleted file mode 100644 index 43dac752..00000000 --- a/src/main/java/org/whispersystems/libaxolotl/groups/GroupCipher.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.whispersystems.libaxolotl.groups; - -import org.whispersystems.libaxolotl.DuplicateMessageException; -import org.whispersystems.libaxolotl.InvalidKeyIdException; -import org.whispersystems.libaxolotl.InvalidMessageException; -import org.whispersystems.libaxolotl.LegacyMessageException; -import org.whispersystems.libaxolotl.NoSessionException; -import org.whispersystems.libaxolotl.groups.ratchet.SenderChainKey; -import org.whispersystems.libaxolotl.groups.ratchet.SenderMessageKey; -import org.whispersystems.libaxolotl.groups.state.SenderKeyRecord; -import org.whispersystems.libaxolotl.groups.state.SenderKeyState; -import org.whispersystems.libaxolotl.groups.state.SenderKeyStore; -import org.whispersystems.libaxolotl.protocol.SenderKeyMessage; - -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -public class GroupCipher { - - static final Object LOCK = new Object(); - - private final SenderKeyStore senderKeyStore; - private final String senderKeyId; - - public GroupCipher(SenderKeyStore senderKeyStore, String senderKeyId) { - this.senderKeyStore = senderKeyStore; - this.senderKeyId = senderKeyId; - } - - public byte[] encrypt(byte[] paddedPlaintext) throws NoSessionException { - synchronized (LOCK) { - try { - SenderKeyRecord record = senderKeyStore.loadSenderKey(senderKeyId); - SenderKeyState senderKeyState = record.getSenderKeyState(); - SenderMessageKey senderKey = senderKeyState.getSenderChainKey().getSenderMessageKey(); - byte[] ciphertext = getCipherText(senderKey.getIv(), senderKey.getCipherKey(), paddedPlaintext); - - SenderKeyMessage senderKeyMessage = new SenderKeyMessage(senderKeyState.getKeyId(), - senderKey.getIteration(), - ciphertext, - senderKeyState.getSigningKeyPrivate()); - - senderKeyState.setSenderChainKey(senderKeyState.getSenderChainKey().getNext()); - - senderKeyStore.storeSenderKey(senderKeyId, record); - - return senderKeyMessage.serialize(); - } catch (InvalidKeyIdException e) { - throw new NoSessionException(e); - } - } - } - - public byte[] decrypt(byte[] senderKeyMessageBytes) - throws LegacyMessageException, InvalidMessageException, DuplicateMessageException - { - synchronized (LOCK) { - try { - SenderKeyRecord record = senderKeyStore.loadSenderKey(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()); - - senderKeyStore.storeSenderKey(senderKeyId, record); - - return plaintext; - } catch (org.whispersystems.libaxolotl.InvalidKeyException | InvalidKeyIdException e) { - throw new InvalidMessageException(e); - } - } - } - - private SenderMessageKey getSenderKey(SenderKeyState senderKeyState, int iteration) - throws DuplicateMessageException, InvalidMessageException - { - SenderChainKey senderChainKey = senderKeyState.getSenderChainKey(); - - if (senderChainKey.getIteration() > iteration) { - if (senderKeyState.hasSenderMessageKey(iteration)) { - return senderKeyState.removeSenderMessageKey(iteration); - } else { - throw new DuplicateMessageException("Received message with old counter: " + - senderChainKey.getIteration() + " , " + iteration); - } - } - - if (senderChainKey.getIteration() - iteration > 2000) { - throw new InvalidMessageException("Over 2000 messages into the future!"); - } - - while (senderChainKey.getIteration() < iteration) { - senderKeyState.addSenderMessageKey(senderChainKey.getSenderMessageKey()); - senderChainKey = senderChainKey.getNext(); - } - - senderKeyState.setSenderChainKey(senderChainKey.getNext()); - return senderChainKey.getSenderMessageKey(); - } - - private byte[] getPlainText(byte[] iv, byte[] key, byte[] ciphertext) - throws InvalidMessageException - { - try { - IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - - cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), ivParameterSpec); - - return cipher.doFinal(ciphertext); - } catch (NoSuchAlgorithmException | NoSuchPaddingException | java.security.InvalidKeyException | - InvalidAlgorithmParameterException e) - { - throw new AssertionError(e); - } catch (IllegalBlockSizeException | BadPaddingException e) { - throw new InvalidMessageException(e); - } - } - - private byte[] getCipherText(byte[] iv, byte[] key, byte[] plaintext) { - try { - IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - - cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), ivParameterSpec); - - return cipher.doFinal(plaintext); - } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | - IllegalBlockSizeException | BadPaddingException | java.security.InvalidKeyException e) - { - throw new AssertionError(e); - } - } - -} diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/GroupSessionBuilder.java b/src/main/java/org/whispersystems/libaxolotl/groups/GroupSessionBuilder.java deleted file mode 100644 index 8b73484b..00000000 --- a/src/main/java/org/whispersystems/libaxolotl/groups/GroupSessionBuilder.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.whispersystems.libaxolotl.groups; - -import org.whispersystems.libaxolotl.ecc.ECKeyPair; -import org.whispersystems.libaxolotl.groups.state.SenderKeyRecord; -import org.whispersystems.libaxolotl.groups.state.SenderKeyStore; -import org.whispersystems.libaxolotl.protocol.SenderKeyDistributionMessage; - -public class GroupSessionBuilder { - - private final SenderKeyStore senderKeyStore; - - public GroupSessionBuilder(SenderKeyStore senderKeyStore) { - this.senderKeyStore = senderKeyStore; - } - - public void process(String sender, SenderKeyDistributionMessage senderKeyDistributionMessage) { - synchronized (GroupCipher.LOCK) { - SenderKeyRecord senderKeyRecord = senderKeyStore.loadSenderKey(sender); - senderKeyRecord.addSenderKeyState(senderKeyDistributionMessage.getId(), - senderKeyDistributionMessage.getIteration(), - senderKeyDistributionMessage.getChainKey(), - senderKeyDistributionMessage.getSignatureKey()); - senderKeyStore.storeSenderKey(sender, senderKeyRecord); - } - } - - public SenderKeyDistributionMessage process(String groupId, int keyId, int iteration, - byte[] chainKey, ECKeyPair signatureKey) - { - synchronized (GroupCipher.LOCK) { - SenderKeyRecord senderKeyRecord = senderKeyStore.loadSenderKey(groupId); - senderKeyRecord.setSenderKeyState(keyId, iteration, chainKey, signatureKey); - senderKeyStore.storeSenderKey(groupId, senderKeyRecord); - - return new SenderKeyDistributionMessage(keyId, iteration, chainKey, signatureKey.getPublicKey()); - } - } -} diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java b/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java deleted file mode 100644 index 71375923..00000000 --- a/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.whispersystems.libaxolotl.groups.ratchet; - -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -public class SenderChainKey { - - private static final byte[] MESSAGE_KEY_SEED = {0x01}; - private static final byte[] CHAIN_KEY_SEED = {0x02}; - - private final int iteration; - private final byte[] chainKey; - - public SenderChainKey(int iteration, byte[] chainKey) { - this.iteration = iteration; - this.chainKey = chainKey; - } - - public int getIteration() { - return iteration; - } - - public SenderMessageKey getSenderMessageKey() { - return new SenderMessageKey(iteration, getDerivative(MESSAGE_KEY_SEED, chainKey)); - } - - public SenderChainKey getNext() { - return new SenderChainKey(iteration + 1, getDerivative(CHAIN_KEY_SEED, chainKey)); - } - - public byte[] getSeed() { - return chainKey; - } - - private byte[] getDerivative(byte[] seed, byte[] key) { - try { - Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(new SecretKeySpec(key, "HmacSHA256")); - - return mac.doFinal(seed); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new AssertionError(e); - } - } - -} diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderMessageKey.java b/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderMessageKey.java deleted file mode 100644 index 8808a8e8..00000000 --- a/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderMessageKey.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.whispersystems.libaxolotl.groups.ratchet; - -import org.whispersystems.libaxolotl.kdf.HKDFv3; -import org.whispersystems.libaxolotl.util.ByteUtil; - -public class SenderMessageKey { - - private final int iteration; - private final byte[] iv; - private final byte[] cipherKey; - private final byte[] seed; - - public SenderMessageKey(int iteration, byte[] seed) { - byte[] derivative = new HKDFv3().deriveSecrets(seed, "WhisperGroup".getBytes(), 48); - byte[][] parts = ByteUtil.split(derivative, 16, 32); - - this.iteration = iteration; - this.seed = seed; - this.iv = parts[0]; - this.cipherKey = parts[1]; - } - - public int getIteration() { - return iteration; - } - - public byte[] getIv() { - return iv; - } - - public byte[] getCipherKey() { - return cipherKey; - } - - public byte[] getSeed() { - return seed; - } -} diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyRecord.java b/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyRecord.java deleted file mode 100644 index bb1ba952..00000000 --- a/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyRecord.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.whispersystems.libaxolotl.groups.state; - -import org.whispersystems.libaxolotl.InvalidKeyIdException; -import org.whispersystems.libaxolotl.ecc.ECKeyPair; -import org.whispersystems.libaxolotl.ecc.ECPublicKey; -import org.whispersystems.libaxolotl.state.StorageProtos; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -import static org.whispersystems.libaxolotl.state.StorageProtos.SenderKeyRecordStructure; - -public class SenderKeyRecord { - - private List<SenderKeyState> senderKeyStates = new LinkedList<>(); - - public SenderKeyRecord() {} - - public SenderKeyRecord(byte[] serialized) throws IOException { - SenderKeyRecordStructure senderKeyRecordStructure = SenderKeyRecordStructure.parseFrom(serialized); - - for (StorageProtos.SenderKeyStateStructure structure : senderKeyRecordStructure.getSenderKeyStatesList()) { - this.senderKeyStates.add(new SenderKeyState(structure)); - } - } - - public SenderKeyState getSenderKeyState() throws InvalidKeyIdException { - if (!senderKeyStates.isEmpty()) { - return senderKeyStates.get(0); - } else { - throw new InvalidKeyIdException("No key state in record!"); - } - } - - public SenderKeyState getSenderKeyState(int keyId) throws InvalidKeyIdException { - for (SenderKeyState state : senderKeyStates) { - if (state.getKeyId() == keyId) { - return state; - } - } - - throw new InvalidKeyIdException("No keys for: " + keyId); - } - - public void addSenderKeyState(int id, int iteration, byte[] chainKey, ECPublicKey signatureKey) { - senderKeyStates.add(new SenderKeyState(id, iteration, chainKey, signatureKey)); - } - - public void setSenderKeyState(int id, int iteration, byte[] chainKey, ECKeyPair signatureKey) { - senderKeyStates.clear(); - senderKeyStates.add(new SenderKeyState(id, iteration, chainKey, signatureKey)); - } - - public byte[] serialize() { - SenderKeyRecordStructure.Builder recordStructure = SenderKeyRecordStructure.newBuilder(); - - for (SenderKeyState senderKeyState : senderKeyStates) { - recordStructure.addSenderKeyStates(senderKeyState.getStructure()); - } - - return recordStructure.build().toByteArray(); - } -} diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyState.java b/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyState.java deleted file mode 100644 index 80498ce0..00000000 --- a/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyState.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.whispersystems.libaxolotl.groups.state; - -import com.google.protobuf.ByteString; - -import org.whispersystems.libaxolotl.InvalidKeyException; -import org.whispersystems.libaxolotl.ecc.Curve; -import org.whispersystems.libaxolotl.ecc.ECKeyPair; -import org.whispersystems.libaxolotl.ecc.ECPrivateKey; -import org.whispersystems.libaxolotl.ecc.ECPublicKey; -import org.whispersystems.libaxolotl.groups.ratchet.SenderChainKey; -import org.whispersystems.libaxolotl.groups.ratchet.SenderMessageKey; -import org.whispersystems.libaxolotl.util.guava.Optional; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import static org.whispersystems.libaxolotl.state.StorageProtos.SenderKeyStateStructure; - -public class SenderKeyState { - - private SenderKeyStateStructure senderKeyStateStructure; - - public SenderKeyState(int id, int iteration, byte[] chainKey, ECPublicKey signatureKey) { - this(id, iteration, chainKey, signatureKey, Optional.<ECPrivateKey>absent()); - } - - public SenderKeyState(int id, int iteration, byte[] chainKey, ECKeyPair signatureKey) { - this(id, iteration, chainKey, signatureKey.getPublicKey(), Optional.of(signatureKey.getPrivateKey())); - } - - private SenderKeyState(int id, int iteration, byte[] chainKey, - ECPublicKey signatureKeyPublic, - Optional<ECPrivateKey> signatureKeyPrivate) - { - SenderKeyStateStructure.SenderChainKey senderChainKeyStructure = - SenderKeyStateStructure.SenderChainKey.newBuilder() - .setIteration(iteration) - .setSeed(ByteString.copyFrom(chainKey)) - .build(); - - SenderKeyStateStructure.SenderSigningKey.Builder signingKeyStructure = - SenderKeyStateStructure.SenderSigningKey.newBuilder() - .setPublic(ByteString.copyFrom(signatureKeyPublic.serialize())); - - if (signatureKeyPrivate.isPresent()) { - signingKeyStructure.setPrivate(ByteString.copyFrom(signatureKeyPrivate.get().serialize())); - } - - this.senderKeyStateStructure = SenderKeyStateStructure.newBuilder() - .setSenderKeyId(id) - .setSenderChainKey(senderChainKeyStructure) - .setSenderSigningKey(signingKeyStructure) - .build(); - } - - public SenderKeyState(SenderKeyStateStructure senderKeyStateStructure) { - this.senderKeyStateStructure = senderKeyStateStructure; - } - - public int getKeyId() { - return senderKeyStateStructure.getSenderKeyId(); - } - - public SenderChainKey getSenderChainKey() { - return new SenderChainKey(senderKeyStateStructure.getSenderChainKey().getIteration(), - senderKeyStateStructure.getSenderChainKey().getSeed().toByteArray()); - } - - public void setSenderChainKey(SenderChainKey chainKey) { - SenderKeyStateStructure.SenderChainKey senderChainKeyStructure = - SenderKeyStateStructure.SenderChainKey.newBuilder() - .setIteration(chainKey.getIteration()) - .setSeed(ByteString.copyFrom(chainKey.getSeed())) - .build(); - - this.senderKeyStateStructure = senderKeyStateStructure.toBuilder() - .setSenderChainKey(senderChainKeyStructure) - .build(); - } - - public ECPublicKey getSigningKeyPublic() throws InvalidKeyException { - return Curve.decodePoint(senderKeyStateStructure.getSenderSigningKey() - .getPublic() - .toByteArray(), 0); - } - - public ECPrivateKey getSigningKeyPrivate() { - return Curve.decodePrivatePoint(senderKeyStateStructure.getSenderSigningKey() - .getPrivate().toByteArray()); - } - - public boolean hasSenderMessageKey(int iteration) { - for (SenderKeyStateStructure.SenderMessageKey senderMessageKey : senderKeyStateStructure.getSenderMessageKeysList()) { - if (senderMessageKey.getIteration() == iteration) return true; - } - - return false; - } - - public void addSenderMessageKey(SenderMessageKey senderMessageKey) { - SenderKeyStateStructure.SenderMessageKey senderMessageKeyStructure = - SenderKeyStateStructure.SenderMessageKey.newBuilder() - .setIteration(senderMessageKey.getIteration()) - .setSeed(ByteString.copyFrom(senderMessageKey.getSeed())) - .build(); - - this.senderKeyStateStructure = this.senderKeyStateStructure.toBuilder() - .addSenderMessageKeys(senderMessageKeyStructure) - .build(); - } - - public SenderMessageKey removeSenderMessageKey(int iteration) { - List<SenderKeyStateStructure.SenderMessageKey> keys = new LinkedList<>(senderKeyStateStructure.getSenderMessageKeysList()); - Iterator<SenderKeyStateStructure.SenderMessageKey> iterator = keys.iterator(); - - SenderKeyStateStructure.SenderMessageKey result = null; - - while (iterator.hasNext()) { - SenderKeyStateStructure.SenderMessageKey senderMessageKey = iterator.next(); - - if (senderMessageKey.getIteration() == iteration) { - result = senderMessageKey; - iterator.remove(); - break; - } - } - - this.senderKeyStateStructure = this.senderKeyStateStructure.toBuilder() - .clearSenderMessageKeys() - .addAllSenderMessageKeys(keys) - .build(); - - if (result != null) { - return new SenderMessageKey(result.getIteration(), result.getSeed().toByteArray()); - } else { - return null; - } - } - - public SenderKeyStateStructure getStructure() { - return senderKeyStateStructure; - } -} diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyStore.java b/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyStore.java deleted file mode 100644 index da01b1f3..00000000 --- a/src/main/java/org/whispersystems/libaxolotl/groups/state/SenderKeyStore.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.whispersystems.libaxolotl.groups.state; - -public interface SenderKeyStore { - public void storeSenderKey(String senderKeyId, SenderKeyRecord record); - public SenderKeyRecord loadSenderKey(String senderKeyId); -} |