Create DB tables for static keys.

This commit is contained in:
akwizgran
2019-04-09 14:48:45 +01:00
parent ff2f710495
commit b568405f59
17 changed files with 324 additions and 196 deletions

View File

@@ -11,19 +11,19 @@ public interface TransportCrypto {
/** /**
* Derives initial transport keys for the given transport in the given * Derives initial transport keys for the given transport in the given
* rotation period from the given master secret. * time period from the given master secret.
* *
* @param alice whether the keys are for use by Alice or Bob. * @param alice whether the keys are for use by Alice or Bob.
* @param active whether the keys are usable for outgoing streams. * @param active whether the keys are usable for outgoing streams.
*/ */
TransportKeys deriveTransportKeys(TransportId t, SecretKey master, TransportKeys deriveTransportKeys(TransportId t, SecretKey master,
long rotationPeriod, boolean alice, boolean active); long timePeriod, boolean alice, boolean active);
/** /**
* Rotates the given transport keys to the given rotation period. If the * Rotates the given transport keys to the given time period. If the keys
* keys are for the given period or any later period they are not rotated. * are for the given period or any later period they are not rotated.
*/ */
TransportKeys rotateTransportKeys(TransportKeys k, long rotationPeriod); TransportKeys rotateTransportKeys(TransportKeys k, long timePeriod);
/** /**
* Encodes the pseudo-random tag that is used to recognise a stream. * Encodes the pseudo-random tag that is used to recognise a stream.

View File

@@ -554,10 +554,10 @@ public interface DatabaseComponent {
/** /**
* Sets the reordering window for the given key set and transport in the * Sets the reordering window for the given key set and transport in the
* given rotation period. * given time period.
*/ */
void setReorderingWindow(Transaction txn, KeySetId k, TransportId t, void setReorderingWindow(Transaction txn, KeySetId k, TransportId t,
long rotationPeriod, long base, byte[] bitmap) throws DbException; long timePeriod, long base, byte[] bitmap) throws DbException;
/** /**
* Marks the given transport keys as usable for outgoing streams. * Marks the given transport keys as usable for outgoing streams.

View File

@@ -9,27 +9,27 @@ import static org.briarproject.bramble.api.transport.TransportConstants.REORDERI
/** /**
* Contains transport keys for receiving streams from a given contact over a * Contains transport keys for receiving streams from a given contact over a
* given transport in a given rotation period. * given transport in a given time period.
*/ */
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class IncomingKeys { public class IncomingKeys {
private final SecretKey tagKey, headerKey; private final SecretKey tagKey, headerKey;
private final long rotationPeriod, windowBase; private final long timePeriod, windowBase;
private final byte[] windowBitmap; private final byte[] windowBitmap;
public IncomingKeys(SecretKey tagKey, SecretKey headerKey, public IncomingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod) { long timePeriod) {
this(tagKey, headerKey, rotationPeriod, 0, this(tagKey, headerKey, timePeriod, 0,
new byte[REORDERING_WINDOW_SIZE / 8]); new byte[REORDERING_WINDOW_SIZE / 8]);
} }
public IncomingKeys(SecretKey tagKey, SecretKey headerKey, public IncomingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod, long windowBase, byte[] windowBitmap) { long timePeriod, long windowBase, byte[] windowBitmap) {
this.tagKey = tagKey; this.tagKey = tagKey;
this.headerKey = headerKey; this.headerKey = headerKey;
this.rotationPeriod = rotationPeriod; this.timePeriod = timePeriod;
this.windowBase = windowBase; this.windowBase = windowBase;
this.windowBitmap = windowBitmap; this.windowBitmap = windowBitmap;
} }
@@ -42,8 +42,8 @@ public class IncomingKeys {
return headerKey; return headerKey;
} }
public long getRotationPeriod() { public long getTimePeriod() {
return rotationPeriod; return timePeriod;
} }
public long getWindowBase() { public long getWindowBase() {

View File

@@ -7,26 +7,26 @@ import javax.annotation.concurrent.Immutable;
/** /**
* Contains transport keys for sending streams to a given contact over a given * Contains transport keys for sending streams to a given contact over a given
* transport in a given rotation period. * transport in a given time period.
*/ */
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class OutgoingKeys { public class OutgoingKeys {
private final SecretKey tagKey, headerKey; private final SecretKey tagKey, headerKey;
private final long rotationPeriod, streamCounter; private final long timePeriod, streamCounter;
private final boolean active; private final boolean active;
public OutgoingKeys(SecretKey tagKey, SecretKey headerKey, public OutgoingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod, boolean active) { long timePeriod, boolean active) {
this(tagKey, headerKey, rotationPeriod, 0, active); this(tagKey, headerKey, timePeriod, 0, active);
} }
public OutgoingKeys(SecretKey tagKey, SecretKey headerKey, public OutgoingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod, long streamCounter, boolean active) { long timePeriod, long streamCounter, boolean active) {
this.tagKey = tagKey; this.tagKey = tagKey;
this.headerKey = headerKey; this.headerKey = headerKey;
this.rotationPeriod = rotationPeriod; this.timePeriod = timePeriod;
this.streamCounter = streamCounter; this.streamCounter = streamCounter;
this.active = active; this.active = active;
} }
@@ -39,8 +39,8 @@ public class OutgoingKeys {
return headerKey; return headerKey;
} }
public long getRotationPeriod() { public long getTimePeriod() {
return rotationPeriod; return timePeriod;
} }
public long getStreamCounter() { public long getStreamCounter() {

View File

@@ -18,11 +18,11 @@ public class TransportKeys {
public TransportKeys(TransportId transportId, IncomingKeys inPrev, public TransportKeys(TransportId transportId, IncomingKeys inPrev,
IncomingKeys inCurr, IncomingKeys inNext, OutgoingKeys outCurr) { IncomingKeys inCurr, IncomingKeys inNext, OutgoingKeys outCurr) {
if (inPrev.getRotationPeriod() != outCurr.getRotationPeriod() - 1) if (inPrev.getTimePeriod() != outCurr.getTimePeriod() - 1)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (inCurr.getRotationPeriod() != outCurr.getRotationPeriod()) if (inCurr.getTimePeriod() != outCurr.getTimePeriod())
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (inNext.getRotationPeriod() != outCurr.getRotationPeriod() + 1) if (inNext.getTimePeriod() != outCurr.getTimePeriod() + 1)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.transportId = transportId; this.transportId = transportId;
this.inPrev = inPrev; this.inPrev = inPrev;
@@ -51,7 +51,7 @@ public class TransportKeys {
return outCurr; return outCurr;
} }
public long getRotationPeriod() { public long getTimePeriod() {
return outCurr.getRotationPeriod(); return outCurr.getTimePeriod();
} }
} }

View File

@@ -36,45 +36,44 @@ class TransportCryptoImpl implements TransportCrypto {
@Override @Override
public TransportKeys deriveTransportKeys(TransportId t, public TransportKeys deriveTransportKeys(TransportId t,
SecretKey master, long rotationPeriod, boolean alice, SecretKey master, long timePeriod, boolean alice, boolean active) {
boolean active) {
// Keys for the previous period are derived from the master secret // Keys for the previous period are derived from the master secret
SecretKey inTagPrev = deriveTagKey(master, t, !alice); SecretKey inTagPrev = deriveTagKey(master, t, !alice);
SecretKey inHeaderPrev = deriveHeaderKey(master, t, !alice); SecretKey inHeaderPrev = deriveHeaderKey(master, t, !alice);
SecretKey outTagPrev = deriveTagKey(master, t, alice); SecretKey outTagPrev = deriveTagKey(master, t, alice);
SecretKey outHeaderPrev = deriveHeaderKey(master, t, alice); SecretKey outHeaderPrev = deriveHeaderKey(master, t, alice);
// Derive the keys for the current and next periods // Derive the keys for the current and next periods
SecretKey inTagCurr = rotateKey(inTagPrev, rotationPeriod); SecretKey inTagCurr = rotateKey(inTagPrev, timePeriod);
SecretKey inHeaderCurr = rotateKey(inHeaderPrev, rotationPeriod); SecretKey inHeaderCurr = rotateKey(inHeaderPrev, timePeriod);
SecretKey inTagNext = rotateKey(inTagCurr, rotationPeriod + 1); SecretKey inTagNext = rotateKey(inTagCurr, timePeriod + 1);
SecretKey inHeaderNext = rotateKey(inHeaderCurr, rotationPeriod + 1); SecretKey inHeaderNext = rotateKey(inHeaderCurr, timePeriod + 1);
SecretKey outTagCurr = rotateKey(outTagPrev, rotationPeriod); SecretKey outTagCurr = rotateKey(outTagPrev, timePeriod);
SecretKey outHeaderCurr = rotateKey(outHeaderPrev, rotationPeriod); SecretKey outHeaderCurr = rotateKey(outHeaderPrev, timePeriod);
// Initialise the reordering windows and stream counters // Initialise the reordering windows and stream counters
IncomingKeys inPrev = new IncomingKeys(inTagPrev, inHeaderPrev, IncomingKeys inPrev = new IncomingKeys(inTagPrev, inHeaderPrev,
rotationPeriod - 1); timePeriod - 1);
IncomingKeys inCurr = new IncomingKeys(inTagCurr, inHeaderCurr, IncomingKeys inCurr = new IncomingKeys(inTagCurr, inHeaderCurr,
rotationPeriod); timePeriod);
IncomingKeys inNext = new IncomingKeys(inTagNext, inHeaderNext, IncomingKeys inNext = new IncomingKeys(inTagNext, inHeaderNext,
rotationPeriod + 1); timePeriod + 1);
OutgoingKeys outCurr = new OutgoingKeys(outTagCurr, outHeaderCurr, OutgoingKeys outCurr = new OutgoingKeys(outTagCurr, outHeaderCurr,
rotationPeriod, active); timePeriod, active);
// Collect and return the keys // Collect and return the keys
return new TransportKeys(t, inPrev, inCurr, inNext, outCurr); return new TransportKeys(t, inPrev, inCurr, inNext, outCurr);
} }
@Override @Override
public TransportKeys rotateTransportKeys(TransportKeys k, public TransportKeys rotateTransportKeys(TransportKeys k,
long rotationPeriod) { long timePeriod) {
if (k.getRotationPeriod() >= rotationPeriod) return k; if (k.getTimePeriod() >= timePeriod) return k;
IncomingKeys inPrev = k.getPreviousIncomingKeys(); IncomingKeys inPrev = k.getPreviousIncomingKeys();
IncomingKeys inCurr = k.getCurrentIncomingKeys(); IncomingKeys inCurr = k.getCurrentIncomingKeys();
IncomingKeys inNext = k.getNextIncomingKeys(); IncomingKeys inNext = k.getNextIncomingKeys();
OutgoingKeys outCurr = k.getCurrentOutgoingKeys(); OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
long startPeriod = outCurr.getRotationPeriod(); long startPeriod = outCurr.getTimePeriod();
boolean active = outCurr.isActive(); boolean active = outCurr.isActive();
// Rotate the keys // Rotate the keys
for (long p = startPeriod + 1; p <= rotationPeriod; p++) { for (long p = startPeriod + 1; p <= timePeriod; p++) {
inPrev = inCurr; inPrev = inCurr;
inCurr = inNext; inCurr = inNext;
SecretKey inNextTag = rotateKey(inNext.getTagKey(), p + 1); SecretKey inNextTag = rotateKey(inNext.getTagKey(), p + 1);
@@ -89,9 +88,9 @@ class TransportCryptoImpl implements TransportCrypto {
outCurr); outCurr);
} }
private SecretKey rotateKey(SecretKey k, long rotationPeriod) { private SecretKey rotateKey(SecretKey k, long timePeriod) {
byte[] period = new byte[INT_64_BYTES]; byte[] period = new byte[INT_64_BYTES];
ByteUtils.writeUint64(rotationPeriod, period, 0); ByteUtils.writeUint64(timePeriod, period, 0);
return crypto.deriveKey(ROTATE_LABEL, k, period); return crypto.deriveKey(ROTATE_LABEL, k, period);
} }

View File

@@ -635,10 +635,10 @@ interface Database<T> {
/** /**
* Sets the reordering window for the given key set and transport in the * Sets the reordering window for the given key set and transport in the
* given rotation period. * given time period.
*/ */
void setReorderingWindow(T txn, KeySetId k, TransportId t, void setReorderingWindow(T txn, KeySetId k, TransportId t,
long rotationPeriod, long base, byte[] bitmap) throws DbException; long timePeriod, long base, byte[] bitmap) throws DbException;
/** /**
* Marks the given transport keys as usable for outgoing streams. * Marks the given transport keys as usable for outgoing streams.

View File

@@ -956,13 +956,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
@Override @Override
public void setReorderingWindow(Transaction transaction, KeySetId k, public void setReorderingWindow(Transaction transaction, KeySetId k,
TransportId t, long rotationPeriod, long base, byte[] bitmap) TransportId t, long timePeriod, long base, byte[] bitmap)
throws DbException { throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException(); if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsTransport(txn, t)) if (!db.containsTransport(txn, t))
throw new NoSuchTransportException(); throw new NoSuchTransportException();
db.setReorderingWindow(txn, k, t, rotationPeriod, base, bitmap); db.setReorderingWindow(txn, k, t, timePeriod, base, bitmap);
} }
@Override @Override

View File

@@ -85,9 +85,9 @@ import static org.briarproject.bramble.util.LogUtils.now;
abstract class JdbcDatabase implements Database<Connection> { abstract class JdbcDatabase implements Database<Connection> {
// Package access for testing // Package access for testing
static final int CODE_SCHEMA_VERSION = 41; static final int CODE_SCHEMA_VERSION = 42;
// Rotation period offsets for incoming transport keys // Time period offsets for incoming transport keys
private static final int OFFSET_PREV = -1; private static final int OFFSET_PREV = -1;
private static final int OFFSET_CURR = 0; private static final int OFFSET_CURR = 0;
private static final int OFFSET_NEXT = 1; private static final int OFFSET_NEXT = 1;
@@ -248,7 +248,7 @@ abstract class JdbcDatabase implements Database<Connection> {
"CREATE TABLE outgoingKeys" "CREATE TABLE outgoingKeys"
+ " (transportId _STRING NOT NULL," + " (transportId _STRING NOT NULL,"
+ " keySetId _COUNTER," + " keySetId _COUNTER,"
+ " rotationPeriod BIGINT NOT NULL," + " timePeriod BIGINT NOT NULL,"
+ " contactId INT NOT NULL," + " contactId INT NOT NULL,"
+ " tagKey _SECRET NOT NULL," + " tagKey _SECRET NOT NULL,"
+ " headerKey _SECRET NOT NULL," + " headerKey _SECRET NOT NULL,"
@@ -267,8 +267,7 @@ abstract class JdbcDatabase implements Database<Connection> {
"CREATE TABLE incomingKeys" "CREATE TABLE incomingKeys"
+ " (transportId _STRING NOT NULL," + " (transportId _STRING NOT NULL,"
+ " keySetId INT NOT NULL," + " keySetId INT NOT NULL,"
+ " rotationPeriod BIGINT NOT NULL," + " timePeriod BIGINT NOT NULL,"
+ " contactId INT NOT NULL,"
+ " tagKey _SECRET NOT NULL," + " tagKey _SECRET NOT NULL,"
+ " headerKey _SECRET NOT NULL," + " headerKey _SECRET NOT NULL,"
+ " base BIGINT NOT NULL," + " base BIGINT NOT NULL,"
@@ -280,9 +279,49 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " ON DELETE CASCADE," + " ON DELETE CASCADE,"
+ " FOREIGN KEY (keySetId)" + " FOREIGN KEY (keySetId)"
+ " REFERENCES outgoingKeys (keySetId)" + " REFERENCES outgoingKeys (keySetId)"
+ " ON DELETE CASCADE)";
private static final String CREATE_PENDING_CONTACTS =
"CREATE TABLE pendingContacts"
+ " (pendingContactId _HASH NOT NULL,"
+ " PRIMARY KEY (pendingContactId))";
private static final String CREATE_OUTGOING_STATIC_KEYS =
"CREATE TABLE outgoingStaticKeys"
+ " (transportId _STRING NOT NULL,"
+ " staticKeySetId _COUNTER,"
+ " rootKey _SECRET NOT NULL,"
+ " timePeriod BIGINT NOT NULL,"
+ " stream BIGINT NOT NULL,"
+ " contactId INT," // Null if contact is pending
+ " pendingContactId _HASH," // Null if not pending
+ " PRIMARY KEY (transportId, staticKeySetId),"
+ " FOREIGN KEY (transportId)"
+ " REFERENCES transports (transportId)"
+ " ON DELETE CASCADE," + " ON DELETE CASCADE,"
+ " UNIQUE (staticKeySetId),"
+ " FOREIGN KEY (contactId)" + " FOREIGN KEY (contactId)"
+ " REFERENCES contacts (contactId)" + " REFERENCES contacts (contactId)"
+ " ON DELETE CASCADE,"
+ " FOREIGN KEY (pendingContactId)"
+ " REFERENCES pendingContacts (pendingContactId)"
+ " ON DELETE CASCADE)";
private static final String CREATE_INCOMING_STATIC_KEYS =
"CREATE TABLE incomingStaticKeys"
+ " (transportId _STRING NOT NULL,"
+ " staticKeySetId INT NOT NULL,"
+ " timePeriod BIGINT NOT NULL,"
+ " base BIGINT NOT NULL,"
+ " bitmap _BINARY NOT NULL,"
+ " periodOffset INT NOT NULL,"
+ " PRIMARY KEY (transportId, staticKeySetId,"
+ " periodOffset),"
+ " FOREIGN KEY (transportId)"
+ " REFERENCES transports (transportId)"
+ " ON DELETE CASCADE,"
+ " FOREIGN KEY (staticKeySetId)"
+ " REFERENCES outgoingStaticKeys (staticKeySetId)"
+ " ON DELETE CASCADE)"; + " ON DELETE CASCADE)";
private static final String INDEX_CONTACTS_BY_AUTHOR_ID = private static final String INDEX_CONTACTS_BY_AUTHOR_ID =
@@ -428,7 +467,8 @@ abstract class JdbcDatabase implements Database<Connection> {
return Arrays.asList( return Arrays.asList(
new Migration38_39(), new Migration38_39(),
new Migration39_40(), new Migration39_40(),
new Migration40_41(dbTypes) new Migration40_41(dbTypes),
new Migration41_42(dbTypes)
); );
} }
@@ -478,6 +518,9 @@ abstract class JdbcDatabase implements Database<Connection> {
s.executeUpdate(dbTypes.replaceTypes(CREATE_TRANSPORTS)); s.executeUpdate(dbTypes.replaceTypes(CREATE_TRANSPORTS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_OUTGOING_KEYS)); s.executeUpdate(dbTypes.replaceTypes(CREATE_OUTGOING_KEYS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_KEYS)); s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_KEYS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_PENDING_CONTACTS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_OUTGOING_STATIC_KEYS));
s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_STATIC_KEYS));
s.close(); s.close();
} catch (SQLException e) { } catch (SQLException e) {
tryToClose(s, LOG, WARNING); tryToClose(s, LOG, WARNING);
@@ -922,13 +965,13 @@ abstract class JdbcDatabase implements Database<Connection> {
try { try {
// Store the outgoing keys // Store the outgoing keys
String sql = "INSERT INTO outgoingKeys (contactId, transportId," String sql = "INSERT INTO outgoingKeys (contactId, transportId,"
+ " rotationPeriod, tagKey, headerKey, stream, active)" + " timePeriod, tagKey, headerKey, stream, active)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt()); ps.setInt(1, c.getInt());
ps.setString(2, k.getTransportId().getString()); ps.setString(2, k.getTransportId().getString());
OutgoingKeys outCurr = k.getCurrentOutgoingKeys(); OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
ps.setLong(3, outCurr.getRotationPeriod()); ps.setLong(3, outCurr.getTimePeriod());
ps.setBytes(4, outCurr.getTagKey().getBytes()); ps.setBytes(4, outCurr.getTagKey().getBytes());
ps.setBytes(5, outCurr.getHeaderKey().getBytes()); ps.setBytes(5, outCurr.getHeaderKey().getBytes());
ps.setLong(6, outCurr.getStreamCounter()); ps.setLong(6, outCurr.getStreamCounter());
@@ -947,40 +990,39 @@ abstract class JdbcDatabase implements Database<Connection> {
rs.close(); rs.close();
ps.close(); ps.close();
// Store the incoming keys // Store the incoming keys
sql = "INSERT INTO incomingKeys (keySetId, contactId, transportId," sql = "INSERT INTO incomingKeys (keySetId, transportId,"
+ " rotationPeriod, tagKey, headerKey, base, bitmap," + " timePeriod, tagKey, headerKey, base, bitmap,"
+ " periodOffset)" + " periodOffset)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setInt(1, keySetId.getInt()); ps.setInt(1, keySetId.getInt());
ps.setInt(2, c.getInt()); ps.setString(2, k.getTransportId().getString());
ps.setString(3, k.getTransportId().getString()); // Previous time period
// Previous rotation period
IncomingKeys inPrev = k.getPreviousIncomingKeys(); IncomingKeys inPrev = k.getPreviousIncomingKeys();
ps.setLong(4, inPrev.getRotationPeriod()); ps.setLong(3, inPrev.getTimePeriod());
ps.setBytes(5, inPrev.getTagKey().getBytes()); ps.setBytes(4, inPrev.getTagKey().getBytes());
ps.setBytes(6, inPrev.getHeaderKey().getBytes()); ps.setBytes(5, inPrev.getHeaderKey().getBytes());
ps.setLong(7, inPrev.getWindowBase()); ps.setLong(6, inPrev.getWindowBase());
ps.setBytes(8, inPrev.getWindowBitmap()); ps.setBytes(7, inPrev.getWindowBitmap());
ps.setInt(9, OFFSET_PREV); ps.setInt(8, OFFSET_PREV);
ps.addBatch(); ps.addBatch();
// Current rotation period // Current time period
IncomingKeys inCurr = k.getCurrentIncomingKeys(); IncomingKeys inCurr = k.getCurrentIncomingKeys();
ps.setLong(4, inCurr.getRotationPeriod()); ps.setLong(3, inCurr.getTimePeriod());
ps.setBytes(5, inCurr.getTagKey().getBytes()); ps.setBytes(4, inCurr.getTagKey().getBytes());
ps.setBytes(6, inCurr.getHeaderKey().getBytes()); ps.setBytes(5, inCurr.getHeaderKey().getBytes());
ps.setLong(7, inCurr.getWindowBase()); ps.setLong(6, inCurr.getWindowBase());
ps.setBytes(8, inCurr.getWindowBitmap()); ps.setBytes(7, inCurr.getWindowBitmap());
ps.setInt(9, OFFSET_CURR); ps.setInt(8, OFFSET_CURR);
ps.addBatch(); ps.addBatch();
// Next rotation period // Next time period
IncomingKeys inNext = k.getNextIncomingKeys(); IncomingKeys inNext = k.getNextIncomingKeys();
ps.setLong(4, inNext.getRotationPeriod()); ps.setLong(3, inNext.getTimePeriod());
ps.setBytes(5, inNext.getTagKey().getBytes()); ps.setBytes(4, inNext.getTagKey().getBytes());
ps.setBytes(6, inNext.getHeaderKey().getBytes()); ps.setBytes(5, inNext.getHeaderKey().getBytes());
ps.setLong(7, inNext.getWindowBase()); ps.setLong(6, inNext.getWindowBase());
ps.setBytes(8, inNext.getWindowBitmap()); ps.setBytes(7, inNext.getWindowBitmap());
ps.setInt(9, OFFSET_NEXT); ps.setInt(8, OFFSET_NEXT);
ps.addBatch(); ps.addBatch();
int[] batchAffected = ps.executeBatch(); int[] batchAffected = ps.executeBatch();
if (batchAffected.length != 3) throw new DbStateException(); if (batchAffected.length != 3) throw new DbStateException();
@@ -2155,8 +2197,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ResultSet rs = null; ResultSet rs = null;
try { try {
// Retrieve the incoming keys // Retrieve the incoming keys
String sql = "SELECT rotationPeriod, tagKey, headerKey," String sql = "SELECT timePeriod, tagKey, headerKey, base, bitmap"
+ " base, bitmap"
+ " FROM incomingKeys" + " FROM incomingKeys"
+ " WHERE transportId = ?" + " WHERE transportId = ?"
+ " ORDER BY keySetId, periodOffset"; + " ORDER BY keySetId, periodOffset";
@@ -2165,18 +2206,18 @@ abstract class JdbcDatabase implements Database<Connection> {
rs = ps.executeQuery(); rs = ps.executeQuery();
List<IncomingKeys> inKeys = new ArrayList<>(); List<IncomingKeys> inKeys = new ArrayList<>();
while (rs.next()) { while (rs.next()) {
long rotationPeriod = rs.getLong(1); long timePeriod = rs.getLong(1);
SecretKey tagKey = new SecretKey(rs.getBytes(2)); SecretKey tagKey = new SecretKey(rs.getBytes(2));
SecretKey headerKey = new SecretKey(rs.getBytes(3)); SecretKey headerKey = new SecretKey(rs.getBytes(3));
long windowBase = rs.getLong(4); long windowBase = rs.getLong(4);
byte[] windowBitmap = rs.getBytes(5); byte[] windowBitmap = rs.getBytes(5);
inKeys.add(new IncomingKeys(tagKey, headerKey, rotationPeriod, inKeys.add(new IncomingKeys(tagKey, headerKey, timePeriod,
windowBase, windowBitmap)); windowBase, windowBitmap));
} }
rs.close(); rs.close();
ps.close(); ps.close();
// Retrieve the outgoing keys in the same order // Retrieve the outgoing keys in the same order
sql = "SELECT keySetId, contactId, rotationPeriod," sql = "SELECT keySetId, contactId, timePeriod,"
+ " tagKey, headerKey, stream, active" + " tagKey, headerKey, stream, active"
+ " FROM outgoingKeys" + " FROM outgoingKeys"
+ " WHERE transportId = ?" + " WHERE transportId = ?"
@@ -2190,13 +2231,13 @@ abstract class JdbcDatabase implements Database<Connection> {
if (inKeys.size() < (i + 1) * 3) throw new DbStateException(); if (inKeys.size() < (i + 1) * 3) throw new DbStateException();
KeySetId keySetId = new KeySetId(rs.getInt(1)); KeySetId keySetId = new KeySetId(rs.getInt(1));
ContactId contactId = new ContactId(rs.getInt(2)); ContactId contactId = new ContactId(rs.getInt(2));
long rotationPeriod = rs.getLong(3); long timePeriod = rs.getLong(3);
SecretKey tagKey = new SecretKey(rs.getBytes(4)); SecretKey tagKey = new SecretKey(rs.getBytes(4));
SecretKey headerKey = new SecretKey(rs.getBytes(5)); SecretKey headerKey = new SecretKey(rs.getBytes(5));
long streamCounter = rs.getLong(6); long streamCounter = rs.getLong(6);
boolean active = rs.getBoolean(7); boolean active = rs.getBoolean(7);
OutgoingKeys outCurr = new OutgoingKeys(tagKey, headerKey, OutgoingKeys outCurr = new OutgoingKeys(tagKey, headerKey,
rotationPeriod, streamCounter, active); timePeriod, streamCounter, active);
IncomingKeys inPrev = inKeys.get(i * 3); IncomingKeys inPrev = inKeys.get(i * 3);
IncomingKeys inCurr = inKeys.get(i * 3 + 1); IncomingKeys inCurr = inKeys.get(i * 3 + 1);
IncomingKeys inNext = inKeys.get(i * 3 + 2); IncomingKeys inNext = inKeys.get(i * 3 + 2);
@@ -2894,18 +2935,18 @@ abstract class JdbcDatabase implements Database<Connection> {
@Override @Override
public void setReorderingWindow(Connection txn, KeySetId k, TransportId t, public void setReorderingWindow(Connection txn, KeySetId k, TransportId t,
long rotationPeriod, long base, byte[] bitmap) throws DbException { long timePeriod, long base, byte[] bitmap) throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
String sql = "UPDATE incomingKeys SET base = ?, bitmap = ?" String sql = "UPDATE incomingKeys SET base = ?, bitmap = ?"
+ " WHERE transportId = ? AND keySetId = ?" + " WHERE transportId = ? AND keySetId = ?"
+ " AND rotationPeriod = ?"; + " AND timePeriod = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setLong(1, base); ps.setLong(1, base);
ps.setBytes(2, bitmap); ps.setBytes(2, bitmap);
ps.setString(3, t.getString()); ps.setString(3, t.getString());
ps.setInt(4, k.getInt()); ps.setInt(4, k.getInt());
ps.setLong(5, rotationPeriod); ps.setLong(5, timePeriod);
int affected = ps.executeUpdate(); int affected = ps.executeUpdate();
if (affected < 0 || affected > 1) throw new DbStateException(); if (affected < 0 || affected > 1) throw new DbStateException();
ps.close(); ps.close();
@@ -2977,13 +3018,13 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
// Update the outgoing keys // Update the outgoing keys
String sql = "UPDATE outgoingKeys SET rotationPeriod = ?," String sql = "UPDATE outgoingKeys SET timePeriod = ?,"
+ " tagKey = ?, headerKey = ?, stream = ?" + " tagKey = ?, headerKey = ?, stream = ?"
+ " WHERE transportId = ? AND keySetId = ?"; + " WHERE transportId = ? AND keySetId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
TransportKeys k = ks.getTransportKeys(); TransportKeys k = ks.getTransportKeys();
OutgoingKeys outCurr = k.getCurrentOutgoingKeys(); OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
ps.setLong(1, outCurr.getRotationPeriod()); ps.setLong(1, outCurr.getTimePeriod());
ps.setBytes(2, outCurr.getTagKey().getBytes()); ps.setBytes(2, outCurr.getTagKey().getBytes());
ps.setBytes(3, outCurr.getHeaderKey().getBytes()); ps.setBytes(3, outCurr.getHeaderKey().getBytes());
ps.setLong(4, outCurr.getStreamCounter()); ps.setLong(4, outCurr.getStreamCounter());
@@ -2993,34 +3034,34 @@ abstract class JdbcDatabase implements Database<Connection> {
if (affected < 0 || affected > 1) throw new DbStateException(); if (affected < 0 || affected > 1) throw new DbStateException();
ps.close(); ps.close();
// Update the incoming keys // Update the incoming keys
sql = "UPDATE incomingKeys SET rotationPeriod = ?," sql = "UPDATE incomingKeys SET timePeriod = ?,"
+ " tagKey = ?, headerKey = ?, base = ?, bitmap = ?" + " tagKey = ?, headerKey = ?, base = ?, bitmap = ?"
+ " WHERE transportId = ? AND keySetId = ?" + " WHERE transportId = ? AND keySetId = ?"
+ " AND periodOffset = ?"; + " AND periodOffset = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setString(6, k.getTransportId().getString()); ps.setString(6, k.getTransportId().getString());
ps.setInt(7, ks.getKeySetId().getInt()); ps.setInt(7, ks.getKeySetId().getInt());
// Previous rotation period // Previous time period
IncomingKeys inPrev = k.getPreviousIncomingKeys(); IncomingKeys inPrev = k.getPreviousIncomingKeys();
ps.setLong(1, inPrev.getRotationPeriod()); ps.setLong(1, inPrev.getTimePeriod());
ps.setBytes(2, inPrev.getTagKey().getBytes()); ps.setBytes(2, inPrev.getTagKey().getBytes());
ps.setBytes(3, inPrev.getHeaderKey().getBytes()); ps.setBytes(3, inPrev.getHeaderKey().getBytes());
ps.setLong(4, inPrev.getWindowBase()); ps.setLong(4, inPrev.getWindowBase());
ps.setBytes(5, inPrev.getWindowBitmap()); ps.setBytes(5, inPrev.getWindowBitmap());
ps.setInt(8, OFFSET_PREV); ps.setInt(8, OFFSET_PREV);
ps.addBatch(); ps.addBatch();
// Current rotation period // Current time period
IncomingKeys inCurr = k.getCurrentIncomingKeys(); IncomingKeys inCurr = k.getCurrentIncomingKeys();
ps.setLong(1, inCurr.getRotationPeriod()); ps.setLong(1, inCurr.getTimePeriod());
ps.setBytes(2, inCurr.getTagKey().getBytes()); ps.setBytes(2, inCurr.getTagKey().getBytes());
ps.setBytes(3, inCurr.getHeaderKey().getBytes()); ps.setBytes(3, inCurr.getHeaderKey().getBytes());
ps.setLong(4, inCurr.getWindowBase()); ps.setLong(4, inCurr.getWindowBase());
ps.setBytes(5, inCurr.getWindowBitmap()); ps.setBytes(5, inCurr.getWindowBitmap());
ps.setInt(8, OFFSET_CURR); ps.setInt(8, OFFSET_CURR);
ps.addBatch(); ps.addBatch();
// Next rotation period // Next time period
IncomingKeys inNext = k.getNextIncomingKeys(); IncomingKeys inNext = k.getNextIncomingKeys();
ps.setLong(1, inNext.getRotationPeriod()); ps.setLong(1, inNext.getTimePeriod());
ps.setBytes(2, inNext.getTagKey().getBytes()); ps.setBytes(2, inNext.getTagKey().getBytes());
ps.setBytes(3, inNext.getHeaderKey().getBytes()); ps.setBytes(3, inNext.getHeaderKey().getBytes());
ps.setLong(4, inNext.getWindowBase()); ps.setLong(4, inNext.getWindowBase());

View File

@@ -17,7 +17,7 @@ class Migration40_41 implements Migration<Connection> {
private final DatabaseTypes dbTypes; private final DatabaseTypes dbTypes;
public Migration40_41(DatabaseTypes databaseTypes) { Migration40_41(DatabaseTypes databaseTypes) {
this.dbTypes = databaseTypes; this.dbTypes = databaseTypes;
} }

View File

@@ -0,0 +1,89 @@
package org.briarproject.bramble.db;
import org.briarproject.bramble.api.db.DbException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
class Migration41_42 implements Migration<Connection> {
private static final Logger LOG = getLogger(Migration41_42.class.getName());
private final DatabaseTypes dbTypes;
Migration41_42(DatabaseTypes dbTypes) {
this.dbTypes = dbTypes;
}
@Override
public int getStartVersion() {
return 41;
}
@Override
public int getEndVersion() {
return 42;
}
@Override
public void migrate(Connection txn) throws DbException {
Statement s = null;
try {
s = txn.createStatement();
s.execute("ALTER TABLE outgoingKeys"
+ " ALTER COLUMN rotationPeriod"
+ " RENAME TO timePeriod");
s.execute("ALTER TABLE incomingKeys"
+ " ALTER COLUMN rotationPeriod"
+ " RENAME TO timePeriod");
s.execute("ALTER TABLE incomingKeys"
+ " DROP COLUMN contactId");
s.execute(dbTypes.replaceTypes("CREATE TABLE pendingContacts"
+ " (pendingContactId _HASH NOT NULL,"
+ " PRIMARY KEY (pendingContactId))"));
s.execute(dbTypes.replaceTypes("CREATE TABLE outgoingStaticKeys"
+ " (transportId _STRING NOT NULL,"
+ " staticKeySetId _COUNTER,"
+ " rootKey _SECRET NOT NULL,"
+ " timePeriod BIGINT NOT NULL,"
+ " stream BIGINT NOT NULL,"
+ " contactId INT," // Null if contact is pending
+ " pendingContactId _HASH," // Null if not pending
+ " PRIMARY KEY (transportId, staticKeySetId),"
+ " FOREIGN KEY (transportId)"
+ " REFERENCES transports (transportId)"
+ " ON DELETE CASCADE,"
+ " UNIQUE (staticKeySetId),"
+ " FOREIGN KEY (contactId)"
+ " REFERENCES contacts (contactId)"
+ " ON DELETE CASCADE,"
+ " FOREIGN KEY (pendingContactId)"
+ " REFERENCES pendingContacts (pendingContactId)"
+ " ON DELETE CASCADE)"));
s.execute(dbTypes.replaceTypes("CREATE TABLE incomingStaticKeys"
+ " (transportId _STRING NOT NULL,"
+ " staticKeySetId INT NOT NULL,"
+ " timePeriod BIGINT NOT NULL,"
+ " base BIGINT NOT NULL,"
+ " bitmap _BINARY NOT NULL,"
+ " periodOffset INT NOT NULL,"
+ " PRIMARY KEY (transportId, staticKeySetId,"
+ " periodOffset),"
+ " FOREIGN KEY (transportId)"
+ " REFERENCES transports (transportId)"
+ " ON DELETE CASCADE,"
+ " FOREIGN KEY (staticKeySetId)"
+ " REFERENCES outgoingStaticKeys (staticKeySetId)"
+ " ON DELETE CASCADE)"));
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
throw new DbException(e);
}
}
}

View File

@@ -11,18 +11,18 @@ import javax.annotation.concurrent.NotThreadSafe;
class MutableIncomingKeys { class MutableIncomingKeys {
private final SecretKey tagKey, headerKey; private final SecretKey tagKey, headerKey;
private final long rotationPeriod; private final long timePeriod;
private final ReorderingWindow window; private final ReorderingWindow window;
MutableIncomingKeys(IncomingKeys in) { MutableIncomingKeys(IncomingKeys in) {
tagKey = in.getTagKey(); tagKey = in.getTagKey();
headerKey = in.getHeaderKey(); headerKey = in.getHeaderKey();
rotationPeriod = in.getRotationPeriod(); timePeriod = in.getTimePeriod();
window = new ReorderingWindow(in.getWindowBase(), in.getWindowBitmap()); window = new ReorderingWindow(in.getWindowBase(), in.getWindowBitmap());
} }
IncomingKeys snapshot() { IncomingKeys snapshot() {
return new IncomingKeys(tagKey, headerKey, rotationPeriod, return new IncomingKeys(tagKey, headerKey, timePeriod,
window.getBase(), window.getBitmap()); window.getBase(), window.getBitmap());
} }
@@ -34,8 +34,8 @@ class MutableIncomingKeys {
return headerKey; return headerKey;
} }
long getRotationPeriod() { long getTimePeriod() {
return rotationPeriod; return timePeriod;
} }
ReorderingWindow getWindow() { ReorderingWindow getWindow() {

View File

@@ -11,20 +11,20 @@ import javax.annotation.concurrent.NotThreadSafe;
class MutableOutgoingKeys { class MutableOutgoingKeys {
private final SecretKey tagKey, headerKey; private final SecretKey tagKey, headerKey;
private final long rotationPeriod; private final long timePeriod;
private long streamCounter; private long streamCounter;
private boolean active; private boolean active;
MutableOutgoingKeys(OutgoingKeys out) { MutableOutgoingKeys(OutgoingKeys out) {
tagKey = out.getTagKey(); tagKey = out.getTagKey();
headerKey = out.getHeaderKey(); headerKey = out.getHeaderKey();
rotationPeriod = out.getRotationPeriod(); timePeriod = out.getTimePeriod();
streamCounter = out.getStreamCounter(); streamCounter = out.getStreamCounter();
active = out.isActive(); active = out.isActive();
} }
OutgoingKeys snapshot() { OutgoingKeys snapshot() {
return new OutgoingKeys(tagKey, headerKey, rotationPeriod, return new OutgoingKeys(tagKey, headerKey, timePeriod,
streamCounter, active); streamCounter, active);
} }
@@ -36,8 +36,8 @@ class MutableOutgoingKeys {
return headerKey; return headerKey;
} }
long getRotationPeriod() { long getTimePeriod() {
return rotationPeriod; return timePeriod;
} }
long getStreamCounter() { long getStreamCounter() {

View File

@@ -51,7 +51,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
private final ScheduledExecutorService scheduler; private final ScheduledExecutorService scheduler;
private final Clock clock; private final Clock clock;
private final TransportId transportId; private final TransportId transportId;
private final long rotationPeriodLength; private final long timePeriodLength;
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
private final ReentrantLock lock = new ReentrantLock(); private final ReentrantLock lock = new ReentrantLock();
@@ -70,7 +70,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
this.scheduler = scheduler; this.scheduler = scheduler;
this.clock = clock; this.clock = clock;
this.transportId = transportId; this.transportId = transportId;
rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE; timePeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
} }
@Override @Override
@@ -81,7 +81,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
try { try {
// Load the transport keys from the DB // Load the transport keys from the DB
Collection<KeySet> loaded = db.getTransportKeys(txn, transportId); Collection<KeySet> loaded = db.getTransportKeys(txn, transportId);
// Rotate the keys to the current rotation period // Rotate the keys to the current time period
RotationResult rotationResult = rotateKeys(loaded, now); RotationResult rotationResult = rotateKeys(loaded, now);
// Initialise mutable state for all contacts // Initialise mutable state for all contacts
addKeys(rotationResult.current); addKeys(rotationResult.current);
@@ -97,13 +97,13 @@ class TransportKeyManagerImpl implements TransportKeyManager {
private RotationResult rotateKeys(Collection<KeySet> keys, long now) { private RotationResult rotateKeys(Collection<KeySet> keys, long now) {
RotationResult rotationResult = new RotationResult(); RotationResult rotationResult = new RotationResult();
long rotationPeriod = now / rotationPeriodLength; long timePeriod = now / timePeriodLength;
for (KeySet ks : keys) { for (KeySet ks : keys) {
TransportKeys k = ks.getTransportKeys(); TransportKeys k = ks.getTransportKeys();
TransportKeys k1 = TransportKeys k1 =
transportCrypto.rotateTransportKeys(k, rotationPeriod); transportCrypto.rotateTransportKeys(k, timePeriod);
KeySet ks1 = new KeySet(ks.getKeySetId(), ks.getContactId(), k1); KeySet ks1 = new KeySet(ks.getKeySetId(), ks.getContactId(), k1);
if (k1.getRotationPeriod() > k.getRotationPeriod()) if (k1.getTimePeriod() > k.getTimePeriod())
rotationResult.rotated.add(ks1); rotationResult.rotated.add(ks1);
rotationResult.current.add(ks1); rotationResult.current.add(ks1);
} }
@@ -155,7 +155,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
} }
private void scheduleKeyRotation(long now) { private void scheduleKeyRotation(long now) {
long delay = rotationPeriodLength - now % rotationPeriodLength; long delay = timePeriodLength - now % timePeriodLength;
scheduler.schedule((Runnable) this::rotateKeys, delay, MILLISECONDS); scheduler.schedule((Runnable) this::rotateKeys, delay, MILLISECONDS);
} }
@@ -174,14 +174,14 @@ class TransportKeyManagerImpl implements TransportKeyManager {
long timestamp, boolean alice, boolean active) throws DbException { long timestamp, boolean alice, boolean active) throws DbException {
lock.lock(); lock.lock();
try { try {
// Work out what rotation period the timestamp belongs to // Work out what time period the timestamp belongs to
long rotationPeriod = timestamp / rotationPeriodLength; long timePeriod = timestamp / timePeriodLength;
// Derive the transport keys // Derive the transport keys
TransportKeys k = transportCrypto.deriveTransportKeys(transportId, TransportKeys k = transportCrypto.deriveTransportKeys(transportId,
master, rotationPeriod, alice, active); master, timePeriod, alice, active);
// Rotate the keys to the current rotation period if necessary // Rotate the keys to the current time period if necessary
rotationPeriod = clock.currentTimeMillis() / rotationPeriodLength; timePeriod = clock.currentTimeMillis() / timePeriodLength;
k = transportCrypto.rotateTransportKeys(k, rotationPeriod); k = transportCrypto.rotateTransportKeys(k, timePeriod);
// Write the keys back to the DB // Write the keys back to the DB
KeySetId keySetId = db.addTransportKeys(txn, c, k); KeySetId keySetId = db.addTransportKeys(txn, c, k);
// Initialise mutable state for the contact // Initialise mutable state for the contact
@@ -300,7 +300,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
} }
// Write the window back to the DB // Write the window back to the DB
db.setReorderingWindow(txn, tagCtx.keySetId, transportId, db.setReorderingWindow(txn, tagCtx.keySetId, transportId,
inKeys.getRotationPeriod(), window.getBase(), inKeys.getTimePeriod(), window.getBase(),
window.getBitmap()); window.getBitmap());
// If the outgoing keys are inactive, activate them // If the outgoing keys are inactive, activate them
MutableKeySet ks = keys.get(tagCtx.keySetId); MutableKeySet ks = keys.get(tagCtx.keySetId);
@@ -322,7 +322,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
long now = clock.currentTimeMillis(); long now = clock.currentTimeMillis();
lock.lock(); lock.lock();
try { try {
// Rotate the keys to the current rotation period // Rotate the keys to the current time period
Collection<KeySet> snapshot = new ArrayList<>(keys.size()); Collection<KeySet> snapshot = new ArrayList<>(keys.size());
for (MutableKeySet ks : keys.values()) { for (MutableKeySet ks : keys.values()) {
snapshot.add(new KeySet(ks.getKeySetId(), ks.getContactId(), snapshot.add(new KeySet(ks.getKeySetId(), ks.getContactId(),

View File

@@ -40,7 +40,7 @@ public class KeyDerivationTest extends BrambleTestCase {
@Test @Test
public void testCurrentKeysMatchCurrentKeysOfContact() { public void testCurrentKeysMatchCurrentKeysOfContact() {
// Start in rotation period 123 // Start in time period 123
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId, TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); master, 123, true, true);
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId, TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
@@ -72,7 +72,7 @@ public class KeyDerivationTest extends BrambleTestCase {
@Test @Test
public void testPreviousKeysMatchPreviousKeysOfContact() { public void testPreviousKeysMatchPreviousKeysOfContact() {
// Start in rotation period 123 // Start in time period 123
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId, TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); master, 123, true, true);
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId, TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
@@ -99,7 +99,7 @@ public class KeyDerivationTest extends BrambleTestCase {
@Test @Test
public void testNextKeysMatchNextKeysOfContact() { public void testNextKeysMatchNextKeysOfContact() {
// Start in rotation period 123 // Start in time period 123
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId, TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
master, 123, true, true); master, 123, true, true);
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId, TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,

View File

@@ -653,10 +653,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testTransportKeys() throws Exception { public void testTransportKeys() throws Exception {
long rotationPeriod = 123, rotationPeriod1 = 234; long timePeriod = 123, timePeriod1 = 234;
boolean active = random.nextBoolean(); boolean active = random.nextBoolean();
TransportKeys keys = createTransportKeys(rotationPeriod, active); TransportKeys keys = createTransportKeys(timePeriod, active);
TransportKeys keys1 = createTransportKeys(rotationPeriod1, active); TransportKeys keys1 = createTransportKeys(timePeriod1, active);
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
@@ -686,9 +686,9 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
} }
// Rotate the transport keys // Rotate the transport keys
TransportKeys rotated = createTransportKeys(rotationPeriod + 1, active); TransportKeys rotated = createTransportKeys(timePeriod + 1, active);
TransportKeys rotated1 = TransportKeys rotated1 =
createTransportKeys(rotationPeriod1 + 1, active); createTransportKeys(timePeriod1 + 1, active);
db.updateTransportKeys(txn, new KeySet(keySetId, contactId, rotated)); db.updateTransportKeys(txn, new KeySet(keySetId, contactId, rotated));
db.updateTransportKeys(txn, new KeySet(keySetId1, contactId, rotated1)); db.updateTransportKeys(txn, new KeySet(keySetId1, contactId, rotated1));
@@ -716,7 +716,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
private void assertKeysEquals(TransportKeys expected, private void assertKeysEquals(TransportKeys expected,
TransportKeys actual) { TransportKeys actual) {
assertEquals(expected.getTransportId(), actual.getTransportId()); assertEquals(expected.getTransportId(), actual.getTransportId());
assertEquals(expected.getRotationPeriod(), actual.getRotationPeriod()); assertEquals(expected.getTimePeriod(), actual.getTimePeriod());
assertKeysEquals(expected.getPreviousIncomingKeys(), assertKeysEquals(expected.getPreviousIncomingKeys(),
actual.getPreviousIncomingKeys()); actual.getPreviousIncomingKeys());
assertKeysEquals(expected.getCurrentIncomingKeys(), assertKeysEquals(expected.getCurrentIncomingKeys(),
@@ -732,7 +732,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
actual.getTagKey().getBytes()); actual.getTagKey().getBytes());
assertArrayEquals(expected.getHeaderKey().getBytes(), assertArrayEquals(expected.getHeaderKey().getBytes(),
actual.getHeaderKey().getBytes()); actual.getHeaderKey().getBytes());
assertEquals(expected.getRotationPeriod(), actual.getRotationPeriod()); assertEquals(expected.getTimePeriod(), actual.getTimePeriod());
assertEquals(expected.getWindowBase(), actual.getWindowBase()); assertEquals(expected.getWindowBase(), actual.getWindowBase());
assertArrayEquals(expected.getWindowBitmap(), actual.getWindowBitmap()); assertArrayEquals(expected.getWindowBitmap(), actual.getWindowBitmap());
} }
@@ -742,15 +742,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
actual.getTagKey().getBytes()); actual.getTagKey().getBytes());
assertArrayEquals(expected.getHeaderKey().getBytes(), assertArrayEquals(expected.getHeaderKey().getBytes(),
actual.getHeaderKey().getBytes()); actual.getHeaderKey().getBytes());
assertEquals(expected.getRotationPeriod(), actual.getRotationPeriod()); assertEquals(expected.getTimePeriod(), actual.getTimePeriod());
assertEquals(expected.getStreamCounter(), actual.getStreamCounter()); assertEquals(expected.getStreamCounter(), actual.getStreamCounter());
assertEquals(expected.isActive(), actual.isActive()); assertEquals(expected.isActive(), actual.isActive());
} }
@Test @Test
public void testIncrementStreamCounter() throws Exception { public void testIncrementStreamCounter() throws Exception {
long rotationPeriod = 123; long timePeriod = 123;
TransportKeys keys = createTransportKeys(rotationPeriod, true); TransportKeys keys = createTransportKeys(timePeriod, true);
long streamCounter = keys.getCurrentOutgoingKeys().getStreamCounter(); long streamCounter = keys.getCurrentOutgoingKeys().getStreamCounter();
Database<Connection> db = open(false); Database<Connection> db = open(false);
@@ -774,7 +774,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
TransportKeys k = ks.getTransportKeys(); TransportKeys k = ks.getTransportKeys();
assertEquals(transportId, k.getTransportId()); assertEquals(transportId, k.getTransportId());
OutgoingKeys outCurr = k.getCurrentOutgoingKeys(); OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
assertEquals(rotationPeriod, outCurr.getRotationPeriod()); assertEquals(timePeriod, outCurr.getTimePeriod());
assertEquals(streamCounter + 2, outCurr.getStreamCounter()); assertEquals(streamCounter + 2, outCurr.getStreamCounter());
// The rest of the keys should be unaffected // The rest of the keys should be unaffected
@@ -791,8 +791,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
@Test @Test
public void testSetReorderingWindow() throws Exception { public void testSetReorderingWindow() throws Exception {
boolean active = random.nextBoolean(); boolean active = random.nextBoolean();
long rotationPeriod = 123; long timePeriod = 123;
TransportKeys keys = createTransportKeys(rotationPeriod, active); TransportKeys keys = createTransportKeys(timePeriod, active);
long base = keys.getCurrentIncomingKeys().getWindowBase(); long base = keys.getCurrentIncomingKeys().getWindowBase();
byte[] bitmap = keys.getCurrentIncomingKeys().getWindowBitmap(); byte[] bitmap = keys.getCurrentIncomingKeys().getWindowBitmap();
@@ -808,7 +808,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
// Update the reordering window and retrieve the transport keys // Update the reordering window and retrieve the transport keys
random.nextBytes(bitmap); random.nextBytes(bitmap);
db.setReorderingWindow(txn, keySetId, transportId, rotationPeriod, db.setReorderingWindow(txn, keySetId, transportId, timePeriod,
base + 1, bitmap); base + 1, bitmap);
Collection<KeySet> newKeys = db.getTransportKeys(txn, transportId); Collection<KeySet> newKeys = db.getTransportKeys(txn, transportId);
assertEquals(1, newKeys.size()); assertEquals(1, newKeys.size());
@@ -818,7 +818,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
TransportKeys k = ks.getTransportKeys(); TransportKeys k = ks.getTransportKeys();
assertEquals(transportId, k.getTransportId()); assertEquals(transportId, k.getTransportId());
IncomingKeys inCurr = k.getCurrentIncomingKeys(); IncomingKeys inCurr = k.getCurrentIncomingKeys();
assertEquals(rotationPeriod, inCurr.getRotationPeriod()); assertEquals(timePeriod, inCurr.getTimePeriod());
assertEquals(base + 1, inCurr.getWindowBase()); assertEquals(base + 1, inCurr.getWindowBase());
assertArrayEquals(bitmap, inCurr.getWindowBitmap()); assertArrayEquals(bitmap, inCurr.getWindowBitmap());
@@ -1978,24 +1978,23 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
return db; return db;
} }
private TransportKeys createTransportKeys(long rotationPeriod, private TransportKeys createTransportKeys(long timePeriod, boolean active) {
boolean active) {
SecretKey inPrevTagKey = getSecretKey(); SecretKey inPrevTagKey = getSecretKey();
SecretKey inPrevHeaderKey = getSecretKey(); SecretKey inPrevHeaderKey = getSecretKey();
IncomingKeys inPrev = new IncomingKeys(inPrevTagKey, inPrevHeaderKey, IncomingKeys inPrev = new IncomingKeys(inPrevTagKey, inPrevHeaderKey,
rotationPeriod - 1, 123, new byte[4]); timePeriod - 1, 123, new byte[4]);
SecretKey inCurrTagKey = getSecretKey(); SecretKey inCurrTagKey = getSecretKey();
SecretKey inCurrHeaderKey = getSecretKey(); SecretKey inCurrHeaderKey = getSecretKey();
IncomingKeys inCurr = new IncomingKeys(inCurrTagKey, inCurrHeaderKey, IncomingKeys inCurr = new IncomingKeys(inCurrTagKey, inCurrHeaderKey,
rotationPeriod, 234, new byte[4]); timePeriod, 234, new byte[4]);
SecretKey inNextTagKey = getSecretKey(); SecretKey inNextTagKey = getSecretKey();
SecretKey inNextHeaderKey = getSecretKey(); SecretKey inNextHeaderKey = getSecretKey();
IncomingKeys inNext = new IncomingKeys(inNextTagKey, inNextHeaderKey, IncomingKeys inNext = new IncomingKeys(inNextTagKey, inNextHeaderKey,
rotationPeriod + 1, 345, new byte[4]); timePeriod + 1, 345, new byte[4]);
SecretKey outCurrTagKey = getSecretKey(); SecretKey outCurrTagKey = getSecretKey();
SecretKey outCurrHeaderKey = getSecretKey(); SecretKey outCurrHeaderKey = getSecretKey();
OutgoingKeys outCurr = new OutgoingKeys(outCurrTagKey, outCurrHeaderKey, OutgoingKeys outCurr = new OutgoingKeys(outCurrTagKey, outCurrHeaderKey,
rotationPeriod, 456, active); timePeriod, 456, active);
return new TransportKeys(transportId, inPrev, inCurr, inNext, outCurr); return new TransportKeys(transportId, inPrev, inCurr, inNext, outCurr);
} }

View File

@@ -57,7 +57,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
private final TransportId transportId = getTransportId(); private final TransportId transportId = getTransportId();
private final long maxLatency = 30 * 1000; // 30 seconds private final long maxLatency = 30 * 1000; // 30 seconds
private final long rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE; private final long timePeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
private final ContactId contactId = new ContactId(123); private final ContactId contactId = new ContactId(123);
private final ContactId contactId1 = new ContactId(234); private final ContactId contactId1 = new ContactId(234);
private final KeySetId keySetId = new KeySetId(345); private final KeySetId keySetId = new KeySetId(345);
@@ -79,9 +79,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Get the current time (1 ms after start of rotation period 1000) // Get the current time (1 ms after start of time period 1000)
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(rotationPeriodLength * 1000 + 1)); will(returnValue(timePeriodLength * 1000 + 1));
// Load the transport keys // Load the transport keys
oneOf(db).getTransportKeys(txn, transportId); oneOf(db).getTransportKeys(txn, transportId);
will(returnValue(loaded)); will(returnValue(loaded));
@@ -100,9 +100,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// Save the keys that were rotated // Save the keys that were rotated
oneOf(db).updateTransportKeys(txn, oneOf(db).updateTransportKeys(txn,
singletonList(new KeySet(keySetId, contactId, rotated))); singletonList(new KeySet(keySetId, contactId, rotated)));
// Schedule key rotation at the start of the next rotation period // Schedule key rotation at the start of the next time period
oneOf(scheduler).schedule(with(any(Runnable.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength - 1), with(MILLISECONDS)); with(timePeriodLength - 1), with(MILLISECONDS));
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
@@ -123,9 +123,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey,
999, alice, true); 999, alice, true);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (1 ms after start of rotation period 1000) // Get the current time (1 ms after start of time period 1000)
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(rotationPeriodLength * 1000 + 1)); will(returnValue(timePeriodLength * 1000 + 1));
// Rotate the transport keys // Rotate the transport keys
oneOf(transportCrypto).rotateTransportKeys(transportKeys, 1000); oneOf(transportCrypto).rotateTransportKeys(transportKeys, 1000);
will(returnValue(rotated)); will(returnValue(rotated));
@@ -144,8 +144,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId, db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency); maxLatency);
// The timestamp is 1 ms before the start of rotation period 1000 // The timestamp is 1 ms before the start of time period 1000
long timestamp = rotationPeriodLength * 1000 - 1; long timestamp = timePeriodLength * 1000 - 1;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); masterKey, timestamp, alice, true));
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId)); assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
@@ -177,8 +177,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId, db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency); maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of time period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); masterKey, timestamp, alice, true));
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId)); assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));
@@ -203,8 +203,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId, db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency); maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of time period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); masterKey, timestamp, alice, true));
// The first request should return a stream context // The first request should return a stream context
@@ -235,8 +235,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId, db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency); maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of time period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, active)); masterKey, timestamp, alice, active));
assertEquals(active, assertEquals(active,
@@ -259,9 +259,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey,
1000, alice, true); 1000, alice, true);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (the start of rotation period 1000) // Get the current time (the start of time period 1000)
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(rotationPeriodLength * 1000)); will(returnValue(timePeriodLength * 1000));
// Encode the tags (3 sets) // Encode the tags (3 sets)
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) { for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
exactly(3).of(transportCrypto).encodeTag( exactly(3).of(transportCrypto).encodeTag(
@@ -280,7 +280,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
with(tagKey), with(PROTOCOL_VERSION), with(tagKey), with(PROTOCOL_VERSION),
with((long) REORDERING_WINDOW_SIZE)); with((long) REORDERING_WINDOW_SIZE));
will(new EncodeTagAction(tags)); will(new EncodeTagAction(tags));
// Save the reordering window (previous rotation period, base 1) // Save the reordering window (previous time period, base 1)
oneOf(db).setReorderingWindow(txn, keySetId, transportId, 999, oneOf(db).setReorderingWindow(txn, keySetId, transportId, 999,
1, new byte[REORDERING_WINDOW_SIZE / 8]); 1, new byte[REORDERING_WINDOW_SIZE / 8]);
}}); }});
@@ -288,12 +288,12 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId, db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency); maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of time period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, true)); masterKey, timestamp, alice, true));
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId)); assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
// Use the first tag (previous rotation period, stream number 0) // Use the first tag (previous time period, stream number 0)
assertEquals(REORDERING_WINDOW_SIZE * 3, tags.size()); assertEquals(REORDERING_WINDOW_SIZE * 3, tags.size());
byte[] tag = tags.get(0); byte[] tag = tags.get(0);
// The first request should return a stream context // The first request should return a stream context
@@ -320,9 +320,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
Transaction txn1 = new Transaction(null, false); Transaction txn1 = new Transaction(null, false);
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
// Get the current time (the start of rotation period 1000) // Get the current time (the start of time period 1000)
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(rotationPeriodLength * 1000)); will(returnValue(timePeriodLength * 1000));
// Load the transport keys // Load the transport keys
oneOf(db).getTransportKeys(txn, transportId); oneOf(db).getTransportKeys(txn, transportId);
will(returnValue(loaded)); will(returnValue(loaded));
@@ -336,17 +336,17 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
with(PROTOCOL_VERSION), with(i)); with(PROTOCOL_VERSION), with(i));
will(new EncodeTagAction()); will(new EncodeTagAction());
} }
// Schedule key rotation at the start of the next rotation period // Schedule key rotation at the start of the next time period
oneOf(scheduler).schedule(with(any(Runnable.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength), with(MILLISECONDS)); with(timePeriodLength), with(MILLISECONDS));
will(new RunAction()); will(new RunAction());
oneOf(dbExecutor).execute(with(any(Runnable.class))); oneOf(dbExecutor).execute(with(any(Runnable.class)));
will(new RunAction()); will(new RunAction());
// Start a transaction for key rotation // Start a transaction for key rotation
oneOf(db).transaction(with(false), withDbRunnable(txn1)); oneOf(db).transaction(with(false), withDbRunnable(txn1));
// Get the current time (the start of rotation period 1001) // Get the current time (the start of time period 1001)
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(rotationPeriodLength * 1001)); will(returnValue(timePeriodLength * 1001));
// Rotate the transport keys // Rotate the transport keys
oneOf(transportCrypto).rotateTransportKeys( oneOf(transportCrypto).rotateTransportKeys(
with(any(TransportKeys.class)), with(1001L)); with(any(TransportKeys.class)), with(1001L));
@@ -361,9 +361,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
// Save the keys that were rotated // Save the keys that were rotated
oneOf(db).updateTransportKeys(txn1, oneOf(db).updateTransportKeys(txn1,
singletonList(new KeySet(keySetId, contactId, rotated))); singletonList(new KeySet(keySetId, contactId, rotated)));
// Schedule key rotation at the start of the next rotation period // Schedule key rotation at the start of the next time period
oneOf(scheduler).schedule(with(any(Runnable.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength), with(MILLISECONDS)); with(timePeriodLength), with(MILLISECONDS));
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
@@ -391,8 +391,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId, db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency); maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of time period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, false)); masterKey, timestamp, alice, false));
// The keys are inactive so no stream context should be returned // The keys are inactive so no stream context should be returned
@@ -424,9 +424,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey,
1000, alice, false); 1000, alice, false);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (the start of rotation period 1000) // Get the current time (the start of time period 1000)
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(rotationPeriodLength * 1000)); will(returnValue(timePeriodLength * 1000));
// Encode the tags (3 sets) // Encode the tags (3 sets)
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) { for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
exactly(3).of(transportCrypto).encodeTag( exactly(3).of(transportCrypto).encodeTag(
@@ -445,7 +445,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
with(tagKey), with(PROTOCOL_VERSION), with(tagKey), with(PROTOCOL_VERSION),
with((long) REORDERING_WINDOW_SIZE)); with((long) REORDERING_WINDOW_SIZE));
will(new EncodeTagAction(tags)); will(new EncodeTagAction(tags));
// Save the reordering window (previous rotation period, base 1) // Save the reordering window (previous time period, base 1)
oneOf(db).setReorderingWindow(txn, keySetId, transportId, 999, oneOf(db).setReorderingWindow(txn, keySetId, transportId, 999,
1, new byte[REORDERING_WINDOW_SIZE / 8]); 1, new byte[REORDERING_WINDOW_SIZE / 8]);
// Activate the keys // Activate the keys
@@ -457,8 +457,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl( TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
db, transportCrypto, dbExecutor, scheduler, clock, transportId, db, transportCrypto, dbExecutor, scheduler, clock, transportId,
maxLatency); maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of time period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = timePeriodLength * 1000;
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId, assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
masterKey, timestamp, alice, false)); masterKey, timestamp, alice, false));
// The keys are inactive so no stream context should be returned // The keys are inactive so no stream context should be returned
@@ -491,9 +491,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey, oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey,
1000, alice, active); 1000, alice, active);
will(returnValue(transportKeys)); will(returnValue(transportKeys));
// Get the current time (the start of rotation period 1000) // Get the current time (the start of time period 1000)
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(rotationPeriodLength * 1000)); will(returnValue(timePeriodLength * 1000));
// Encode the tags (3 sets) // Encode the tags (3 sets)
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) { for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
exactly(3).of(transportCrypto).encodeTag( exactly(3).of(transportCrypto).encodeTag(
@@ -510,16 +510,16 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
}}); }});
} }
private TransportKeys createTransportKeys(long rotationPeriod, private TransportKeys createTransportKeys(long timePeriod,
long streamCounter, boolean active) { long streamCounter, boolean active) {
IncomingKeys inPrev = new IncomingKeys(tagKey, headerKey, IncomingKeys inPrev = new IncomingKeys(tagKey, headerKey,
rotationPeriod - 1); timePeriod - 1);
IncomingKeys inCurr = new IncomingKeys(tagKey, headerKey, IncomingKeys inCurr = new IncomingKeys(tagKey, headerKey,
rotationPeriod); timePeriod);
IncomingKeys inNext = new IncomingKeys(tagKey, headerKey, IncomingKeys inNext = new IncomingKeys(tagKey, headerKey,
rotationPeriod + 1); timePeriod + 1);
OutgoingKeys outCurr = new OutgoingKeys(tagKey, headerKey, OutgoingKeys outCurr = new OutgoingKeys(tagKey, headerKey,
rotationPeriod, streamCounter, active); timePeriod, streamCounter, active);
return new TransportKeys(transportId, inPrev, inCurr, inNext, outCurr); return new TransportKeys(transportId, inPrev, inCurr, inNext, outCurr);
} }