Refactor KeyManager and TagRecogniser. #55

This commit is contained in:
akwizgran
2015-02-12 09:11:24 +00:00
parent 878a70620d
commit 9868feeb2a
60 changed files with 2123 additions and 3840 deletions

View File

@@ -4,6 +4,7 @@ import org.briarproject.BriarTestCase;
import org.briarproject.TestSeedProvider;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.system.SeedProvider;
import org.junit.Test;
@@ -19,8 +20,8 @@ public class KeyAgreementTest extends BriarTestCase {
byte[] aPub = aPair.getPublic().getEncoded();
KeyPair bPair = crypto.generateAgreementKeyPair();
byte[] bPub = bPair.getPublic().getEncoded();
byte[] aSecret = crypto.deriveMasterSecret(aPub, bPair, true);
byte[] bSecret = crypto.deriveMasterSecret(bPub, aPair, false);
assertArrayEquals(aSecret, bSecret);
SecretKey aMaster = crypto.deriveMasterSecret(aPub, bPair, true);
SecretKey bMaster = crypto.deriveMasterSecret(bPub, aPair, false);
assertArrayEquals(aMaster.getBytes(), bMaster.getBytes());
}
}

View File

@@ -2,72 +2,164 @@ package org.briarproject.crypto;
import org.briarproject.BriarTestCase;
import org.briarproject.TestSeedProvider;
import org.briarproject.TestUtils;
import org.briarproject.api.TransportId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.transport.TransportKeys;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
public class KeyDerivationTest extends BriarTestCase {
private final TransportId transportId = new TransportId("id");
private final CryptoComponent crypto;
private final byte[] secret;
private final SecretKey master;
public KeyDerivationTest() {
crypto = new CryptoComponentImpl(new TestSeedProvider());
secret = new byte[32];
new Random().nextBytes(secret);
master = TestUtils.createSecretKey();
}
@Test
public void testKeysAreDistinct() {
List<SecretKey> keys = new ArrayList<SecretKey>();
keys.add(crypto.deriveFrameKey(secret, 0, true));
keys.add(crypto.deriveFrameKey(secret, 0, false));
keys.add(crypto.deriveTagKey(secret, true));
keys.add(crypto.deriveTagKey(secret, false));
for (int i = 0; i < 4; i++) {
byte[] keyI = keys.get(i).getBytes();
for (int j = 0; j < 4; j++) {
byte[] keyJ = keys.get(j).getBytes();
assertEquals(i == j, Arrays.equals(keyI, keyJ));
}
}
TransportKeys k = crypto.deriveTransportKeys(transportId, master,
123, true);
assertAllDifferent(k);
}
@Test
public void testSecretAffectsDerivation() {
Random r = new Random();
List<byte[]> secrets = new ArrayList<byte[]>();
for (int i = 0; i < 20; i++) {
byte[] b = new byte[32];
r.nextBytes(b);
secrets.add(crypto.deriveNextSecret(b, 0));
}
for (int i = 0; i < 20; i++) {
byte[] secretI = secrets.get(i);
for (int j = 0; j < 20; j++) {
byte[] secretJ = secrets.get(j);
assertEquals(i == j, Arrays.equals(secretI, secretJ));
}
}
public void testCurrentKeysMatchCurrentKeysOfContact() {
// Start in rotation period 123
TransportKeys kA = crypto.deriveTransportKeys(transportId, master,
123, true);
TransportKeys kB = crypto.deriveTransportKeys(transportId, master,
123, false);
// Alice's incoming keys should equal Bob's outgoing keys
assertArrayEquals(kA.getCurrentIncomingKeys().getTagKey().getBytes(),
kB.getCurrentOutgoingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getCurrentIncomingKeys().getHeaderKey().getBytes(),
kB.getCurrentOutgoingKeys().getHeaderKey().getBytes());
// Alice's outgoing keys should equal Bob's incoming keys
assertArrayEquals(kA.getCurrentOutgoingKeys().getTagKey().getBytes(),
kB.getCurrentIncomingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getCurrentOutgoingKeys().getHeaderKey().getBytes(),
kB.getCurrentIncomingKeys().getHeaderKey().getBytes());
// Rotate into the future
kA = crypto.rotateTransportKeys(kA, 456);
kB = crypto.rotateTransportKeys(kB, 456);
// Alice's incoming keys should equal Bob's outgoing keys
assertArrayEquals(kA.getCurrentIncomingKeys().getTagKey().getBytes(),
kB.getCurrentOutgoingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getCurrentIncomingKeys().getHeaderKey().getBytes(),
kB.getCurrentOutgoingKeys().getHeaderKey().getBytes());
// Alice's outgoing keys should equal Bob's incoming keys
assertArrayEquals(kA.getCurrentOutgoingKeys().getTagKey().getBytes(),
kB.getCurrentIncomingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getCurrentOutgoingKeys().getHeaderKey().getBytes(),
kB.getCurrentIncomingKeys().getHeaderKey().getBytes());
}
@Test
public void testStreamNumberAffectsDerivation() {
List<byte[]> secrets = new ArrayList<byte[]>();
for (int i = 0; i < 20; i++)
secrets.add(crypto.deriveNextSecret(secret, i));
for (int i = 0; i < 20; i++) {
byte[] secretI = secrets.get(i);
for (int j = 0; j < 20; j++) {
byte[] secretJ = secrets.get(j);
assertEquals(i == j, Arrays.equals(secretI, secretJ));
public void testPreviousKeysMatchPreviousKeysOfContact() {
// Start in rotation period 123
TransportKeys kA = crypto.deriveTransportKeys(transportId, master,
123, true);
TransportKeys kB = crypto.deriveTransportKeys(transportId, master,
123, false);
// Compare Alice's previous keys in period 456 with Bob's current keys
// in period 455
kA = crypto.rotateTransportKeys(kA, 456);
kB = crypto.rotateTransportKeys(kB, 455);
// Alice's previous incoming keys should equal Bob's outgoing keys
assertArrayEquals(kA.getPreviousIncomingKeys().getTagKey().getBytes(),
kB.getCurrentOutgoingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getPreviousIncomingKeys().getHeaderKey().getBytes(),
kB.getCurrentOutgoingKeys().getHeaderKey().getBytes());
// Compare Alice's current keys in period 456 with Bob's previous keys
// in period 457
kB = crypto.rotateTransportKeys(kB, 457);
// Alice's outgoing keys should equal Bob's previous incoming keys
assertArrayEquals(kA.getCurrentOutgoingKeys().getTagKey().getBytes(),
kB.getPreviousIncomingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getCurrentOutgoingKeys().getHeaderKey().getBytes(),
kB.getPreviousIncomingKeys().getHeaderKey().getBytes());
}
@Test
public void testNextKeysMatchNextKeysOfContact() {
// Start in rotation period 123
TransportKeys kA = crypto.deriveTransportKeys(transportId, master,
123, true);
TransportKeys kB = crypto.deriveTransportKeys(transportId, master,
123, false);
// Compare Alice's current keys in period 456 with Bob's next keys in
// period 455
kA = crypto.rotateTransportKeys(kA, 456);
kB = crypto.rotateTransportKeys(kB, 455);
// Alice's outgoing keys should equal Bob's next incoming keys
assertArrayEquals(kA.getCurrentOutgoingKeys().getTagKey().getBytes(),
kB.getNextIncomingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getCurrentOutgoingKeys().getHeaderKey().getBytes(),
kB.getNextIncomingKeys().getHeaderKey().getBytes());
// Compare Alice's next keys in period 456 with Bob's current keys
// in period 457
kB = crypto.rotateTransportKeys(kB, 457);
// Alice's next incoming keys should equal Bob's outgoing keys
assertArrayEquals(kA.getNextIncomingKeys().getTagKey().getBytes(),
kB.getCurrentOutgoingKeys().getTagKey().getBytes());
assertArrayEquals(kA.getNextIncomingKeys().getHeaderKey().getBytes(),
kB.getCurrentOutgoingKeys().getHeaderKey().getBytes());
}
@Test
public void testMasterKeyAffectsOutput() {
SecretKey master1 = TestUtils.createSecretKey();
assertFalse(Arrays.equals(master.getBytes(), master1.getBytes()));
TransportKeys k = crypto.deriveTransportKeys(transportId, master,
123, true);
TransportKeys k1 = crypto.deriveTransportKeys(transportId, master1,
123, true);
assertAllDifferent(k, k1);
}
@Test
public void testTransportIdAffectsOutput() {
TransportId transportId1 = new TransportId("id1");
assertFalse(transportId.getString().equals(transportId1.getString()));
TransportKeys k = crypto.deriveTransportKeys(transportId, master,
123, true);
TransportKeys k1 = crypto.deriveTransportKeys(transportId1, master,
123, true);
assertAllDifferent(k, k1);
}
private void assertAllDifferent(TransportKeys... transportKeys) {
List<SecretKey> secretKeys = new ArrayList<SecretKey>();
for (TransportKeys k : transportKeys) {
secretKeys.add(k.getPreviousIncomingKeys().getTagKey());
secretKeys.add(k.getPreviousIncomingKeys().getHeaderKey());
secretKeys.add(k.getCurrentIncomingKeys().getTagKey());
secretKeys.add(k.getCurrentIncomingKeys().getHeaderKey());
secretKeys.add(k.getNextIncomingKeys().getTagKey());
secretKeys.add(k.getNextIncomingKeys().getHeaderKey());
secretKeys.add(k.getCurrentOutgoingKeys().getTagKey());
secretKeys.add(k.getCurrentOutgoingKeys().getHeaderKey());
}
assertAllDifferent(secretKeys);
}
private void assertAllDifferent(List<SecretKey> keys) {
for (SecretKey ki : keys) {
for (SecretKey kj : keys) {
if (ki == kj) assertArrayEquals(ki.getBytes(), kj.getBytes());
else assertFalse(Arrays.equals(ki.getBytes(), kj.getBytes()));
}
}
}