From 5ea3b3038e7f07c2efc72f28ddaafde3641d1e4a Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Wed, 23 Jul 2014 21:46:19 -0700 Subject: [PATCH] Remove verification tag. 1) Remove verification tag from PreKeyWhisperMessage. 2) Include sender and recipient identity keys in the MAC of each WhisperMessage. --- .../protobuf/LocalStorageProtocol.proto | 1 - libaxolotl/protobuf/WhisperTextProtocol.proto | 1 - .../test/SessionBuilderTest.java | 76 --------- .../test/ratchet/VerifyKeyTest.java | 90 ----------- .../libaxolotl/SessionBuilder.java | 6 - .../libaxolotl/SessionCipher.java | 10 +- .../protocol/PreKeyWhisperMessage.java | 12 +- .../libaxolotl/protocol/WhisperMessage.java | 25 ++- .../libaxolotl/protocol/WhisperProtos.java | 149 ++---------------- .../libaxolotl/ratchet/RatchetingSession.java | 60 +------ .../libaxolotl/ratchet/VerifyKey.java | 53 ------- .../libaxolotl/state/SessionState.java | 10 -- .../libaxolotl/state/StorageProtos.java | 143 ++++------------- 13 files changed, 80 insertions(+), 556 deletions(-) delete mode 100644 libaxolotl/src/androidTest/java/org/whispersystems/test/ratchet/VerifyKeyTest.java delete mode 100644 libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/VerifyKey.java diff --git a/libaxolotl/protobuf/LocalStorageProtocol.proto b/libaxolotl/protobuf/LocalStorageProtocol.proto index 6b4d6104f1..93badb59e3 100644 --- a/libaxolotl/protobuf/LocalStorageProtocol.proto +++ b/libaxolotl/protobuf/LocalStorageProtocol.proto @@ -58,7 +58,6 @@ message SessionStructure { optional bool needsRefresh = 12; optional bytes aliceBaseKey = 13; - optional bytes verification = 14; } message RecordStructure { diff --git a/libaxolotl/protobuf/WhisperTextProtocol.proto b/libaxolotl/protobuf/WhisperTextProtocol.proto index 93d19f0de7..211a409fda 100644 --- a/libaxolotl/protobuf/WhisperTextProtocol.proto +++ b/libaxolotl/protobuf/WhisperTextProtocol.proto @@ -16,7 +16,6 @@ message PreKeyWhisperMessage { optional uint32 signedPreKeyId = 6; optional bytes baseKey = 2; optional bytes identityKey = 3; - optional bytes verification = 7; optional bytes message = 4; // WhisperMessage } diff --git a/libaxolotl/src/androidTest/java/org/whispersystems/test/SessionBuilderTest.java b/libaxolotl/src/androidTest/java/org/whispersystems/test/SessionBuilderTest.java index 0f43f83895..44434d7384 100644 --- a/libaxolotl/src/androidTest/java/org/whispersystems/test/SessionBuilderTest.java +++ b/libaxolotl/src/androidTest/java/org/whispersystems/test/SessionBuilderTest.java @@ -406,82 +406,6 @@ public class SessionBuilderTest extends AndroidTestCase { } - public void testBadVerificationTagV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, NoSessionException { - SessionStore aliceSessionStore = new InMemorySessionStore(); - SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore(); - PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); - IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, - aliceSignedPreKeyStore, - aliceIdentityKeyStore, - BOB_RECIPIENT_ID, 1); - - SessionStore bobSessionStore = new InMemorySessionStore(); - PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); - SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore(); - IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); - - - ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true); - ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(true); - byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), - bobSignedPreKeyPair.getPublicKey().serialize()); - - PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, - 31337, bobPreKeyPair.getPublicKey(), - 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature, - bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); - - bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); - bobSignedPreKeyStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature)); - - aliceSessionBuilder.process(bobPreKey); - - String originalMessage = "L'homme est condamné à être libre"; - SessionCipher aliceSessionCipher = new SessionCipher(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentityKeyStore, BOB_RECIPIENT_ID, 1); - CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes()); - - assertTrue(outgoingMessageOne.getType() == CiphertextMessage.PREKEY_TYPE); - - PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessageOne.serialize()); - - SessionCipher bobSessionCipher = new SessionCipher(bobSessionStore, bobPreKeyStore, bobSignedPreKeyStore, bobIdentityKeyStore, ALICE_RECIPIENT_ID, 1); - - for (int i=0;i= 3) { + mac.update(senderIdentityKey.getPublicKey().serialize()); + mac.update(receiverIdentityKey.getPublicKey().serialize()); + } + byte[] fullMac = mac.doFinal(serialized); return ByteUtil.trim(fullMac, MAC_LENGTH); } catch (NoSuchAlgorithmException | java.security.InvalidKeyException e) { diff --git a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/protocol/WhisperProtos.java b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/protocol/WhisperProtos.java index b4e85e54df..0e2e9c0155 100644 --- a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/protocol/WhisperProtos.java +++ b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/protocol/WhisperProtos.java @@ -706,16 +706,6 @@ public final class WhisperProtos { */ com.google.protobuf.ByteString getIdentityKey(); - // optional bytes verification = 7; - /** - * optional bytes verification = 7; - */ - boolean hasVerification(); - /** - * optional bytes verification = 7; - */ - com.google.protobuf.ByteString getVerification(); - // optional bytes message = 4; /** * optional bytes message = 4; @@ -801,7 +791,7 @@ public final class WhisperProtos { break; } case 34: { - bitField0_ |= 0x00000040; + bitField0_ |= 0x00000020; message_ = input.readBytes(); break; } @@ -815,11 +805,6 @@ public final class WhisperProtos { signedPreKeyId_ = input.readUInt32(); break; } - case 58: { - bitField0_ |= 0x00000020; - verification_ = input.readBytes(); - break; - } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -940,22 +925,6 @@ public final class WhisperProtos { return identityKey_; } - // optional bytes verification = 7; - public static final int VERIFICATION_FIELD_NUMBER = 7; - private com.google.protobuf.ByteString verification_; - /** - * optional bytes verification = 7; - */ - public boolean hasVerification() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional bytes verification = 7; - */ - public com.google.protobuf.ByteString getVerification() { - return verification_; - } - // optional bytes message = 4; public static final int MESSAGE_FIELD_NUMBER = 4; private com.google.protobuf.ByteString message_; @@ -967,7 +936,7 @@ public final class WhisperProtos { * */ public boolean hasMessage() { - return ((bitField0_ & 0x00000040) == 0x00000040); + return ((bitField0_ & 0x00000020) == 0x00000020); } /** * optional bytes message = 4; @@ -986,7 +955,6 @@ public final class WhisperProtos { signedPreKeyId_ = 0; baseKey_ = com.google.protobuf.ByteString.EMPTY; identityKey_ = com.google.protobuf.ByteString.EMPTY; - verification_ = com.google.protobuf.ByteString.EMPTY; message_ = com.google.protobuf.ByteString.EMPTY; } private byte memoizedIsInitialized = -1; @@ -1010,7 +978,7 @@ public final class WhisperProtos { if (((bitField0_ & 0x00000010) == 0x00000010)) { output.writeBytes(3, identityKey_); } - if (((bitField0_ & 0x00000040) == 0x00000040)) { + if (((bitField0_ & 0x00000020) == 0x00000020)) { output.writeBytes(4, message_); } if (((bitField0_ & 0x00000001) == 0x00000001)) { @@ -1019,9 +987,6 @@ public final class WhisperProtos { if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeUInt32(6, signedPreKeyId_); } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - output.writeBytes(7, verification_); - } getUnknownFields().writeTo(output); } @@ -1043,7 +1008,7 @@ public final class WhisperProtos { size += com.google.protobuf.CodedOutputStream .computeBytesSize(3, identityKey_); } - if (((bitField0_ & 0x00000040) == 0x00000040)) { + if (((bitField0_ & 0x00000020) == 0x00000020)) { size += com.google.protobuf.CodedOutputStream .computeBytesSize(4, message_); } @@ -1055,10 +1020,6 @@ public final class WhisperProtos { size += com.google.protobuf.CodedOutputStream .computeUInt32Size(6, signedPreKeyId_); } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(7, verification_); - } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -1185,10 +1146,8 @@ public final class WhisperProtos { bitField0_ = (bitField0_ & ~0x00000008); identityKey_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000010); - verification_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000020); message_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000040); + bitField0_ = (bitField0_ & ~0x00000020); return this; } @@ -1240,10 +1199,6 @@ public final class WhisperProtos { if (((from_bitField0_ & 0x00000020) == 0x00000020)) { to_bitField0_ |= 0x00000020; } - result.verification_ = verification_; - if (((from_bitField0_ & 0x00000040) == 0x00000040)) { - to_bitField0_ |= 0x00000040; - } result.message_ = message_; result.bitField0_ = to_bitField0_; onBuilt(); @@ -1276,9 +1231,6 @@ public final class WhisperProtos { if (other.hasIdentityKey()) { setIdentityKey(other.getIdentityKey()); } - if (other.hasVerification()) { - setVerification(other.getVerification()); - } if (other.hasMessage()) { setMessage(other.getMessage()); } @@ -1480,42 +1432,6 @@ public final class WhisperProtos { return this; } - // optional bytes verification = 7; - private com.google.protobuf.ByteString verification_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes verification = 7; - */ - public boolean hasVerification() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional bytes verification = 7; - */ - public com.google.protobuf.ByteString getVerification() { - return verification_; - } - /** - * optional bytes verification = 7; - */ - public Builder setVerification(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000020; - verification_ = value; - onChanged(); - return this; - } - /** - * optional bytes verification = 7; - */ - public Builder clearVerification() { - bitField0_ = (bitField0_ & ~0x00000020); - verification_ = getDefaultInstance().getVerification(); - onChanged(); - return this; - } - // optional bytes message = 4; private com.google.protobuf.ByteString message_ = com.google.protobuf.ByteString.EMPTY; /** @@ -1526,7 +1442,7 @@ public final class WhisperProtos { * */ public boolean hasMessage() { - return ((bitField0_ & 0x00000040) == 0x00000040); + return ((bitField0_ & 0x00000020) == 0x00000020); } /** * optional bytes message = 4; @@ -1549,7 +1465,7 @@ public final class WhisperProtos { if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00000040; + bitField0_ |= 0x00000020; message_ = value; onChanged(); return this; @@ -1562,7 +1478,7 @@ public final class WhisperProtos { * */ public Builder clearMessage() { - bitField0_ = (bitField0_ & ~0x00000040); + bitField0_ = (bitField0_ & ~0x00000020); message_ = getDefaultInstance().getMessage(); onChanged(); return this; @@ -1625,18 +1541,10 @@ public final class WhisperProtos { // optional bytes baseKeySignature = 5; /** * optional bytes baseKeySignature = 5; - * - *
-     *  optional bytes  verification     = 6;
-     * 
*/ boolean hasBaseKeySignature(); /** * optional bytes baseKeySignature = 5; - * - *
-     *  optional bytes  verification     = 6;
-     * 
*/ com.google.protobuf.ByteString getBaseKeySignature(); } @@ -1825,20 +1733,12 @@ public final class WhisperProtos { private com.google.protobuf.ByteString baseKeySignature_; /** * optional bytes baseKeySignature = 5; - * - *
-     *  optional bytes  verification     = 6;
-     * 
*/ public boolean hasBaseKeySignature() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional bytes baseKeySignature = 5; - * - *
-     *  optional bytes  verification     = 6;
-     * 
*/ public com.google.protobuf.ByteString getBaseKeySignature() { return baseKeySignature_; @@ -2284,30 +2184,18 @@ public final class WhisperProtos { private com.google.protobuf.ByteString baseKeySignature_ = com.google.protobuf.ByteString.EMPTY; /** * optional bytes baseKeySignature = 5; - * - *
-       *  optional bytes  verification     = 6;
-       * 
*/ public boolean hasBaseKeySignature() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional bytes baseKeySignature = 5; - * - *
-       *  optional bytes  verification     = 6;
-       * 
*/ public com.google.protobuf.ByteString getBaseKeySignature() { return baseKeySignature_; } /** * optional bytes baseKeySignature = 5; - * - *
-       *  optional bytes  verification     = 6;
-       * 
*/ public Builder setBaseKeySignature(com.google.protobuf.ByteString value) { if (value == null) { @@ -2320,10 +2208,6 @@ public final class WhisperProtos { } /** * optional bytes baseKeySignature = 5; - * - *
-       *  optional bytes  verification     = 6;
-       * 
*/ public Builder clearBaseKeySignature() { bitField0_ = (bitField0_ & ~0x00000010); @@ -2370,16 +2254,15 @@ public final class WhisperProtos { "\n\031WhisperTextProtocol.proto\022\ntextsecure\"" + "b\n\016WhisperMessage\022\022\n\nratchetKey\030\001 \001(\014\022\017\n" + "\007counter\030\002 \001(\r\022\027\n\017previousCounter\030\003 \001(\r\022" + - "\022\n\nciphertext\030\004 \001(\014\"\245\001\n\024PreKeyWhisperMes" + + "\022\n\nciphertext\030\004 \001(\014\"\217\001\n\024PreKeyWhisperMes" + "sage\022\026\n\016registrationId\030\005 \001(\r\022\020\n\010preKeyId" + "\030\001 \001(\r\022\026\n\016signedPreKeyId\030\006 \001(\r\022\017\n\007baseKe" + - "y\030\002 \001(\014\022\023\n\013identityKey\030\003 \001(\014\022\024\n\014verifica" + - "tion\030\007 \001(\014\022\017\n\007message\030\004 \001(\014\"t\n\022KeyExchan" + - "geMessage\022\n\n\002id\030\001 \001(\r\022\017\n\007baseKey\030\002 \001(\014\022\022" + - "\n\nratchetKey\030\003 \001(\014\022\023\n\013identityKey\030\004 \001(\014\022", - "\030\n\020baseKeySignature\030\005 \001(\014B7\n&org.whisper" + - "systems.libaxolotl.protocolB\rWhisperProt" + - "os" + "y\030\002 \001(\014\022\023\n\013identityKey\030\003 \001(\014\022\017\n\007message\030" + + "\004 \001(\014\"t\n\022KeyExchangeMessage\022\n\n\002id\030\001 \001(\r\022" + + "\017\n\007baseKey\030\002 \001(\014\022\022\n\nratchetKey\030\003 \001(\014\022\023\n\013" + + "identityKey\030\004 \001(\014\022\030\n\020baseKeySignature\030\005 ", + "\001(\014B7\n&org.whispersystems.libaxolotl.pro" + + "tocolB\rWhisperProtos" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -2397,7 +2280,7 @@ public final class WhisperProtos { internal_static_textsecure_PreKeyWhisperMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_textsecure_PreKeyWhisperMessage_descriptor, - new java.lang.String[] { "RegistrationId", "PreKeyId", "SignedPreKeyId", "BaseKey", "IdentityKey", "Verification", "Message", }); + new java.lang.String[] { "RegistrationId", "PreKeyId", "SignedPreKeyId", "BaseKey", "IdentityKey", "Message", }); internal_static_textsecure_KeyExchangeMessage_descriptor = getDescriptor().getMessageTypes().get(2); internal_static_textsecure_KeyExchangeMessage_fieldAccessorTable = new diff --git a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/RatchetingSession.java b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/RatchetingSession.java index c732be1d2a..564969d980 100644 --- a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/RatchetingSession.java +++ b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/RatchetingSession.java @@ -28,7 +28,6 @@ import org.whispersystems.libaxolotl.util.guava.Optional; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.text.ParseException; import java.util.Arrays; public class RatchetingSession { @@ -98,11 +97,6 @@ public class RatchetingSession { sessionState.addReceiverChain(parameters.getTheirRatchetKey(), derivedKeys.getChainKey()); sessionState.setSenderChain(sendingRatchetKey, sendingChain.second()); sessionState.setRootKey(sendingChain.first()); - - if (sessionVersion >= 3) { - sessionState.setVerification(calculateVerificationTag(derivedKeys.getVerifyKey(), parameters)); - } - } catch (IOException e) { throw new AssertionError(e); } @@ -141,39 +135,11 @@ public class RatchetingSession { sessionState.setSenderChain(parameters.getOurRatchetKey(), derivedKeys.getChainKey()); sessionState.setRootKey(derivedKeys.getRootKey()); - - if (sessionVersion >= 3) { - sessionState.setVerification(calculateVerificationTag(derivedKeys.getVerifyKey(), parameters)); - } } catch (IOException e) { throw new AssertionError(e); } } - private static byte[] calculateVerificationTag(VerifyKey verifyKey, AliceAxolotlParameters parameters) { - return verifyKey.generateVerification(parameters.getOurIdentityKey().getPublicKey(), - parameters.getTheirIdentityKey(), - parameters.getOurBaseKey().getPublicKey(), - parameters.getTheirSignedPreKey(), - parameters.getTheirOneTimePreKey()); - } - - private static byte[] calculateVerificationTag(VerifyKey verifyKey, BobAxolotlParameters parameters) { - Optional ourOneTimePreKey; - - if (parameters.getOurOneTimePreKey().isPresent()) { - ourOneTimePreKey = Optional.of(parameters.getOurOneTimePreKey().get().getPublicKey()); - } else { - ourOneTimePreKey = Optional.absent(); - } - - return verifyKey.generateVerification(parameters.getTheirIdentityKey(), - parameters.getOurIdentityKey().getPublicKey(), - parameters.getTheirBaseKey(), - parameters.getOurSignedPreKey().getPublicKey(), - ourOneTimePreKey); - } - private static byte[] getDiscontinuityBytes() { byte[] discontinuity = new byte[32]; Arrays.fill(discontinuity, (byte) 0xFF); @@ -181,33 +147,25 @@ public class RatchetingSession { } private static DerivedKeys calculateDerivedKeys(int sessionVersion, byte[] masterSecret) { - try { - HKDF kdf = HKDF.createFor(sessionVersion); - byte[] derivedSecretBytes = kdf.deriveSecrets(masterSecret, "WhisperText".getBytes(), 96); - byte[][] derivedSecrets = ByteUtil.split(derivedSecretBytes, 32, 32, 32); - - return new DerivedKeys(new RootKey(kdf, derivedSecrets[0]), - new ChainKey(kdf, derivedSecrets[1], 0), - new VerifyKey(derivedSecrets[2])); - } catch (ParseException e) { - throw new AssertionError(e); - } + HKDF kdf = HKDF.createFor(sessionVersion); + byte[] derivedSecretBytes = kdf.deriveSecrets(masterSecret, "WhisperText".getBytes(), 64); + byte[][] derivedSecrets = ByteUtil.split(derivedSecretBytes, 32, 32); + + return new DerivedKeys(new RootKey(kdf, derivedSecrets[0]), + new ChainKey(kdf, derivedSecrets[1], 0)); } private static boolean isAlice(ECPublicKey ourKey, ECPublicKey theirKey) { return ourKey.compareTo(theirKey) < 0; } - private static class DerivedKeys { private final RootKey rootKey; private final ChainKey chainKey; - private final VerifyKey verifyKey; - private DerivedKeys(RootKey rootKey, ChainKey chainKey, VerifyKey verifyKey) { + private DerivedKeys(RootKey rootKey, ChainKey chainKey) { this.rootKey = rootKey; this.chainKey = chainKey; - this.verifyKey = verifyKey; } public RootKey getRootKey() { @@ -217,9 +175,5 @@ public class RatchetingSession { public ChainKey getChainKey() { return chainKey; } - - public VerifyKey getVerifyKey() { - return verifyKey; - } } } diff --git a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/VerifyKey.java b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/VerifyKey.java deleted file mode 100644 index e2ca84b148..0000000000 --- a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/ratchet/VerifyKey.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.whispersystems.libaxolotl.ratchet; - -import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.ecc.ECPublicKey; -import org.whispersystems.libaxolotl.util.ByteUtil; -import org.whispersystems.libaxolotl.util.guava.Optional; - -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -public class VerifyKey { - - private static final byte[] VERIFICATION_INFO = "TextSecure Verification Tag".getBytes(); - - private final byte[] key; - - public VerifyKey(byte[] key) { - this.key = key; - } - - public byte[] getKey() { - return key; - } - - public byte[] generateVerification(IdentityKey aliceIdentity, - IdentityKey bobIdentity, - ECPublicKey aliceBaseKey, - ECPublicKey bobSignedPreKey, - Optional bobOneTimePreKey) - { - try { - Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(new SecretKeySpec(key, "HmacSHA256")); - - mac.update(VERIFICATION_INFO); - mac.update(aliceIdentity.getPublicKey().serialize()); - mac.update(bobIdentity.getPublicKey().serialize()); - mac.update(aliceBaseKey.serialize()); - mac.update(bobSignedPreKey.serialize()); - - if (bobOneTimePreKey.isPresent()) { - mac.update(bobOneTimePreKey.get().serialize()); - } - - return ByteUtil.trim(mac.doFinal(), 8); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - throw new AssertionError(e); - } - } -} diff --git a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/SessionState.java b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/SessionState.java index 2e3bbb7367..bd150ca2bc 100644 --- a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/SessionState.java +++ b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/SessionState.java @@ -61,16 +61,6 @@ public class SessionState { return sessionStructure; } - public byte[] getVerification() { - return this.sessionStructure.getVerification().toByteArray(); - } - - public void setVerification(byte[] verification) { - this.sessionStructure = this.sessionStructure.toBuilder() - .setVerification(ByteString.copyFrom(verification)) - .build(); - } - public byte[] getAliceBaseKey() { return this.sessionStructure.getAliceBaseKey().toByteArray(); } diff --git a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/StorageProtos.java b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/StorageProtos.java index 59b1c5d030..17d14ae444 100644 --- a/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/StorageProtos.java +++ b/libaxolotl/src/main/java/org/whispersystems/libaxolotl/state/StorageProtos.java @@ -167,16 +167,6 @@ public final class StorageProtos { * optional bytes aliceBaseKey = 13; */ com.google.protobuf.ByteString getAliceBaseKey(); - - // optional bytes verification = 14; - /** - * optional bytes verification = 14; - */ - boolean hasVerification(); - /** - * optional bytes verification = 14; - */ - com.google.protobuf.ByteString getVerification(); } /** * Protobuf type {@code textsecure.SessionStructure} @@ -321,11 +311,6 @@ public final class StorageProtos { aliceBaseKey_ = input.readBytes(); break; } - case 114: { - bitField0_ |= 0x00001000; - verification_ = input.readBytes(); - break; - } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -4157,22 +4142,6 @@ public final class StorageProtos { return aliceBaseKey_; } - // optional bytes verification = 14; - public static final int VERIFICATION_FIELD_NUMBER = 14; - private com.google.protobuf.ByteString verification_; - /** - * optional bytes verification = 14; - */ - public boolean hasVerification() { - return ((bitField0_ & 0x00001000) == 0x00001000); - } - /** - * optional bytes verification = 14; - */ - public com.google.protobuf.ByteString getVerification() { - return verification_; - } - private void initFields() { sessionVersion_ = 0; localIdentityPublic_ = com.google.protobuf.ByteString.EMPTY; @@ -4187,7 +4156,6 @@ public final class StorageProtos { localRegistrationId_ = 0; needsRefresh_ = false; aliceBaseKey_ = com.google.protobuf.ByteString.EMPTY; - verification_ = com.google.protobuf.ByteString.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -4240,9 +4208,6 @@ public final class StorageProtos { if (((bitField0_ & 0x00000800) == 0x00000800)) { output.writeBytes(13, aliceBaseKey_); } - if (((bitField0_ & 0x00001000) == 0x00001000)) { - output.writeBytes(14, verification_); - } getUnknownFields().writeTo(output); } @@ -4304,10 +4269,6 @@ public final class StorageProtos { size += com.google.protobuf.CodedOutputStream .computeBytesSize(13, aliceBaseKey_); } - if (((bitField0_ & 0x00001000) == 0x00001000)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(14, verification_); - } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -4470,8 +4431,6 @@ public final class StorageProtos { bitField0_ = (bitField0_ & ~0x00000800); aliceBaseKey_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00001000); - verification_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00002000); return this; } @@ -4569,10 +4528,6 @@ public final class StorageProtos { to_bitField0_ |= 0x00000800; } result.aliceBaseKey_ = aliceBaseKey_; - if (((from_bitField0_ & 0x00002000) == 0x00002000)) { - to_bitField0_ |= 0x00001000; - } - result.verification_ = verification_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -4651,9 +4606,6 @@ public final class StorageProtos { if (other.hasAliceBaseKey()) { setAliceBaseKey(other.getAliceBaseKey()); } - if (other.hasVerification()) { - setVerification(other.getVerification()); - } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -5581,42 +5533,6 @@ public final class StorageProtos { return this; } - // optional bytes verification = 14; - private com.google.protobuf.ByteString verification_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes verification = 14; - */ - public boolean hasVerification() { - return ((bitField0_ & 0x00002000) == 0x00002000); - } - /** - * optional bytes verification = 14; - */ - public com.google.protobuf.ByteString getVerification() { - return verification_; - } - /** - * optional bytes verification = 14; - */ - public Builder setVerification(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00002000; - verification_ = value; - onChanged(); - return this; - } - /** - * optional bytes verification = 14; - */ - public Builder clearVerification() { - bitField0_ = (bitField0_ & ~0x00002000); - verification_ = getDefaultInstance().getVerification(); - onChanged(); - return this; - } - // @@protoc_insertion_point(builder_scope:textsecure.SessionStructure) } @@ -8333,7 +8249,7 @@ public final class StorageProtos { static { java.lang.String[] descriptorData = { "\n\032LocalStorageProtocol.proto\022\ntextsecure" + - "\"\335\010\n\020SessionStructure\022\026\n\016sessionVersion\030" + + "\"\307\010\n\020SessionStructure\022\026\n\016sessionVersion\030" + "\001 \001(\r\022\033\n\023localIdentityPublic\030\002 \001(\014\022\034\n\024re" + "moteIdentityPublic\030\003 \001(\014\022\017\n\007rootKey\030\004 \001(" + "\014\022\027\n\017previousCounter\030\005 \001(\r\0227\n\013senderChai" + @@ -8345,34 +8261,33 @@ public final class StorageProtos { "\001(\0132*.textsecure.SessionStructure.Pendin" + "gPreKey\022\034\n\024remoteRegistrationId\030\n \001(\r\022\033\n" + "\023localRegistrationId\030\013 \001(\r\022\024\n\014needsRefre" + - "sh\030\014 \001(\010\022\024\n\014aliceBaseKey\030\r \001(\014\022\024\n\014verifi" + - "cation\030\016 \001(\014\032\255\002\n\005Chain\022\030\n\020senderRatchetK" + - "ey\030\001 \001(\014\022\037\n\027senderRatchetKeyPrivate\030\002 \001(" + - "\014\022=\n\010chainKey\030\003 \001(\0132+.textsecure.Session" + - "Structure.Chain.ChainKey\022B\n\013messageKeys\030" + - "\004 \003(\0132-.textsecure.SessionStructure.Chai" + - "n.MessageKey\032&\n\010ChainKey\022\r\n\005index\030\001 \001(\r\022", - "\013\n\003key\030\002 \001(\014\032>\n\nMessageKey\022\r\n\005index\030\001 \001(" + - "\r\022\021\n\tcipherKey\030\002 \001(\014\022\016\n\006macKey\030\003 \001(\014\032\315\001\n" + - "\022PendingKeyExchange\022\020\n\010sequence\030\001 \001(\r\022\024\n" + - "\014localBaseKey\030\002 \001(\014\022\033\n\023localBaseKeyPriva" + - "te\030\003 \001(\014\022\027\n\017localRatchetKey\030\004 \001(\014\022\036\n\026loc" + - "alRatchetKeyPrivate\030\005 \001(\014\022\030\n\020localIdenti" + - "tyKey\030\007 \001(\014\022\037\n\027localIdentityKeyPrivate\030\010" + - " \001(\014\032J\n\rPendingPreKey\022\020\n\010preKeyId\030\001 \001(\r\022" + - "\026\n\016signedPreKeyId\030\003 \001(\005\022\017\n\007baseKey\030\002 \001(\014" + - "\"\177\n\017RecordStructure\0224\n\016currentSession\030\001 ", - "\001(\0132\034.textsecure.SessionStructure\0226\n\020pre" + - "viousSessions\030\002 \003(\0132\034.textsecure.Session" + - "Structure\"J\n\025PreKeyRecordStructure\022\n\n\002id" + - "\030\001 \001(\r\022\021\n\tpublicKey\030\002 \001(\014\022\022\n\nprivateKey\030" + - "\003 \001(\014\"v\n\033SignedPreKeyRecordStructure\022\n\n\002" + - "id\030\001 \001(\r\022\021\n\tpublicKey\030\002 \001(\014\022\022\n\nprivateKe" + - "y\030\003 \001(\014\022\021\n\tsignature\030\004 \001(\014\022\021\n\ttimestamp\030" + - "\005 \001(\006\"A\n\030IdentityKeyPairStructure\022\021\n\tpub" + - "licKey\030\001 \001(\014\022\022\n\nprivateKey\030\002 \001(\014B4\n#org." + - "whispersystems.libaxolotl.stateB\rStorage", - "Protos" + "sh\030\014 \001(\010\022\024\n\014aliceBaseKey\030\r \001(\014\032\255\002\n\005Chain" + + "\022\030\n\020senderRatchetKey\030\001 \001(\014\022\037\n\027senderRatc" + + "hetKeyPrivate\030\002 \001(\014\022=\n\010chainKey\030\003 \001(\0132+." + + "textsecure.SessionStructure.Chain.ChainK" + + "ey\022B\n\013messageKeys\030\004 \003(\0132-.textsecure.Ses" + + "sionStructure.Chain.MessageKey\032&\n\010ChainK" + + "ey\022\r\n\005index\030\001 \001(\r\022\013\n\003key\030\002 \001(\014\032>\n\nMessag", + "eKey\022\r\n\005index\030\001 \001(\r\022\021\n\tcipherKey\030\002 \001(\014\022\016" + + "\n\006macKey\030\003 \001(\014\032\315\001\n\022PendingKeyExchange\022\020\n" + + "\010sequence\030\001 \001(\r\022\024\n\014localBaseKey\030\002 \001(\014\022\033\n" + + "\023localBaseKeyPrivate\030\003 \001(\014\022\027\n\017localRatch" + + "etKey\030\004 \001(\014\022\036\n\026localRatchetKeyPrivate\030\005 " + + "\001(\014\022\030\n\020localIdentityKey\030\007 \001(\014\022\037\n\027localId" + + "entityKeyPrivate\030\010 \001(\014\032J\n\rPendingPreKey\022" + + "\020\n\010preKeyId\030\001 \001(\r\022\026\n\016signedPreKeyId\030\003 \001(" + + "\005\022\017\n\007baseKey\030\002 \001(\014\"\177\n\017RecordStructure\0224\n" + + "\016currentSession\030\001 \001(\0132\034.textsecure.Sessi", + "onStructure\0226\n\020previousSessions\030\002 \003(\0132\034." + + "textsecure.SessionStructure\"J\n\025PreKeyRec" + + "ordStructure\022\n\n\002id\030\001 \001(\r\022\021\n\tpublicKey\030\002 " + + "\001(\014\022\022\n\nprivateKey\030\003 \001(\014\"v\n\033SignedPreKeyR" + + "ecordStructure\022\n\n\002id\030\001 \001(\r\022\021\n\tpublicKey\030" + + "\002 \001(\014\022\022\n\nprivateKey\030\003 \001(\014\022\021\n\tsignature\030\004" + + " \001(\014\022\021\n\ttimestamp\030\005 \001(\006\"A\n\030IdentityKeyPa" + + "irStructure\022\021\n\tpublicKey\030\001 \001(\014\022\022\n\nprivat" + + "eKey\030\002 \001(\014B4\n#org.whispersystems.libaxol" + + "otl.stateB\rStorageProtos" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -8384,7 +8299,7 @@ public final class StorageProtos { internal_static_textsecure_SessionStructure_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_textsecure_SessionStructure_descriptor, - new java.lang.String[] { "SessionVersion", "LocalIdentityPublic", "RemoteIdentityPublic", "RootKey", "PreviousCounter", "SenderChain", "ReceiverChains", "PendingKeyExchange", "PendingPreKey", "RemoteRegistrationId", "LocalRegistrationId", "NeedsRefresh", "AliceBaseKey", "Verification", }); + new java.lang.String[] { "SessionVersion", "LocalIdentityPublic", "RemoteIdentityPublic", "RootKey", "PreviousCounter", "SenderChain", "ReceiverChains", "PendingKeyExchange", "PendingPreKey", "RemoteRegistrationId", "LocalRegistrationId", "NeedsRefresh", "AliceBaseKey", }); internal_static_textsecure_SessionStructure_Chain_descriptor = internal_static_textsecure_SessionStructure_descriptor.getNestedTypes().get(0); internal_static_textsecure_SessionStructure_Chain_fieldAccessorTable = new