Rename axolotl terminology.

1) ephemeralKey -> ratchetKey

2) Have the caller specify Alice/Bob orientation.

3) Reorganize verification tag.

4) Remove verification tag from key exchange messages, replace
   with signatures in both directions.
This commit is contained in:
Moxie Marlinspike
2014-07-23 01:00:32 -07:00
parent 82bd75fb75
commit 641ac9aed9
18 changed files with 962 additions and 828 deletions

View File

@@ -154,7 +154,8 @@ public class SessionBuilderTest extends AndroidTestCase {
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(),
22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
22, bobSignedPreKeyPair.getPublicKey(),
bobSignedPreKeySignature,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
aliceSessionBuilder.process(bobPreKey);

View File

@@ -15,6 +15,8 @@ import org.whispersystems.libaxolotl.ecc.ECKeyPair;
import org.whispersystems.libaxolotl.ecc.ECPublicKey;
import org.whispersystems.libaxolotl.protocol.CiphertextMessage;
import org.whispersystems.libaxolotl.protocol.WhisperMessage;
import org.whispersystems.libaxolotl.ratchet.AliceAxolotlParameters;
import org.whispersystems.libaxolotl.ratchet.BobAxolotlParameters;
import org.whispersystems.libaxolotl.ratchet.RatchetingSession;
import org.whispersystems.libaxolotl.state.IdentityKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyStore;
@@ -31,7 +33,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Random;
import static org.whispersystems.libaxolotl.ratchet.RatchetingSession.AxolotlParameters;
public class SessionCipherTest extends AndroidTestCase {
@@ -149,30 +150,23 @@ public class SessionCipherTest extends AndroidTestCase {
ECKeyPair bobBaseKey = Curve.generateKeyPair(true);
ECKeyPair bobEphemeralKey = bobBaseKey;
AxolotlParameters aliceParameters =
AxolotlParameters.newBuilder()
.setOurIdentityKey(aliceIdentityKey)
.setOurBaseKey(aliceBaseKey)
.setOurEphemeralKey(aliceEphemeralKey)
.setOurPreKey(Optional.<ECKeyPair>absent())
.setTheirIdentityKey(bobIdentityKey.getPublicKey())
.setTheirBaseKey(bobBaseKey.getPublicKey())
.setTheirEphemeralKey(bobEphemeralKey.getPublicKey())
.setTheirPreKey(Optional.<ECPublicKey>absent())
.create();
AxolotlParameters bobParameters =
RatchetingSession.AxolotlParameters.newBuilder()
.setOurIdentityKey(bobIdentityKey)
.setOurBaseKey(bobBaseKey)
.setOurEphemeralKey(bobEphemeralKey)
.setOurPreKey(Optional.<ECKeyPair>absent())
.setTheirIdentityKey(aliceIdentityKey.getPublicKey())
.setTheirBaseKey(aliceBaseKey.getPublicKey())
.setTheirEphemeralKey(aliceEphemeralKey.getPublicKey())
.setTheirPreKey(Optional.<ECPublicKey>absent())
.create();
AliceAxolotlParameters aliceParameters = AliceAxolotlParameters.newBuilder()
.setOurIdentityKey(aliceIdentityKey)
.setOurBaseKey(aliceBaseKey)
.setTheirIdentityKey(bobIdentityKey.getPublicKey())
.setTheirSignedPreKey(bobEphemeralKey.getPublicKey())
.setTheirRatchetKey(bobEphemeralKey.getPublicKey())
.setTheirOneTimePreKey(Optional.<ECPublicKey>absent())
.create();
BobAxolotlParameters bobParameters = BobAxolotlParameters.newBuilder()
.setOurIdentityKey(bobIdentityKey)
.setOurOneTimePreKey(Optional.<ECKeyPair>absent())
.setOurRatchetKey(bobEphemeralKey)
.setOurSignedPreKey(bobBaseKey)
.setTheirBaseKey(aliceBaseKey.getPublicKey())
.setTheirIdentityKey(aliceIdentityKey.getPublicKey())
.create();
RatchetingSession.initializeSession(aliceSessionState, 2, aliceParameters);
RatchetingSession.initializeSession(bobSessionState, 2, bobParameters);
@@ -197,33 +191,25 @@ public class SessionCipherTest extends AndroidTestCase {
ECKeyPair bobPreKey = Curve.generateKeyPair(true);
AxolotlParameters aliceParameters =
AxolotlParameters.newBuilder()
.setOurIdentityKey(aliceIdentityKey)
.setOurBaseKey(aliceBaseKey)
.setOurEphemeralKey(aliceEphemeralKey)
.setOurPreKey(Optional.of(alicePreKey))
.setTheirIdentityKey(bobIdentityKey.getPublicKey())
.setTheirBaseKey(bobBaseKey.getPublicKey())
.setTheirEphemeralKey(bobEphemeralKey.getPublicKey())
.setTheirPreKey(Optional.of(bobPreKey.getPublicKey()))
.create();
AxolotlParameters bobParameters =
AxolotlParameters.newBuilder()
.setOurIdentityKey(bobIdentityKey)
.setOurBaseKey(bobBaseKey)
.setOurEphemeralKey(bobEphemeralKey)
.setOurPreKey(Optional.of(bobPreKey))
.setTheirIdentityKey(aliceIdentityKey.getPublicKey())
.setTheirBaseKey(aliceBaseKey.getPublicKey())
.setTheirEphemeralKey(aliceEphemeralKey.getPublicKey())
.setTheirPreKey(Optional.of(alicePreKey.getPublicKey()))
.create();
AliceAxolotlParameters aliceParameters = AliceAxolotlParameters.newBuilder()
.setOurBaseKey(aliceBaseKey)
.setOurIdentityKey(aliceIdentityKey)
.setTheirOneTimePreKey(Optional.<ECPublicKey>absent())
.setTheirRatchetKey(bobEphemeralKey.getPublicKey())
.setTheirSignedPreKey(bobBaseKey.getPublicKey())
.setTheirIdentityKey(bobIdentityKey.getPublicKey())
.create();
BobAxolotlParameters bobParameters = BobAxolotlParameters.newBuilder()
.setOurRatchetKey(bobEphemeralKey)
.setOurSignedPreKey(bobBaseKey)
.setOurOneTimePreKey(Optional.<ECKeyPair>absent())
.setOurIdentityKey(bobIdentityKey)
.setTheirIdentityKey(aliceIdentityKey.getPublicKey())
.setTheirBaseKey(aliceBaseKey.getPublicKey())
.create();
RatchetingSession.initializeSession(aliceSessionState, 3, aliceParameters);
RatchetingSession.initializeSession(bobSessionState, 3, bobParameters);
}
}

View File

@@ -9,14 +9,14 @@ 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.ratchet.AliceAxolotlParameters;
import org.whispersystems.libaxolotl.ratchet.BobAxolotlParameters;
import org.whispersystems.libaxolotl.ratchet.RatchetingSession;
import org.whispersystems.libaxolotl.state.SessionState;
import org.whispersystems.libaxolotl.util.guava.Optional;
import java.util.Arrays;
import static org.whispersystems.libaxolotl.ratchet.RatchetingSession.AxolotlParameters;
public class RatchetingSessionTest extends AndroidTestCase {
public void testRatchetingSessionAsBob() throws InvalidKeyException {
@@ -108,20 +108,17 @@ public class RatchetingSessionTest extends AndroidTestCase {
ECPublicKey aliceEphemeralPublicKey = Curve.decodePoint(aliceEphemeralPublic, 0);
IdentityKey aliceIdentityPublicKey = new IdentityKey(aliceIdentityPublic, 0);
AxolotlParameters parameters = AxolotlParameters.newBuilder()
.setOurBaseKey(bobBaseKey)
.setOurEphemeralKey(bobEphemeralKey)
.setOurIdentityKey(bobIdentityKey)
.setOurPreKey(Optional.<ECKeyPair>absent())
.setTheirBaseKey(aliceBasePublicKey)
.setTheirEphemeralKey(aliceEphemeralPublicKey)
.setTheirIdentityKey(aliceIdentityPublicKey)
.setTheirPreKey(Optional.<ECPublicKey>absent())
.create();
BobAxolotlParameters parameters = BobAxolotlParameters.newBuilder()
.setOurIdentityKey(bobIdentityKey)
.setOurSignedPreKey(bobBaseKey)
.setOurRatchetKey(bobEphemeralKey)
.setOurOneTimePreKey(Optional.<ECKeyPair>absent())
.setTheirIdentityKey(aliceIdentityPublicKey)
.setTheirBaseKey(aliceBasePublicKey)
.create();
SessionState session = new SessionState();
RatchetingSession.initializeSession(session, 2, parameters);
assertTrue(session.getLocalIdentityKey().equals(bobIdentityKey.getPublicKey()));
@@ -217,16 +214,14 @@ public class RatchetingSessionTest extends AndroidTestCase {
SessionState session = new SessionState();
AxolotlParameters parameters = AxolotlParameters.newBuilder()
.setOurBaseKey(aliceBaseKey)
.setOurEphemeralKey(aliceEphemeralKey)
.setOurIdentityKey(aliceIdentityKey)
.setOurPreKey(Optional.<ECKeyPair>absent())
.setTheirBaseKey(bobBasePublicKey)
.setTheirEphemeralKey(bobEphemeralPublicKey)
.setTheirIdentityKey(bobIdentityKey)
.setTheirPreKey(Optional.<ECPublicKey>absent())
.create();
AliceAxolotlParameters parameters = AliceAxolotlParameters.newBuilder()
.setOurBaseKey(aliceBaseKey)
.setOurIdentityKey(aliceIdentityKey)
.setTheirIdentityKey(bobIdentityKey)
.setTheirSignedPreKey(bobBasePublicKey)
.setTheirRatchetKey(bobEphemeralPublicKey)
.setTheirOneTimePreKey(Optional.<ECPublicKey>absent())
.create();
RatchetingSession.initializeSession(session, 2, parameters);

View File

@@ -3,6 +3,7 @@ package org.whispersystems.test.ratchet;
import android.test.AndroidTestCase;
import android.util.Log;
import org.whispersystems.libaxolotl.IdentityKey;
import org.whispersystems.libaxolotl.InvalidKeyException;
import org.whispersystems.libaxolotl.ecc.Curve;
import org.whispersystems.libaxolotl.ecc.ECPublicKey;
@@ -65,8 +66,8 @@ public class VerifyKeyTest extends AndroidTestCase {
(byte)0x79, (byte)0x00, (byte)0xef, (byte)0x1b, (byte)0x40,
(byte)0x0f, (byte)0xdc};
byte[] expectedTag = {(byte)0x2f, (byte)0x77, (byte)0xaf, (byte)0xad, (byte)0x5b,
(byte)0x96, (byte)0xf5, (byte)0x3c};
byte[] expectedTag = {(byte)0xd3, (byte)0x62, (byte)0x84, (byte)0x3c,
(byte)0x9d, (byte)0x59, (byte)0x8c, (byte)0x6f};
ECPublicKey aliceBaseKey = Curve.decodePoint(aliceBaseKeyBytes, 0);
ECPublicKey alicePreKey = aliceBaseKey;
@@ -77,9 +78,11 @@ public class VerifyKeyTest extends AndroidTestCase {
ECPublicKey bobIdentityKey = Curve.decodePoint(bobIdentityKeyBytes, 0);
VerifyKey verifyKey = new VerifyKey(key);
byte[] verification = verifyKey.generateVerification(aliceBaseKey, Optional.of(alicePreKey),
aliceIdentityKey, bobBaseKey,
Optional.of(bobPreKey), bobIdentityKey);
byte[] verification = verifyKey.generateVerification(new IdentityKey(aliceIdentityKey),
new IdentityKey(bobIdentityKey),
aliceBaseKey, bobBaseKey,
Optional.of(bobPreKey));
assertTrue(MessageDigest.isEqual(verification, expectedTag));
}