Merge branch '2079-reject-old-timestamps' into '1802-sync-via-removable-storage'

Reject old timestamps when deriving rotation mode keys

See merge request briar/briar!1481
This commit is contained in:
Torsten Grote
2021-07-06 12:22:42 +00:00
11 changed files with 343 additions and 42 deletions

View File

@@ -47,6 +47,7 @@ import javax.inject.Inject;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.api.system.Clock.MIN_REASONABLE_TIME_MS;
import static org.briarproject.bramble.contact.ContactExchangeConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.contact.ContactExchangeRecordTypes.CONTACT_INFO;
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
@@ -184,6 +185,10 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
// The agreed timestamp is the minimum of the peers' timestamps
long timestamp = Math.min(localTimestamp, remoteInfo.timestamp);
if (timestamp < MIN_REASONABLE_TIME_MS) {
LOG.warning("Timestamp is too old");
throw new FormatException();
}
// Add the contact
Contact contact = addContact(p, remoteInfo.author, localAuthor,

View File

@@ -41,6 +41,8 @@ import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResul
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DB_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SERVICE_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
import static org.briarproject.bramble.api.system.Clock.MAX_REASONABLE_TIME_MS;
import static org.briarproject.bramble.api.system.Clock.MIN_REASONABLE_TIME_MS;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;

View File

@@ -19,6 +19,7 @@ import javax.annotation.concurrent.Immutable;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
import static org.briarproject.bramble.api.plugin.TransportId.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.bramble.api.system.Clock.MIN_REASONABLE_TIME_MS;
import static org.briarproject.bramble.transport.agreement.MessageType.ACTIVATE;
import static org.briarproject.bramble.transport.agreement.MessageType.KEY;
import static org.briarproject.bramble.transport.agreement.TransportKeyAgreementConstants.MSG_KEY_PUBLIC_KEY;
@@ -42,13 +43,14 @@ class TransportKeyAgreementValidator extends BdfMessageValidator {
protected BdfMessageContext validateMessage(Message m, Group g,
BdfList body) throws FormatException {
MessageType type = MessageType.fromValue(body.getLong(0).intValue());
if (type == KEY) return validateKeyMessage(body);
if (type == KEY) return validateKeyMessage(m.getTimestamp(), body);
else if (type == ACTIVATE) return validateActivateMessage(body);
else throw new AssertionError();
}
private BdfMessageContext validateKeyMessage(BdfList body)
private BdfMessageContext validateKeyMessage(long timestamp, BdfList body)
throws FormatException {
if (timestamp < MIN_REASONABLE_TIME_MS) throw new FormatException();
// Message type, transport ID, public key
checkSize(body, 3);
String transportId = body.getString(1);

View File

@@ -15,10 +15,10 @@ import org.junit.Test;
import java.util.concurrent.atomic.AtomicBoolean;
import static junit.framework.TestCase.assertTrue;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.MAX_REASONABLE_TIME_MS;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.MIN_REASONABLE_TIME_MS;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.CLOCK_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
import static org.briarproject.bramble.api.system.Clock.MAX_REASONABLE_TIME_MS;
import static org.briarproject.bramble.api.system.Clock.MIN_REASONABLE_TIME_MS;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.junit.Assert.assertEquals;

View File

@@ -19,6 +19,7 @@ import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
import static org.briarproject.bramble.api.plugin.TransportId.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.bramble.api.system.Clock.MIN_REASONABLE_TIME_MS;
import static org.briarproject.bramble.api.versioning.ClientVersioningManager.CLIENT_ID;
import static org.briarproject.bramble.api.versioning.ClientVersioningManager.MAJOR_VERSION;
import static org.briarproject.bramble.test.TestUtils.getGroup;
@@ -109,6 +110,27 @@ public class TransportKeyAgreementValidatorTest extends BrambleMockTestCase {
assertArrayEquals(publicKey, d.getRaw(MSG_KEY_PUBLIC_KEY));
}
@Test
public void testAcceptsMinTimestampKeyMsg() throws Exception {
Message message =
getMessage(group.getId(), 1234, MIN_REASONABLE_TIME_MS);
TransportId transportId = new TransportId(getRandomString(1));
context.checking(new Expectations() {{
oneOf(messageEncoder)
.encodeMessageMetadata(transportId, KEY, false);
will(returnValue(new BdfDictionary()));
}});
byte[] publicKey = getRandomBytes(1);
BdfList body =
BdfList.of(KEY.getValue(), transportId.getString(), publicKey);
BdfMessageContext msgCtx =
validator.validateMessage(message, group, body);
assertEquals(emptyList(), msgCtx.getDependencies());
BdfDictionary d = msgCtx.getDictionary();
assertArrayEquals(publicKey, d.getRaw(MSG_KEY_PUBLIC_KEY));
}
@Test(expected = FormatException.class)
public void testRejectsTooLongKeyMsg() throws Exception {
BdfList body = BdfList.of(KEY.getValue(), getRandomString(1),
@@ -168,6 +190,15 @@ public class TransportKeyAgreementValidatorTest extends BrambleMockTestCase {
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class)
public void testRejectsTooOldTimestampKeyMsg() throws Exception {
Message message =
getMessage(group.getId(), 1234, MIN_REASONABLE_TIME_MS - 1);
BdfList body = BdfList.of(KEY.getValue(), getRandomString(1),
getRandomBytes(1));
validator.validateMessage(message, group, body);
}
@Test
public void testAcceptsActivateMsg() throws Exception {
TransportId transportId = new TransportId(getRandomString(1));