diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/src/main/java/org/whispersystems/libaxolotl/protocol/SenderKeyDistributionMessage.java | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/java/src/main/java/org/whispersystems/libaxolotl/protocol/SenderKeyDistributionMessage.java b/java/src/main/java/org/whispersystems/libaxolotl/protocol/SenderKeyDistributionMessage.java index 424dd87c..35f9e218 100644 --- a/java/src/main/java/org/whispersystems/libaxolotl/protocol/SenderKeyDistributionMessage.java +++ b/java/src/main/java/org/whispersystems/libaxolotl/protocol/SenderKeyDistributionMessage.java @@ -1,7 +1,12 @@ package org.whispersystems.libaxolotl.protocol; import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import org.whispersystems.libaxolotl.InvalidKeyException; +import org.whispersystems.libaxolotl.InvalidMessageException; +import org.whispersystems.libaxolotl.LegacyMessageException; +import org.whispersystems.libaxolotl.ecc.Curve; import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.util.ByteUtil; @@ -15,17 +20,52 @@ public class SenderKeyDistributionMessage implements CiphertextMessage { public SenderKeyDistributionMessage(int id, int iteration, byte[] chainKey, ECPublicKey signatureKey) { byte[] version = {ByteUtil.intsToByteHighAndLow(CURRENT_VERSION, CURRENT_VERSION)}; + byte[] protobuf = WhisperProtos.SenderKeyDistributionMessage.newBuilder() + .setId(id) + .setIteration(iteration) + .setChainKey(ByteString.copyFrom(chainKey)) + .setSigningKey(ByteString.copyFrom(signatureKey.serialize())) + .build().toByteArray(); this.id = id; this.iteration = iteration; this.chainKey = chainKey; this.signatureKey = signatureKey; - this.serialized = WhisperProtos.SenderKeyDistributionMessage.newBuilder() - .setId(id) - .setIteration(iteration) - .setChainKey(ByteString.copyFrom(chainKey)) - .setSigningKey(ByteString.copyFrom(signatureKey.serialize())) - .build().toByteArray(); + this.serialized = ByteUtil.combine(version, protobuf); + } + + 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)); + } + + WhisperProtos.SenderKeyDistributionMessage distributionMessage = WhisperProtos.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); + } } @Override |