mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Create DB tables for static keys.
This commit is contained in:
@@ -36,45 +36,44 @@ class TransportCryptoImpl implements TransportCrypto {
|
||||
|
||||
@Override
|
||||
public TransportKeys deriveTransportKeys(TransportId t,
|
||||
SecretKey master, long rotationPeriod, boolean alice,
|
||||
boolean active) {
|
||||
SecretKey master, long timePeriod, boolean alice, boolean active) {
|
||||
// Keys for the previous period are derived from the master secret
|
||||
SecretKey inTagPrev = deriveTagKey(master, t, !alice);
|
||||
SecretKey inHeaderPrev = deriveHeaderKey(master, t, !alice);
|
||||
SecretKey outTagPrev = deriveTagKey(master, t, alice);
|
||||
SecretKey outHeaderPrev = deriveHeaderKey(master, t, alice);
|
||||
// Derive the keys for the current and next periods
|
||||
SecretKey inTagCurr = rotateKey(inTagPrev, rotationPeriod);
|
||||
SecretKey inHeaderCurr = rotateKey(inHeaderPrev, rotationPeriod);
|
||||
SecretKey inTagNext = rotateKey(inTagCurr, rotationPeriod + 1);
|
||||
SecretKey inHeaderNext = rotateKey(inHeaderCurr, rotationPeriod + 1);
|
||||
SecretKey outTagCurr = rotateKey(outTagPrev, rotationPeriod);
|
||||
SecretKey outHeaderCurr = rotateKey(outHeaderPrev, rotationPeriod);
|
||||
SecretKey inTagCurr = rotateKey(inTagPrev, timePeriod);
|
||||
SecretKey inHeaderCurr = rotateKey(inHeaderPrev, timePeriod);
|
||||
SecretKey inTagNext = rotateKey(inTagCurr, timePeriod + 1);
|
||||
SecretKey inHeaderNext = rotateKey(inHeaderCurr, timePeriod + 1);
|
||||
SecretKey outTagCurr = rotateKey(outTagPrev, timePeriod);
|
||||
SecretKey outHeaderCurr = rotateKey(outHeaderPrev, timePeriod);
|
||||
// Initialise the reordering windows and stream counters
|
||||
IncomingKeys inPrev = new IncomingKeys(inTagPrev, inHeaderPrev,
|
||||
rotationPeriod - 1);
|
||||
timePeriod - 1);
|
||||
IncomingKeys inCurr = new IncomingKeys(inTagCurr, inHeaderCurr,
|
||||
rotationPeriod);
|
||||
timePeriod);
|
||||
IncomingKeys inNext = new IncomingKeys(inTagNext, inHeaderNext,
|
||||
rotationPeriod + 1);
|
||||
timePeriod + 1);
|
||||
OutgoingKeys outCurr = new OutgoingKeys(outTagCurr, outHeaderCurr,
|
||||
rotationPeriod, active);
|
||||
timePeriod, active);
|
||||
// Collect and return the keys
|
||||
return new TransportKeys(t, inPrev, inCurr, inNext, outCurr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportKeys rotateTransportKeys(TransportKeys k,
|
||||
long rotationPeriod) {
|
||||
if (k.getRotationPeriod() >= rotationPeriod) return k;
|
||||
long timePeriod) {
|
||||
if (k.getTimePeriod() >= timePeriod) return k;
|
||||
IncomingKeys inPrev = k.getPreviousIncomingKeys();
|
||||
IncomingKeys inCurr = k.getCurrentIncomingKeys();
|
||||
IncomingKeys inNext = k.getNextIncomingKeys();
|
||||
OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
|
||||
long startPeriod = outCurr.getRotationPeriod();
|
||||
long startPeriod = outCurr.getTimePeriod();
|
||||
boolean active = outCurr.isActive();
|
||||
// Rotate the keys
|
||||
for (long p = startPeriod + 1; p <= rotationPeriod; p++) {
|
||||
for (long p = startPeriod + 1; p <= timePeriod; p++) {
|
||||
inPrev = inCurr;
|
||||
inCurr = inNext;
|
||||
SecretKey inNextTag = rotateKey(inNext.getTagKey(), p + 1);
|
||||
@@ -89,9 +88,9 @@ class TransportCryptoImpl implements TransportCrypto {
|
||||
outCurr);
|
||||
}
|
||||
|
||||
private SecretKey rotateKey(SecretKey k, long rotationPeriod) {
|
||||
private SecretKey rotateKey(SecretKey k, long timePeriod) {
|
||||
byte[] period = new byte[INT_64_BYTES];
|
||||
ByteUtils.writeUint64(rotationPeriod, period, 0);
|
||||
ByteUtils.writeUint64(timePeriod, period, 0);
|
||||
return crypto.deriveKey(ROTATE_LABEL, k, period);
|
||||
}
|
||||
|
||||
|
||||
@@ -635,10 +635,10 @@ interface Database<T> {
|
||||
|
||||
/**
|
||||
* 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,
|
||||
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.
|
||||
|
||||
@@ -956,13 +956,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
|
||||
@Override
|
||||
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 {
|
||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsTransport(txn, t))
|
||||
throw new NoSuchTransportException();
|
||||
db.setReorderingWindow(txn, k, t, rotationPeriod, base, bitmap);
|
||||
db.setReorderingWindow(txn, k, t, timePeriod, base, bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -85,9 +85,9 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
||||
abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
// 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_CURR = 0;
|
||||
private static final int OFFSET_NEXT = 1;
|
||||
@@ -248,7 +248,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
"CREATE TABLE outgoingKeys"
|
||||
+ " (transportId _STRING NOT NULL,"
|
||||
+ " keySetId _COUNTER,"
|
||||
+ " rotationPeriod BIGINT NOT NULL,"
|
||||
+ " timePeriod BIGINT NOT NULL,"
|
||||
+ " contactId INT NOT NULL,"
|
||||
+ " tagKey _SECRET NOT NULL,"
|
||||
+ " headerKey _SECRET NOT NULL,"
|
||||
@@ -267,8 +267,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
"CREATE TABLE incomingKeys"
|
||||
+ " (transportId _STRING NOT NULL,"
|
||||
+ " keySetId INT NOT NULL,"
|
||||
+ " rotationPeriod BIGINT NOT NULL,"
|
||||
+ " contactId INT NOT NULL,"
|
||||
+ " timePeriod BIGINT NOT NULL,"
|
||||
+ " tagKey _SECRET NOT NULL,"
|
||||
+ " headerKey _SECRET NOT NULL,"
|
||||
+ " base BIGINT NOT NULL,"
|
||||
@@ -280,9 +279,49 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " ON DELETE CASCADE,"
|
||||
+ " FOREIGN KEY (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,"
|
||||
+ " UNIQUE (staticKeySetId),"
|
||||
+ " FOREIGN KEY (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)";
|
||||
|
||||
private static final String INDEX_CONTACTS_BY_AUTHOR_ID =
|
||||
@@ -428,7 +467,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
return Arrays.asList(
|
||||
new Migration38_39(),
|
||||
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_OUTGOING_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();
|
||||
} catch (SQLException e) {
|
||||
tryToClose(s, LOG, WARNING);
|
||||
@@ -922,13 +965,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
try {
|
||||
// Store the outgoing keys
|
||||
String sql = "INSERT INTO outgoingKeys (contactId, transportId,"
|
||||
+ " rotationPeriod, tagKey, headerKey, stream, active)"
|
||||
+ " timePeriod, tagKey, headerKey, stream, active)"
|
||||
+ " VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
ps.setString(2, k.getTransportId().getString());
|
||||
OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
|
||||
ps.setLong(3, outCurr.getRotationPeriod());
|
||||
ps.setLong(3, outCurr.getTimePeriod());
|
||||
ps.setBytes(4, outCurr.getTagKey().getBytes());
|
||||
ps.setBytes(5, outCurr.getHeaderKey().getBytes());
|
||||
ps.setLong(6, outCurr.getStreamCounter());
|
||||
@@ -947,40 +990,39 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
rs.close();
|
||||
ps.close();
|
||||
// Store the incoming keys
|
||||
sql = "INSERT INTO incomingKeys (keySetId, contactId, transportId,"
|
||||
+ " rotationPeriod, tagKey, headerKey, base, bitmap,"
|
||||
sql = "INSERT INTO incomingKeys (keySetId, transportId,"
|
||||
+ " timePeriod, tagKey, headerKey, base, bitmap,"
|
||||
+ " periodOffset)"
|
||||
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, keySetId.getInt());
|
||||
ps.setInt(2, c.getInt());
|
||||
ps.setString(3, k.getTransportId().getString());
|
||||
// Previous rotation period
|
||||
ps.setString(2, k.getTransportId().getString());
|
||||
// Previous time period
|
||||
IncomingKeys inPrev = k.getPreviousIncomingKeys();
|
||||
ps.setLong(4, inPrev.getRotationPeriod());
|
||||
ps.setBytes(5, inPrev.getTagKey().getBytes());
|
||||
ps.setBytes(6, inPrev.getHeaderKey().getBytes());
|
||||
ps.setLong(7, inPrev.getWindowBase());
|
||||
ps.setBytes(8, inPrev.getWindowBitmap());
|
||||
ps.setInt(9, OFFSET_PREV);
|
||||
ps.setLong(3, inPrev.getTimePeriod());
|
||||
ps.setBytes(4, inPrev.getTagKey().getBytes());
|
||||
ps.setBytes(5, inPrev.getHeaderKey().getBytes());
|
||||
ps.setLong(6, inPrev.getWindowBase());
|
||||
ps.setBytes(7, inPrev.getWindowBitmap());
|
||||
ps.setInt(8, OFFSET_PREV);
|
||||
ps.addBatch();
|
||||
// Current rotation period
|
||||
// Current time period
|
||||
IncomingKeys inCurr = k.getCurrentIncomingKeys();
|
||||
ps.setLong(4, inCurr.getRotationPeriod());
|
||||
ps.setBytes(5, inCurr.getTagKey().getBytes());
|
||||
ps.setBytes(6, inCurr.getHeaderKey().getBytes());
|
||||
ps.setLong(7, inCurr.getWindowBase());
|
||||
ps.setBytes(8, inCurr.getWindowBitmap());
|
||||
ps.setInt(9, OFFSET_CURR);
|
||||
ps.setLong(3, inCurr.getTimePeriod());
|
||||
ps.setBytes(4, inCurr.getTagKey().getBytes());
|
||||
ps.setBytes(5, inCurr.getHeaderKey().getBytes());
|
||||
ps.setLong(6, inCurr.getWindowBase());
|
||||
ps.setBytes(7, inCurr.getWindowBitmap());
|
||||
ps.setInt(8, OFFSET_CURR);
|
||||
ps.addBatch();
|
||||
// Next rotation period
|
||||
// Next time period
|
||||
IncomingKeys inNext = k.getNextIncomingKeys();
|
||||
ps.setLong(4, inNext.getRotationPeriod());
|
||||
ps.setBytes(5, inNext.getTagKey().getBytes());
|
||||
ps.setBytes(6, inNext.getHeaderKey().getBytes());
|
||||
ps.setLong(7, inNext.getWindowBase());
|
||||
ps.setBytes(8, inNext.getWindowBitmap());
|
||||
ps.setInt(9, OFFSET_NEXT);
|
||||
ps.setLong(3, inNext.getTimePeriod());
|
||||
ps.setBytes(4, inNext.getTagKey().getBytes());
|
||||
ps.setBytes(5, inNext.getHeaderKey().getBytes());
|
||||
ps.setLong(6, inNext.getWindowBase());
|
||||
ps.setBytes(7, inNext.getWindowBitmap());
|
||||
ps.setInt(8, OFFSET_NEXT);
|
||||
ps.addBatch();
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if (batchAffected.length != 3) throw new DbStateException();
|
||||
@@ -2155,8 +2197,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
// Retrieve the incoming keys
|
||||
String sql = "SELECT rotationPeriod, tagKey, headerKey,"
|
||||
+ " base, bitmap"
|
||||
String sql = "SELECT timePeriod, tagKey, headerKey, base, bitmap"
|
||||
+ " FROM incomingKeys"
|
||||
+ " WHERE transportId = ?"
|
||||
+ " ORDER BY keySetId, periodOffset";
|
||||
@@ -2165,18 +2206,18 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
rs = ps.executeQuery();
|
||||
List<IncomingKeys> inKeys = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
long rotationPeriod = rs.getLong(1);
|
||||
long timePeriod = rs.getLong(1);
|
||||
SecretKey tagKey = new SecretKey(rs.getBytes(2));
|
||||
SecretKey headerKey = new SecretKey(rs.getBytes(3));
|
||||
long windowBase = rs.getLong(4);
|
||||
byte[] windowBitmap = rs.getBytes(5);
|
||||
inKeys.add(new IncomingKeys(tagKey, headerKey, rotationPeriod,
|
||||
inKeys.add(new IncomingKeys(tagKey, headerKey, timePeriod,
|
||||
windowBase, windowBitmap));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
// Retrieve the outgoing keys in the same order
|
||||
sql = "SELECT keySetId, contactId, rotationPeriod,"
|
||||
sql = "SELECT keySetId, contactId, timePeriod,"
|
||||
+ " tagKey, headerKey, stream, active"
|
||||
+ " FROM outgoingKeys"
|
||||
+ " WHERE transportId = ?"
|
||||
@@ -2190,13 +2231,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
if (inKeys.size() < (i + 1) * 3) throw new DbStateException();
|
||||
KeySetId keySetId = new KeySetId(rs.getInt(1));
|
||||
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 headerKey = new SecretKey(rs.getBytes(5));
|
||||
long streamCounter = rs.getLong(6);
|
||||
boolean active = rs.getBoolean(7);
|
||||
OutgoingKeys outCurr = new OutgoingKeys(tagKey, headerKey,
|
||||
rotationPeriod, streamCounter, active);
|
||||
timePeriod, streamCounter, active);
|
||||
IncomingKeys inPrev = inKeys.get(i * 3);
|
||||
IncomingKeys inCurr = inKeys.get(i * 3 + 1);
|
||||
IncomingKeys inNext = inKeys.get(i * 3 + 2);
|
||||
@@ -2894,18 +2935,18 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
@Override
|
||||
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;
|
||||
try {
|
||||
String sql = "UPDATE incomingKeys SET base = ?, bitmap = ?"
|
||||
+ " WHERE transportId = ? AND keySetId = ?"
|
||||
+ " AND rotationPeriod = ?";
|
||||
+ " AND timePeriod = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setLong(1, base);
|
||||
ps.setBytes(2, bitmap);
|
||||
ps.setString(3, t.getString());
|
||||
ps.setInt(4, k.getInt());
|
||||
ps.setLong(5, rotationPeriod);
|
||||
ps.setLong(5, timePeriod);
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||
ps.close();
|
||||
@@ -2977,13 +3018,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
// Update the outgoing keys
|
||||
String sql = "UPDATE outgoingKeys SET rotationPeriod = ?,"
|
||||
String sql = "UPDATE outgoingKeys SET timePeriod = ?,"
|
||||
+ " tagKey = ?, headerKey = ?, stream = ?"
|
||||
+ " WHERE transportId = ? AND keySetId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
TransportKeys k = ks.getTransportKeys();
|
||||
OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
|
||||
ps.setLong(1, outCurr.getRotationPeriod());
|
||||
ps.setLong(1, outCurr.getTimePeriod());
|
||||
ps.setBytes(2, outCurr.getTagKey().getBytes());
|
||||
ps.setBytes(3, outCurr.getHeaderKey().getBytes());
|
||||
ps.setLong(4, outCurr.getStreamCounter());
|
||||
@@ -2993,34 +3034,34 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||
ps.close();
|
||||
// Update the incoming keys
|
||||
sql = "UPDATE incomingKeys SET rotationPeriod = ?,"
|
||||
sql = "UPDATE incomingKeys SET timePeriod = ?,"
|
||||
+ " tagKey = ?, headerKey = ?, base = ?, bitmap = ?"
|
||||
+ " WHERE transportId = ? AND keySetId = ?"
|
||||
+ " AND periodOffset = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(6, k.getTransportId().getString());
|
||||
ps.setInt(7, ks.getKeySetId().getInt());
|
||||
// Previous rotation period
|
||||
// Previous time period
|
||||
IncomingKeys inPrev = k.getPreviousIncomingKeys();
|
||||
ps.setLong(1, inPrev.getRotationPeriod());
|
||||
ps.setLong(1, inPrev.getTimePeriod());
|
||||
ps.setBytes(2, inPrev.getTagKey().getBytes());
|
||||
ps.setBytes(3, inPrev.getHeaderKey().getBytes());
|
||||
ps.setLong(4, inPrev.getWindowBase());
|
||||
ps.setBytes(5, inPrev.getWindowBitmap());
|
||||
ps.setInt(8, OFFSET_PREV);
|
||||
ps.addBatch();
|
||||
// Current rotation period
|
||||
// Current time period
|
||||
IncomingKeys inCurr = k.getCurrentIncomingKeys();
|
||||
ps.setLong(1, inCurr.getRotationPeriod());
|
||||
ps.setLong(1, inCurr.getTimePeriod());
|
||||
ps.setBytes(2, inCurr.getTagKey().getBytes());
|
||||
ps.setBytes(3, inCurr.getHeaderKey().getBytes());
|
||||
ps.setLong(4, inCurr.getWindowBase());
|
||||
ps.setBytes(5, inCurr.getWindowBitmap());
|
||||
ps.setInt(8, OFFSET_CURR);
|
||||
ps.addBatch();
|
||||
// Next rotation period
|
||||
// Next time period
|
||||
IncomingKeys inNext = k.getNextIncomingKeys();
|
||||
ps.setLong(1, inNext.getRotationPeriod());
|
||||
ps.setLong(1, inNext.getTimePeriod());
|
||||
ps.setBytes(2, inNext.getTagKey().getBytes());
|
||||
ps.setBytes(3, inNext.getHeaderKey().getBytes());
|
||||
ps.setLong(4, inNext.getWindowBase());
|
||||
|
||||
@@ -17,7 +17,7 @@ class Migration40_41 implements Migration<Connection> {
|
||||
|
||||
private final DatabaseTypes dbTypes;
|
||||
|
||||
public Migration40_41(DatabaseTypes databaseTypes) {
|
||||
Migration40_41(DatabaseTypes databaseTypes) {
|
||||
this.dbTypes = databaseTypes;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,18 +11,18 @@ import javax.annotation.concurrent.NotThreadSafe;
|
||||
class MutableIncomingKeys {
|
||||
|
||||
private final SecretKey tagKey, headerKey;
|
||||
private final long rotationPeriod;
|
||||
private final long timePeriod;
|
||||
private final ReorderingWindow window;
|
||||
|
||||
MutableIncomingKeys(IncomingKeys in) {
|
||||
tagKey = in.getTagKey();
|
||||
headerKey = in.getHeaderKey();
|
||||
rotationPeriod = in.getRotationPeriod();
|
||||
timePeriod = in.getTimePeriod();
|
||||
window = new ReorderingWindow(in.getWindowBase(), in.getWindowBitmap());
|
||||
}
|
||||
|
||||
IncomingKeys snapshot() {
|
||||
return new IncomingKeys(tagKey, headerKey, rotationPeriod,
|
||||
return new IncomingKeys(tagKey, headerKey, timePeriod,
|
||||
window.getBase(), window.getBitmap());
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ class MutableIncomingKeys {
|
||||
return headerKey;
|
||||
}
|
||||
|
||||
long getRotationPeriod() {
|
||||
return rotationPeriod;
|
||||
long getTimePeriod() {
|
||||
return timePeriod;
|
||||
}
|
||||
|
||||
ReorderingWindow getWindow() {
|
||||
|
||||
@@ -11,20 +11,20 @@ import javax.annotation.concurrent.NotThreadSafe;
|
||||
class MutableOutgoingKeys {
|
||||
|
||||
private final SecretKey tagKey, headerKey;
|
||||
private final long rotationPeriod;
|
||||
private final long timePeriod;
|
||||
private long streamCounter;
|
||||
private boolean active;
|
||||
|
||||
MutableOutgoingKeys(OutgoingKeys out) {
|
||||
tagKey = out.getTagKey();
|
||||
headerKey = out.getHeaderKey();
|
||||
rotationPeriod = out.getRotationPeriod();
|
||||
timePeriod = out.getTimePeriod();
|
||||
streamCounter = out.getStreamCounter();
|
||||
active = out.isActive();
|
||||
}
|
||||
|
||||
OutgoingKeys snapshot() {
|
||||
return new OutgoingKeys(tagKey, headerKey, rotationPeriod,
|
||||
return new OutgoingKeys(tagKey, headerKey, timePeriod,
|
||||
streamCounter, active);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ class MutableOutgoingKeys {
|
||||
return headerKey;
|
||||
}
|
||||
|
||||
long getRotationPeriod() {
|
||||
return rotationPeriod;
|
||||
long getTimePeriod() {
|
||||
return timePeriod;
|
||||
}
|
||||
|
||||
long getStreamCounter() {
|
||||
|
||||
@@ -51,7 +51,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
private final ScheduledExecutorService scheduler;
|
||||
private final Clock clock;
|
||||
private final TransportId transportId;
|
||||
private final long rotationPeriodLength;
|
||||
private final long timePeriodLength;
|
||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
@@ -70,7 +70,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
this.scheduler = scheduler;
|
||||
this.clock = clock;
|
||||
this.transportId = transportId;
|
||||
rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
timePeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +81,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
try {
|
||||
// Load the transport keys from the DB
|
||||
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);
|
||||
// Initialise mutable state for all contacts
|
||||
addKeys(rotationResult.current);
|
||||
@@ -97,13 +97,13 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
|
||||
private RotationResult rotateKeys(Collection<KeySet> keys, long now) {
|
||||
RotationResult rotationResult = new RotationResult();
|
||||
long rotationPeriod = now / rotationPeriodLength;
|
||||
long timePeriod = now / timePeriodLength;
|
||||
for (KeySet ks : keys) {
|
||||
TransportKeys k = ks.getTransportKeys();
|
||||
TransportKeys k1 =
|
||||
transportCrypto.rotateTransportKeys(k, rotationPeriod);
|
||||
transportCrypto.rotateTransportKeys(k, timePeriod);
|
||||
KeySet ks1 = new KeySet(ks.getKeySetId(), ks.getContactId(), k1);
|
||||
if (k1.getRotationPeriod() > k.getRotationPeriod())
|
||||
if (k1.getTimePeriod() > k.getTimePeriod())
|
||||
rotationResult.rotated.add(ks1);
|
||||
rotationResult.current.add(ks1);
|
||||
}
|
||||
@@ -155,7 +155,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
}
|
||||
|
||||
private void scheduleKeyRotation(long now) {
|
||||
long delay = rotationPeriodLength - now % rotationPeriodLength;
|
||||
long delay = timePeriodLength - now % timePeriodLength;
|
||||
scheduler.schedule((Runnable) this::rotateKeys, delay, MILLISECONDS);
|
||||
}
|
||||
|
||||
@@ -174,14 +174,14 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
long timestamp, boolean alice, boolean active) throws DbException {
|
||||
lock.lock();
|
||||
try {
|
||||
// Work out what rotation period the timestamp belongs to
|
||||
long rotationPeriod = timestamp / rotationPeriodLength;
|
||||
// Work out what time period the timestamp belongs to
|
||||
long timePeriod = timestamp / timePeriodLength;
|
||||
// Derive the transport keys
|
||||
TransportKeys k = transportCrypto.deriveTransportKeys(transportId,
|
||||
master, rotationPeriod, alice, active);
|
||||
// Rotate the keys to the current rotation period if necessary
|
||||
rotationPeriod = clock.currentTimeMillis() / rotationPeriodLength;
|
||||
k = transportCrypto.rotateTransportKeys(k, rotationPeriod);
|
||||
master, timePeriod, alice, active);
|
||||
// Rotate the keys to the current time period if necessary
|
||||
timePeriod = clock.currentTimeMillis() / timePeriodLength;
|
||||
k = transportCrypto.rotateTransportKeys(k, timePeriod);
|
||||
// Write the keys back to the DB
|
||||
KeySetId keySetId = db.addTransportKeys(txn, c, k);
|
||||
// Initialise mutable state for the contact
|
||||
@@ -300,7 +300,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
}
|
||||
// Write the window back to the DB
|
||||
db.setReorderingWindow(txn, tagCtx.keySetId, transportId,
|
||||
inKeys.getRotationPeriod(), window.getBase(),
|
||||
inKeys.getTimePeriod(), window.getBase(),
|
||||
window.getBitmap());
|
||||
// If the outgoing keys are inactive, activate them
|
||||
MutableKeySet ks = keys.get(tagCtx.keySetId);
|
||||
@@ -322,7 +322,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
long now = clock.currentTimeMillis();
|
||||
lock.lock();
|
||||
try {
|
||||
// Rotate the keys to the current rotation period
|
||||
// Rotate the keys to the current time period
|
||||
Collection<KeySet> snapshot = new ArrayList<>(keys.size());
|
||||
for (MutableKeySet ks : keys.values()) {
|
||||
snapshot.add(new KeySet(ks.getKeySetId(), ks.getContactId(),
|
||||
|
||||
@@ -40,7 +40,7 @@ public class KeyDerivationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testCurrentKeysMatchCurrentKeysOfContact() {
|
||||
// Start in rotation period 123
|
||||
// Start in time period 123
|
||||
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
|
||||
master, 123, true, true);
|
||||
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
|
||||
@@ -72,7 +72,7 @@ public class KeyDerivationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testPreviousKeysMatchPreviousKeysOfContact() {
|
||||
// Start in rotation period 123
|
||||
// Start in time period 123
|
||||
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
|
||||
master, 123, true, true);
|
||||
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
|
||||
@@ -99,7 +99,7 @@ public class KeyDerivationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testNextKeysMatchNextKeysOfContact() {
|
||||
// Start in rotation period 123
|
||||
// Start in time period 123
|
||||
TransportKeys kA = transportCrypto.deriveTransportKeys(transportId,
|
||||
master, 123, true, true);
|
||||
TransportKeys kB = transportCrypto.deriveTransportKeys(transportId,
|
||||
|
||||
@@ -653,10 +653,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testTransportKeys() throws Exception {
|
||||
long rotationPeriod = 123, rotationPeriod1 = 234;
|
||||
long timePeriod = 123, timePeriod1 = 234;
|
||||
boolean active = random.nextBoolean();
|
||||
TransportKeys keys = createTransportKeys(rotationPeriod, active);
|
||||
TransportKeys keys1 = createTransportKeys(rotationPeriod1, active);
|
||||
TransportKeys keys = createTransportKeys(timePeriod, active);
|
||||
TransportKeys keys1 = createTransportKeys(timePeriod1, active);
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
@@ -686,9 +686,9 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
}
|
||||
|
||||
// Rotate the transport keys
|
||||
TransportKeys rotated = createTransportKeys(rotationPeriod + 1, active);
|
||||
TransportKeys rotated = createTransportKeys(timePeriod + 1, active);
|
||||
TransportKeys rotated1 =
|
||||
createTransportKeys(rotationPeriod1 + 1, active);
|
||||
createTransportKeys(timePeriod1 + 1, active);
|
||||
db.updateTransportKeys(txn, new KeySet(keySetId, contactId, rotated));
|
||||
db.updateTransportKeys(txn, new KeySet(keySetId1, contactId, rotated1));
|
||||
|
||||
@@ -716,7 +716,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
private void assertKeysEquals(TransportKeys expected,
|
||||
TransportKeys actual) {
|
||||
assertEquals(expected.getTransportId(), actual.getTransportId());
|
||||
assertEquals(expected.getRotationPeriod(), actual.getRotationPeriod());
|
||||
assertEquals(expected.getTimePeriod(), actual.getTimePeriod());
|
||||
assertKeysEquals(expected.getPreviousIncomingKeys(),
|
||||
actual.getPreviousIncomingKeys());
|
||||
assertKeysEquals(expected.getCurrentIncomingKeys(),
|
||||
@@ -732,7 +732,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
actual.getTagKey().getBytes());
|
||||
assertArrayEquals(expected.getHeaderKey().getBytes(),
|
||||
actual.getHeaderKey().getBytes());
|
||||
assertEquals(expected.getRotationPeriod(), actual.getRotationPeriod());
|
||||
assertEquals(expected.getTimePeriod(), actual.getTimePeriod());
|
||||
assertEquals(expected.getWindowBase(), actual.getWindowBase());
|
||||
assertArrayEquals(expected.getWindowBitmap(), actual.getWindowBitmap());
|
||||
}
|
||||
@@ -742,15 +742,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
actual.getTagKey().getBytes());
|
||||
assertArrayEquals(expected.getHeaderKey().getBytes(),
|
||||
actual.getHeaderKey().getBytes());
|
||||
assertEquals(expected.getRotationPeriod(), actual.getRotationPeriod());
|
||||
assertEquals(expected.getTimePeriod(), actual.getTimePeriod());
|
||||
assertEquals(expected.getStreamCounter(), actual.getStreamCounter());
|
||||
assertEquals(expected.isActive(), actual.isActive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncrementStreamCounter() throws Exception {
|
||||
long rotationPeriod = 123;
|
||||
TransportKeys keys = createTransportKeys(rotationPeriod, true);
|
||||
long timePeriod = 123;
|
||||
TransportKeys keys = createTransportKeys(timePeriod, true);
|
||||
long streamCounter = keys.getCurrentOutgoingKeys().getStreamCounter();
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
@@ -774,7 +774,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
TransportKeys k = ks.getTransportKeys();
|
||||
assertEquals(transportId, k.getTransportId());
|
||||
OutgoingKeys outCurr = k.getCurrentOutgoingKeys();
|
||||
assertEquals(rotationPeriod, outCurr.getRotationPeriod());
|
||||
assertEquals(timePeriod, outCurr.getTimePeriod());
|
||||
assertEquals(streamCounter + 2, outCurr.getStreamCounter());
|
||||
|
||||
// The rest of the keys should be unaffected
|
||||
@@ -791,8 +791,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testSetReorderingWindow() throws Exception {
|
||||
boolean active = random.nextBoolean();
|
||||
long rotationPeriod = 123;
|
||||
TransportKeys keys = createTransportKeys(rotationPeriod, active);
|
||||
long timePeriod = 123;
|
||||
TransportKeys keys = createTransportKeys(timePeriod, active);
|
||||
long base = keys.getCurrentIncomingKeys().getWindowBase();
|
||||
byte[] bitmap = keys.getCurrentIncomingKeys().getWindowBitmap();
|
||||
|
||||
@@ -808,7 +808,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Update the reordering window and retrieve the transport keys
|
||||
random.nextBytes(bitmap);
|
||||
db.setReorderingWindow(txn, keySetId, transportId, rotationPeriod,
|
||||
db.setReorderingWindow(txn, keySetId, transportId, timePeriod,
|
||||
base + 1, bitmap);
|
||||
Collection<KeySet> newKeys = db.getTransportKeys(txn, transportId);
|
||||
assertEquals(1, newKeys.size());
|
||||
@@ -818,7 +818,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
TransportKeys k = ks.getTransportKeys();
|
||||
assertEquals(transportId, k.getTransportId());
|
||||
IncomingKeys inCurr = k.getCurrentIncomingKeys();
|
||||
assertEquals(rotationPeriod, inCurr.getRotationPeriod());
|
||||
assertEquals(timePeriod, inCurr.getTimePeriod());
|
||||
assertEquals(base + 1, inCurr.getWindowBase());
|
||||
assertArrayEquals(bitmap, inCurr.getWindowBitmap());
|
||||
|
||||
@@ -1978,24 +1978,23 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
return db;
|
||||
}
|
||||
|
||||
private TransportKeys createTransportKeys(long rotationPeriod,
|
||||
boolean active) {
|
||||
private TransportKeys createTransportKeys(long timePeriod, boolean active) {
|
||||
SecretKey inPrevTagKey = getSecretKey();
|
||||
SecretKey inPrevHeaderKey = getSecretKey();
|
||||
IncomingKeys inPrev = new IncomingKeys(inPrevTagKey, inPrevHeaderKey,
|
||||
rotationPeriod - 1, 123, new byte[4]);
|
||||
timePeriod - 1, 123, new byte[4]);
|
||||
SecretKey inCurrTagKey = getSecretKey();
|
||||
SecretKey inCurrHeaderKey = getSecretKey();
|
||||
IncomingKeys inCurr = new IncomingKeys(inCurrTagKey, inCurrHeaderKey,
|
||||
rotationPeriod, 234, new byte[4]);
|
||||
timePeriod, 234, new byte[4]);
|
||||
SecretKey inNextTagKey = getSecretKey();
|
||||
SecretKey inNextHeaderKey = getSecretKey();
|
||||
IncomingKeys inNext = new IncomingKeys(inNextTagKey, inNextHeaderKey,
|
||||
rotationPeriod + 1, 345, new byte[4]);
|
||||
timePeriod + 1, 345, new byte[4]);
|
||||
SecretKey outCurrTagKey = getSecretKey();
|
||||
SecretKey outCurrHeaderKey = getSecretKey();
|
||||
OutgoingKeys outCurr = new OutgoingKeys(outCurrTagKey, outCurrHeaderKey,
|
||||
rotationPeriod, 456, active);
|
||||
timePeriod, 456, active);
|
||||
return new TransportKeys(transportId, inPrev, inCurr, inNext, outCurr);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final TransportId transportId = getTransportId();
|
||||
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 contactId1 = new ContactId(234);
|
||||
private final KeySetId keySetId = new KeySetId(345);
|
||||
@@ -79,9 +79,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
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();
|
||||
will(returnValue(rotationPeriodLength * 1000 + 1));
|
||||
will(returnValue(timePeriodLength * 1000 + 1));
|
||||
// Load the transport keys
|
||||
oneOf(db).getTransportKeys(txn, transportId);
|
||||
will(returnValue(loaded));
|
||||
@@ -100,9 +100,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
// Save the keys that were rotated
|
||||
oneOf(db).updateTransportKeys(txn,
|
||||
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)),
|
||||
with(rotationPeriodLength - 1), with(MILLISECONDS));
|
||||
with(timePeriodLength - 1), with(MILLISECONDS));
|
||||
}});
|
||||
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
@@ -123,9 +123,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey,
|
||||
999, alice, true);
|
||||
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();
|
||||
will(returnValue(rotationPeriodLength * 1000 + 1));
|
||||
will(returnValue(timePeriodLength * 1000 + 1));
|
||||
// Rotate the transport keys
|
||||
oneOf(transportCrypto).rotateTransportKeys(transportKeys, 1000);
|
||||
will(returnValue(rotated));
|
||||
@@ -144,8 +144,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
|
||||
maxLatency);
|
||||
// The timestamp is 1 ms before the start of rotation period 1000
|
||||
long timestamp = rotationPeriodLength * 1000 - 1;
|
||||
// The timestamp is 1 ms before the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000 - 1;
|
||||
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
|
||||
masterKey, timestamp, alice, true));
|
||||
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
|
||||
@@ -177,8 +177,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
|
||||
maxLatency);
|
||||
// The timestamp is at the start of rotation period 1000
|
||||
long timestamp = rotationPeriodLength * 1000;
|
||||
// The timestamp is at the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000;
|
||||
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
|
||||
masterKey, timestamp, alice, true));
|
||||
assertFalse(transportKeyManager.canSendOutgoingStreams(contactId));
|
||||
@@ -203,8 +203,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
|
||||
maxLatency);
|
||||
// The timestamp is at the start of rotation period 1000
|
||||
long timestamp = rotationPeriodLength * 1000;
|
||||
// The timestamp is at the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000;
|
||||
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
|
||||
masterKey, timestamp, alice, true));
|
||||
// The first request should return a stream context
|
||||
@@ -235,8 +235,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
|
||||
maxLatency);
|
||||
// The timestamp is at the start of rotation period 1000
|
||||
long timestamp = rotationPeriodLength * 1000;
|
||||
// The timestamp is at the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000;
|
||||
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
|
||||
masterKey, timestamp, alice, active));
|
||||
assertEquals(active,
|
||||
@@ -259,9 +259,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(transportCrypto).deriveTransportKeys(transportId, masterKey,
|
||||
1000, alice, true);
|
||||
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();
|
||||
will(returnValue(rotationPeriodLength * 1000));
|
||||
will(returnValue(timePeriodLength * 1000));
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(transportCrypto).encodeTag(
|
||||
@@ -280,7 +280,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
with(tagKey), with(PROTOCOL_VERSION),
|
||||
with((long) REORDERING_WINDOW_SIZE));
|
||||
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,
|
||||
1, new byte[REORDERING_WINDOW_SIZE / 8]);
|
||||
}});
|
||||
@@ -288,12 +288,12 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
|
||||
maxLatency);
|
||||
// The timestamp is at the start of rotation period 1000
|
||||
long timestamp = rotationPeriodLength * 1000;
|
||||
// The timestamp is at the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000;
|
||||
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
|
||||
masterKey, timestamp, alice, true));
|
||||
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());
|
||||
byte[] tag = tags.get(0);
|
||||
// The first request should return a stream context
|
||||
@@ -320,9 +320,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
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();
|
||||
will(returnValue(rotationPeriodLength * 1000));
|
||||
will(returnValue(timePeriodLength * 1000));
|
||||
// Load the transport keys
|
||||
oneOf(db).getTransportKeys(txn, transportId);
|
||||
will(returnValue(loaded));
|
||||
@@ -336,17 +336,17 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
with(PROTOCOL_VERSION), with(i));
|
||||
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)),
|
||||
with(rotationPeriodLength), with(MILLISECONDS));
|
||||
with(timePeriodLength), with(MILLISECONDS));
|
||||
will(new RunAction());
|
||||
oneOf(dbExecutor).execute(with(any(Runnable.class)));
|
||||
will(new RunAction());
|
||||
// Start a transaction for key rotation
|
||||
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();
|
||||
will(returnValue(rotationPeriodLength * 1001));
|
||||
will(returnValue(timePeriodLength * 1001));
|
||||
// Rotate the transport keys
|
||||
oneOf(transportCrypto).rotateTransportKeys(
|
||||
with(any(TransportKeys.class)), with(1001L));
|
||||
@@ -361,9 +361,9 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
// Save the keys that were rotated
|
||||
oneOf(db).updateTransportKeys(txn1,
|
||||
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)),
|
||||
with(rotationPeriodLength), with(MILLISECONDS));
|
||||
with(timePeriodLength), with(MILLISECONDS));
|
||||
}});
|
||||
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
@@ -391,8 +391,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
|
||||
maxLatency);
|
||||
// The timestamp is at the start of rotation period 1000
|
||||
long timestamp = rotationPeriodLength * 1000;
|
||||
// The timestamp is at the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000;
|
||||
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
|
||||
masterKey, timestamp, alice, false));
|
||||
// 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,
|
||||
1000, alice, false);
|
||||
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();
|
||||
will(returnValue(rotationPeriodLength * 1000));
|
||||
will(returnValue(timePeriodLength * 1000));
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(transportCrypto).encodeTag(
|
||||
@@ -445,7 +445,7 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
with(tagKey), with(PROTOCOL_VERSION),
|
||||
with((long) REORDERING_WINDOW_SIZE));
|
||||
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,
|
||||
1, new byte[REORDERING_WINDOW_SIZE / 8]);
|
||||
// Activate the keys
|
||||
@@ -457,8 +457,8 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
TransportKeyManager transportKeyManager = new TransportKeyManagerImpl(
|
||||
db, transportCrypto, dbExecutor, scheduler, clock, transportId,
|
||||
maxLatency);
|
||||
// The timestamp is at the start of rotation period 1000
|
||||
long timestamp = rotationPeriodLength * 1000;
|
||||
// The timestamp is at the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000;
|
||||
assertEquals(keySetId, transportKeyManager.addContact(txn, contactId,
|
||||
masterKey, timestamp, alice, false));
|
||||
// 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,
|
||||
1000, alice, active);
|
||||
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();
|
||||
will(returnValue(rotationPeriodLength * 1000));
|
||||
will(returnValue(timePeriodLength * 1000));
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
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) {
|
||||
IncomingKeys inPrev = new IncomingKeys(tagKey, headerKey,
|
||||
rotationPeriod - 1);
|
||||
timePeriod - 1);
|
||||
IncomingKeys inCurr = new IncomingKeys(tagKey, headerKey,
|
||||
rotationPeriod);
|
||||
timePeriod);
|
||||
IncomingKeys inNext = new IncomingKeys(tagKey, headerKey,
|
||||
rotationPeriod + 1);
|
||||
timePeriod + 1);
|
||||
OutgoingKeys outCurr = new OutgoingKeys(tagKey, headerKey,
|
||||
rotationPeriod, streamCounter, active);
|
||||
timePeriod, streamCounter, active);
|
||||
return new TransportKeys(transportId, inPrev, inCurr, inNext, outCurr);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user