Address second round of review comments

This commit is contained in:
Torsten Grote
2018-04-26 19:20:10 -03:00
parent 337f7e7b8f
commit 80a9689316
19 changed files with 196 additions and 213 deletions

View File

@@ -16,8 +16,6 @@ import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public abstract class BdfIncomingMessageHook implements IncomingMessageHook { public abstract class BdfIncomingMessageHook implements IncomingMessageHook {
@@ -57,9 +55,7 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook {
public boolean incomingMessage(Transaction txn, Message m, Metadata meta) public boolean incomingMessage(Transaction txn, Message m, Metadata meta)
throws DbException, InvalidMessageException { throws DbException, InvalidMessageException {
try { try {
byte[] raw = m.getRaw(); BdfList body = clientHelper.toList(m);
BdfList body = clientHelper.toList(raw, MESSAGE_HEADER_LENGTH,
raw.length - MESSAGE_HEADER_LENGTH);
BdfDictionary metaDictionary = metadataParser.parse(meta); BdfDictionary metaDictionary = metadataParser.parse(meta);
return incomingMessage(txn, m, body, metaDictionary); return incomingMessage(txn, m, body, metaDictionary);
} catch (FormatException e) { } catch (FormatException e) {

View File

@@ -33,11 +33,13 @@ import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.briar.api.introduction.Role.INTRODUCEE; import static org.briarproject.briar.api.introduction.Role.INTRODUCEE;
import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_AUTH; import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_AUTH;
import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_RESPONSES; import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_RESPONSES;
@@ -51,6 +53,9 @@ import static org.briarproject.briar.introduction.IntroduceeState.START;
class IntroduceeProtocolEngine class IntroduceeProtocolEngine
extends AbstractProtocolEngine<IntroduceeSession> { extends AbstractProtocolEngine<IntroduceeSession> {
private final static Logger LOG =
Logger.getLogger(IntroduceeProtocolEngine.class.getSimpleName());
private final IntroductionCrypto crypto; private final IntroductionCrypto crypto;
private final KeyManager keyManager; private final KeyManager keyManager;
private final TransportPropertyManager transportPropertyManager; private final TransportPropertyManager transportPropertyManager;
@@ -383,11 +388,12 @@ class IntroduceeProtocolEngine
bobMacKey = crypto.deriveMacKey(masterKey, false); bobMacKey = crypto.deriveMacKey(masterKey, false);
SecretKey ourMacKey = s.getLocal().alice ? aliceMacKey : bobMacKey; SecretKey ourMacKey = s.getLocal().alice ? aliceMacKey : bobMacKey;
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
mac = crypto.authMac(ourMacKey, s, localAuthor.getId(), mac = crypto.authMac(ourMacKey, s, localAuthor.getId());
s.getLocal().alice);
signature = crypto.sign(ourMacKey, localAuthor.getPrivateKey()); signature = crypto.sign(ourMacKey, localAuthor.getPrivateKey());
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
// TODO // TODO
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
return abort(txn, s); return abort(txn, s);
} }
if (s.getState() != AWAIT_AUTH) throw new AssertionError(); if (s.getState() != AWAIT_AUTH) throw new AssertionError();
@@ -406,7 +412,7 @@ class IntroduceeProtocolEngine
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
try { try {
crypto.verifyAuthMac(m.getMac(), s, localAuthor.getId()); crypto.verifyAuthMac(m.getMac(), s, localAuthor.getId());
crypto.verifySignature(m.getSignature(), s, localAuthor.getId()); crypto.verifySignature(m.getSignature(), s);
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
return abort(txn, s); return abort(txn, s);
} }

View File

@@ -207,8 +207,10 @@ class IntroducerProtocolEngine
IntroducerSession s, IntroducerSession s,
@Nullable String message, long timestamp) throws DbException { @Nullable String message, long timestamp) throws DbException {
// Send REQUEST messages // Send REQUEST messages
long localTimestamp = long maxIntroduceeTimestamp =
Math.max(timestamp, getLocalTimestamp(s, s.getIntroduceeA())); Math.max(getLocalTimestamp(s, s.getIntroduceeA()),
getLocalTimestamp(s, s.getIntroduceeB()));
long localTimestamp = Math.max(timestamp, maxIntroduceeTimestamp);
Message sentA = sendRequestMessage(txn, s.getIntroduceeA(), Message sentA = sendRequestMessage(txn, s.getIntroduceeA(),
localTimestamp, s.getIntroduceeB().author, message localTimestamp, s.getIntroduceeB().author, message
); );

View File

@@ -49,7 +49,7 @@ interface IntroductionCrypto {
* transport properties, Author IDs and timestamps of the accept message. * transport properties, Author IDs and timestamps of the accept message.
*/ */
byte[] authMac(SecretKey macKey, IntroduceeSession s, byte[] authMac(SecretKey macKey, IntroduceeSession s,
AuthorId localAuthorId, boolean alice); AuthorId localAuthorId);
/** /**
* Verifies a received MAC * Verifies a received MAC
@@ -74,12 +74,12 @@ interface IntroductionCrypto {
throws GeneralSecurityException; throws GeneralSecurityException;
/** /**
* Verifies the signature on a corresponding MAC key. * Verifies the signature on a nonce derived from the MAC key.
* *
* @throws GeneralSecurityException if the signature is invalid * @throws GeneralSecurityException if the signature is invalid
*/ */
void verifySignature(byte[] signature, IntroduceeSession s, void verifySignature(byte[] signature, IntroduceeSession s)
AuthorId localAuthorId) throws GeneralSecurityException; throws GeneralSecurityException;
/** /**
* Generates a MAC using the local MAC key. * Generates a MAC using the local MAC key.

View File

@@ -13,12 +13,11 @@ import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.introduction.IntroduceeSession.Common;
import org.briarproject.briar.introduction.IntroduceeSession.Remote;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Map;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
@@ -32,6 +31,7 @@ import static org.briarproject.briar.api.introduction.IntroductionConstants.LABE
import static org.briarproject.briar.api.introduction.IntroductionConstants.LABEL_MASTER_KEY; import static org.briarproject.briar.api.introduction.IntroductionConstants.LABEL_MASTER_KEY;
import static org.briarproject.briar.api.introduction.IntroductionConstants.LABEL_SESSION_ID; import static org.briarproject.briar.api.introduction.IntroductionConstants.LABEL_SESSION_ID;
import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_VERSION; import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_VERSION;
import static org.briarproject.briar.introduction.IntroduceeSession.Local;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -114,27 +114,16 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
@Override @Override
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
public byte[] authMac(SecretKey macKey, IntroduceeSession s, public byte[] authMac(SecretKey macKey, IntroduceeSession s,
AuthorId localAuthorId, boolean alice) { AuthorId localAuthorId) {
// the macKey is not yet available in the session at this point
return authMac(macKey, s.getIntroducer().getId(), localAuthorId, return authMac(macKey, s.getIntroducer().getId(), localAuthorId,
s.getRemote().author.getId(), s.getLocal().acceptTimestamp, s.getLocal(), s.getRemote());
s.getRemote().acceptTimestamp, s.getLocal().ephemeralPublicKey,
s.getRemote().ephemeralPublicKey,
s.getLocal().transportProperties,
s.getRemote().transportProperties, alice);
} }
byte[] authMac(SecretKey macKey, AuthorId introducerId, byte[] authMac(SecretKey macKey, AuthorId introducerId,
AuthorId localAuthorId, AuthorId remoteAuthorId, AuthorId localAuthorId, Local local, Remote remote) {
long acceptTimestamp, long remoteAcceptTimestamp, byte[] inputs = getAuthMacInputs(introducerId, localAuthorId, local,
byte[] ephemeralPublicKey, byte[] remoteEphemeralPublicKey, remote.author.getId(), remote);
Map<TransportId, TransportProperties> transportProperties,
Map<TransportId, TransportProperties> remoteTransportProperties,
boolean alice) {
byte[] inputs =
getAuthMacInputs(introducerId, localAuthorId, remoteAuthorId,
acceptTimestamp, remoteAcceptTimestamp,
ephemeralPublicKey, remoteEphemeralPublicKey,
transportProperties, remoteTransportProperties, alice);
return crypto.mac( return crypto.mac(
LABEL_AUTH_MAC, LABEL_AUTH_MAC,
macKey, macKey,
@@ -145,59 +134,43 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
@Override @Override
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
public void verifyAuthMac(byte[] mac, IntroduceeSession s, public void verifyAuthMac(byte[] mac, IntroduceeSession s,
AuthorId localAuthorId) AuthorId localAuthorId) throws GeneralSecurityException {
throws GeneralSecurityException {
boolean alice = isAlice(localAuthorId, s.getRemote().author.getId());
verifyAuthMac(mac, new SecretKey(s.getRemote().macKey), verifyAuthMac(mac, new SecretKey(s.getRemote().macKey),
s.getIntroducer().getId(), localAuthorId, s.getIntroducer().getId(), localAuthorId, s.getLocal(),
s.getRemote().author.getId(), s.getLocal().acceptTimestamp, s.getRemote().author.getId(), s.getRemote());
s.getRemote().acceptTimestamp, s.getLocal().ephemeralPublicKey,
s.getRemote().ephemeralPublicKey,
s.getLocal().transportProperties,
s.getRemote().transportProperties, !alice);
} }
void verifyAuthMac(byte[] mac, SecretKey macKey, void verifyAuthMac(byte[] mac, SecretKey macKey, AuthorId introducerId,
AuthorId introducerId, AuthorId localAuthorId, AuthorId localAuthorId, Common local, AuthorId remoteAuthorId,
AuthorId remoteAuthorId, long acceptTimestamp, Common remote) throws GeneralSecurityException {
long remoteAcceptTimestamp, byte[] ephemeralPublicKey, // switch input for verification
byte[] remoteEphemeralPublicKey, byte[] inputs = getAuthMacInputs(introducerId, remoteAuthorId, remote,
Map<TransportId, TransportProperties> transportProperties, localAuthorId, local);
Map<TransportId, TransportProperties> remoteTransportProperties,
boolean alice) throws GeneralSecurityException {
byte[] inputs =
getAuthMacInputs(introducerId, localAuthorId, remoteAuthorId,
acceptTimestamp, remoteAcceptTimestamp,
ephemeralPublicKey, remoteEphemeralPublicKey,
transportProperties, remoteTransportProperties, !alice);
if (!crypto.verifyMac(mac, LABEL_AUTH_MAC, macKey, inputs)) { if (!crypto.verifyMac(mac, LABEL_AUTH_MAC, macKey, inputs)) {
throw new GeneralSecurityException(); throw new GeneralSecurityException();
} }
} }
@SuppressWarnings("ConstantConditions")
private byte[] getAuthMacInputs(AuthorId introducerId, private byte[] getAuthMacInputs(AuthorId introducerId,
AuthorId localAuthorId, AuthorId remoteAuthorId, AuthorId localAuthorId, Common local, AuthorId remoteAuthorId,
long acceptTimestamp, long remoteAcceptTimestamp, Common remote) {
byte[] ephemeralPublicKey, byte[] remoteEphemeralPublicKey,
Map<TransportId, TransportProperties> transportProperties,
Map<TransportId, TransportProperties> remoteTransportProperties,
boolean alice) {
BdfList localInfo = BdfList.of( BdfList localInfo = BdfList.of(
localAuthorId, localAuthorId,
acceptTimestamp, local.acceptTimestamp,
ephemeralPublicKey, local.ephemeralPublicKey,
clientHelper.toDictionary(transportProperties) clientHelper.toDictionary(local.transportProperties)
); );
BdfList remoteInfo = BdfList.of( BdfList remoteInfo = BdfList.of(
remoteAuthorId, remoteAuthorId,
remoteAcceptTimestamp, remote.acceptTimestamp,
remoteEphemeralPublicKey, remote.ephemeralPublicKey,
clientHelper.toDictionary(remoteTransportProperties) clientHelper.toDictionary(remote.transportProperties)
); );
BdfList macList = BdfList.of( BdfList macList = BdfList.of(
introducerId, introducerId,
alice ? localInfo : remoteInfo, localInfo,
alice ? remoteInfo : localInfo remoteInfo
); );
try { try {
return clientHelper.toByteArray(macList); return clientHelper.toByteArray(macList);
@@ -218,8 +191,8 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
@Override @Override
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
public void verifySignature(byte[] signature, IntroduceeSession s, public void verifySignature(byte[] signature, IntroduceeSession s)
AuthorId localAuthorId) throws GeneralSecurityException { throws GeneralSecurityException {
SecretKey macKey = new SecretKey(s.getRemote().macKey); SecretKey macKey = new SecretKey(s.getRemote().macKey);
verifySignature(macKey, s.getRemote().author.getPublicKey(), signature); verifySignature(macKey, s.getRemote().author.getPublicKey(), signature);
} }

View File

@@ -71,6 +71,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
private final IntroductionCrypto crypto; private final IntroductionCrypto crypto;
private final IdentityManager identityManager; private final IdentityManager identityManager;
private final Group localGroup;
@Inject @Inject
IntroductionManagerImpl( IntroductionManagerImpl(
DatabaseComponent db, DatabaseComponent db,
@@ -96,12 +98,13 @@ class IntroductionManagerImpl extends ConversationClientImpl
this.introduceeEngine = introduceeEngine; this.introduceeEngine = introduceeEngine;
this.crypto = crypto; this.crypto = crypto;
this.identityManager = identityManager; this.identityManager = identityManager;
this.localGroup =
contactGroupFactory.createLocalGroup(CLIENT_ID, CLIENT_VERSION);
} }
@Override @Override
public void createLocalState(Transaction txn) throws DbException { public void createLocalState(Transaction txn) throws DbException {
// Create a local group to store protocol sessions // Create a local group to store protocol sessions
Group localGroup = getLocalGroup();
if (db.containsGroup(txn, localGroup.getId())) return; if (db.containsGroup(txn, localGroup.getId())) return;
db.addGroup(txn, localGroup); db.addGroup(txn, localGroup);
// Set up groups for communication with any pre-existing contacts // Set up groups for communication with any pre-existing contacts
@@ -229,8 +232,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
if (sessionId == null) return null; if (sessionId == null) return null;
BdfDictionary query = sessionParser.getSessionQuery(sessionId); BdfDictionary query = sessionParser.getSessionQuery(sessionId);
Map<MessageId, BdfDictionary> results = clientHelper Map<MessageId, BdfDictionary> results = clientHelper
.getMessageMetadataAsDictionary(txn, getLocalGroup().getId(), .getMessageMetadataAsDictionary(txn, localGroup.getId(), query);
query);
if (results.size() > 1) throw new DbException(); if (results.size() > 1) throw new DbException();
if (results.isEmpty()) return null; if (results.isEmpty()) return null;
return new StoredSession(results.keySet().iterator().next(), return new StoredSession(results.keySet().iterator().next(),
@@ -246,7 +248,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
private MessageId createStorageId(Transaction txn) throws DbException { private MessageId createStorageId(Transaction txn) throws DbException {
Message m = clientHelper Message m = clientHelper
.createMessageForStoringMetadata(getLocalGroup().getId()); .createMessageForStoringMetadata(localGroup.getId());
db.addLocalMessage(txn, m, new Metadata(), false); db.addLocalMessage(txn, m, new Metadata(), false);
return m.getId(); return m.getId();
} }
@@ -274,22 +276,28 @@ class IntroductionManagerImpl extends ConversationClientImpl
public boolean canIntroduce(Contact c1, Contact c2) throws DbException { public boolean canIntroduce(Contact c1, Contact c2) throws DbException {
Transaction txn = db.startTransaction(true); Transaction txn = db.startTransaction(true);
try { try {
// Look up the session, if there is one boolean can = canIntroduce(txn, c1, c2);
Author introducer = identityManager.getLocalAuthor(txn); db.commitTransaction(txn);
SessionId sessionId = return can;
crypto.getSessionId(introducer, c1.getAuthor(),
c2.getAuthor());
StoredSession ss = getSession(txn, sessionId);
if (ss == null) return true;
IntroducerSession session =
sessionParser.parseIntroducerSession(ss.bdfSession);
if (session.getState() == START) return true;
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} finally { } finally {
db.endTransaction(txn); db.endTransaction(txn);
} }
return false; }
private boolean canIntroduce(Transaction txn, Contact c1, Contact c2)
throws DbException, FormatException {
// Look up the session, if there is one
Author introducer = identityManager.getLocalAuthor(txn);
SessionId sessionId =
crypto.getSessionId(introducer, c1.getAuthor(),
c2.getAuthor());
StoredSession ss = getSession(txn, sessionId);
if (ss == null) return true;
IntroducerSession session =
sessionParser.parseIntroducerSession(ss.bdfSession);
return session.getState() == START;
} }
@Override @Override
@@ -395,12 +403,12 @@ class IntroductionManagerImpl extends ConversationClientImpl
meta, status, ss.bdfSession)); meta, status, ss.bdfSession));
} else if (type == ACCEPT) { } else if (type == ACCEPT) {
messages.add( messages.add(
parseInvitationResponse(txn, contactGroupId, m, parseInvitationResponse(contactGroupId, m, meta,
meta, status, ss.bdfSession, true)); status, ss.bdfSession, true));
} else if (type == DECLINE) { } else if (type == DECLINE) {
messages.add( messages.add(
parseInvitationResponse(txn, contactGroupId, m, parseInvitationResponse(contactGroupId, m, meta,
meta, status, ss.bdfSession, false)); status, ss.bdfSession, false));
} }
} }
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -435,8 +443,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
author = session.getRemote().author; author = session.getRemote().author;
} else throw new AssertionError(); } else throw new AssertionError();
Message msg = clientHelper.getMessage(txn, m); Message msg = clientHelper.getMessage(txn, m);
BdfList body = clientHelper.getMessageAsList(txn, m); if (msg == null) throw new AssertionError();
if (msg == null || body == null) throw new AssertionError(); BdfList body = clientHelper.toList(msg);
RequestMessage rm = messageParser.parseRequestMessage(msg, body); RequestMessage rm = messageParser.parseRequestMessage(msg, body);
String message = rm.getMessage(); String message = rm.getMessage();
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
@@ -451,10 +459,9 @@ class IntroductionManagerImpl extends ConversationClientImpl
contactExists); contactExists);
} }
private IntroductionResponse parseInvitationResponse(Transaction txn, private IntroductionResponse parseInvitationResponse(GroupId contactGroupId,
GroupId contactGroupId, MessageId m, MessageMetadata meta, MessageId m, MessageMetadata meta, MessageStatus status,
MessageStatus status, BdfDictionary bdfSession, boolean accept) BdfDictionary bdfSession, boolean accept) throws FormatException {
throws FormatException, DbException {
Role role = sessionParser.getRole(bdfSession); Role role = sessionParser.getRole(bdfSession);
SessionId sessionId; SessionId sessionId;
Author author; Author author;
@@ -462,8 +469,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
IntroducerSession session = IntroducerSession session =
sessionParser.parseIntroducerSession(bdfSession); sessionParser.parseIntroducerSession(bdfSession);
sessionId = session.getSessionId(); sessionId = session.getSessionId();
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); if (contactGroupId.equals(session.getIntroduceeA().groupId)) {
if (localAuthor.equals(session.getIntroduceeA().author)) {
author = session.getIntroduceeB().author; author = session.getIntroduceeB().author;
} else { } else {
author = session.getIntroduceeA().author; author = session.getIntroduceeA().author;
@@ -485,13 +491,13 @@ class IntroductionManagerImpl extends ConversationClientImpl
.getIntroduceeSessionsByIntroducerQuery(introducer.getAuthor()); .getIntroduceeSessionsByIntroducerQuery(introducer.getAuthor());
Map<MessageId, BdfDictionary> sessions; Map<MessageId, BdfDictionary> sessions;
try { try {
sessions = clientHelper.getMessageMetadataAsDictionary(txn, sessions = clientHelper
getLocalGroup().getId(), query); .getMessageMetadataAsDictionary(txn, localGroup.getId(),
query);
} catch (FormatException e) { } catch (FormatException e) {
throw new AssertionError(e); throw new DbException(e);
} }
for (MessageId id : sessions.keySet()) { for (MessageId id : sessions.keySet()) {
db.deleteMessageMetadata(txn, id); // TODO needed?
db.removeMessage(txn, id); db.removeMessage(txn, id);
} }
} }
@@ -501,10 +507,11 @@ class IntroductionManagerImpl extends ConversationClientImpl
BdfDictionary query = sessionEncoder.getIntroducerSessionsQuery(); BdfDictionary query = sessionEncoder.getIntroducerSessionsQuery();
Map<MessageId, BdfDictionary> sessions; Map<MessageId, BdfDictionary> sessions;
try { try {
sessions = clientHelper.getMessageMetadataAsDictionary(txn, sessions = clientHelper
getLocalGroup().getId(), query); .getMessageMetadataAsDictionary(txn, localGroup.getId(),
query);
} catch (FormatException e) { } catch (FormatException e) {
throw new AssertionError(); throw new DbException();
} }
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
for (Entry<MessageId, BdfDictionary> session : sessions.entrySet()) { for (Entry<MessageId, BdfDictionary> session : sessions.entrySet()) {
@@ -512,7 +519,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
try { try {
s = sessionParser.parseIntroducerSession(session.getValue()); s = sessionParser.parseIntroducerSession(session.getValue());
} catch (FormatException e) { } catch (FormatException e) {
throw new AssertionError(); throw new DbException();
} }
if (s.getIntroduceeA().author.equals(c.getAuthor())) { if (s.getIntroduceeA().author.equals(c.getAuthor())) {
abortOrRemoveSessionWithIntroducee(txn, s, session.getKey(), abortOrRemoveSessionWithIntroducee(txn, s, session.getKey(),
@@ -531,15 +538,10 @@ class IntroductionManagerImpl extends ConversationClientImpl
IntroducerSession session = introducerEngine.onAbortAction(txn, s); IntroducerSession session = introducerEngine.onAbortAction(txn, s);
storeSession(txn, storageId, session); storeSession(txn, storageId, session);
} else { } else {
db.deleteMessageMetadata(txn, storageId); // TODO needed?
db.removeMessage(txn, storageId); db.removeMessage(txn, storageId);
} }
} }
private Group getLocalGroup() {
return contactGroupFactory.createLocalGroup(CLIENT_ID, CLIENT_VERSION);
}
private static class StoredSession { private static class StoredSession {
private final MessageId storageId; private final MessageId storageId;

View File

@@ -22,7 +22,6 @@ import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.plugin.TransportId.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.bramble.util.ValidationUtils.checkLength; import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize; import static org.briarproject.bramble.util.ValidationUtils.checkSize;
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH; import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH;
@@ -79,8 +78,8 @@ class IntroductionValidator extends BdfMessageValidator {
String msg = body.getOptionalString(3); String msg = body.getOptionalString(3);
checkLength(msg, 1, MAX_REQUEST_MESSAGE_LENGTH); checkLength(msg, 1, MAX_REQUEST_MESSAGE_LENGTH);
BdfDictionary meta = messageEncoder BdfDictionary meta =
.encodeRequestMetadata(m.getTimestamp(), false, false, false); messageEncoder.encodeRequestMetadata(m.getTimestamp());
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
@@ -103,15 +102,13 @@ class IntroductionValidator extends BdfMessageValidator {
byte[] ephemeralPublicKey = body.getRaw(3); byte[] ephemeralPublicKey = body.getRaw(3);
checkLength(ephemeralPublicKey, 0, MAX_PUBLIC_KEY_LENGTH); checkLength(ephemeralPublicKey, 0, MAX_PUBLIC_KEY_LENGTH);
body.getLong(4); long timestamp = body.getLong(4);
if (timestamp < 0) throw new FormatException();
BdfDictionary transportProperties = body.getDictionary(5); BdfDictionary transportProperties = body.getDictionary(5);
if (transportProperties.size() < 1) throw new FormatException(); if (transportProperties.size() < 1) throw new FormatException();
for (String tId : transportProperties.keySet()) { clientHelper
checkLength(tId, 1, MAX_TRANSPORT_ID_LENGTH); .parseAndValidateTransportPropertiesMap(transportProperties);
BdfDictionary tProps = transportProperties.getDictionary(tId);
clientHelper.parseAndValidateTransportProperties(tProps);
}
SessionId sessionId = new SessionId(sessionIdBytes); SessionId sessionId = new SessionId(sessionIdBytes);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder

View File

@@ -17,8 +17,7 @@ import javax.annotation.Nullable;
@NotNullByDefault @NotNullByDefault
interface MessageEncoder { interface MessageEncoder {
BdfDictionary encodeRequestMetadata(long timestamp, boolean local, BdfDictionary encodeRequestMetadata(long timestamp);
boolean read, boolean available);
BdfDictionary encodeMetadata(MessageType type, BdfDictionary encodeMetadata(MessageType type,
@Nullable SessionId sessionId, long timestamp, boolean local, @Nullable SessionId sessionId, long timestamp, boolean local,

View File

@@ -47,11 +47,10 @@ class MessageEncoderImpl implements MessageEncoder {
} }
@Override @Override
public BdfDictionary encodeRequestMetadata(long timestamp, public BdfDictionary encodeRequestMetadata(long timestamp) {
boolean local, boolean read, boolean available) {
BdfDictionary meta = BdfDictionary meta =
encodeMetadata(REQUEST, null, timestamp, local, read, false); encodeMetadata(REQUEST, null, timestamp, false, false, false);
meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, available); meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, false);
return meta; return meta;
} }

View File

@@ -11,23 +11,25 @@ import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
import org.junit.Test; import org.junit.Test;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap; import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap;
import static org.briarproject.bramble.util.StringUtils.fromHexString; import static org.briarproject.briar.introduction.IntroduceeSession.Local;
import static org.briarproject.briar.introduction.IntroduceeSession.Remote;
import static org.briarproject.briar.test.BriarTestUtils.getRealAuthor;
import static org.briarproject.briar.test.BriarTestUtils.getRealLocalAuthor;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class IntroductionCryptoImplTest extends BrambleTestCase { public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
@Inject @Inject
ClientHelper clientHelper; ClientHelper clientHelper;
@@ -42,33 +44,28 @@ public class IntroductionCryptoImplTest extends BrambleTestCase {
private final LocalAuthor alice, bob; private final LocalAuthor alice, bob;
private final long aliceAcceptTimestamp = 42L; private final long aliceAcceptTimestamp = 42L;
private final long bobAcceptTimestamp = 1337L; private final long bobAcceptTimestamp = 1337L;
private final SecretKey masterKey = private final SecretKey masterKey = getSecretKey();
new SecretKey(getRandomBytes(SecretKey.LENGTH));
private final KeyPair aliceEphemeral, bobEphemeral; private final KeyPair aliceEphemeral, bobEphemeral;
private final Map<TransportId, TransportProperties> aliceTransport = private final Map<TransportId, TransportProperties> aliceTransport =
getTransportPropertiesMap(3); getTransportPropertiesMap(3);
private final Map<TransportId, TransportProperties> bobTransport = private final Map<TransportId, TransportProperties> bobTransport =
getTransportPropertiesMap(3); getTransportPropertiesMap(3);
public IntroductionCryptoImplTest() { public IntroductionCryptoIntegrationTest() {
BriarIntegrationTestComponent component = IntroductionIntegrationTestComponent component =
DaggerBriarIntegrationTestComponent.builder().build(); DaggerIntroductionIntegrationTestComponent.builder().build();
component.inject(this); component.inject(this);
crypto = new IntroductionCryptoImpl(cryptoComponent, clientHelper); crypto = new IntroductionCryptoImpl(cryptoComponent, clientHelper);
// create actual deterministic authors for testing introducer = getRealAuthor(authorFactory);
introducer = authorFactory LocalAuthor introducee1 =
.createAuthor("Introducer", new byte[] {0x1, 0x2, 0x3}); getRealLocalAuthor(cryptoComponent, authorFactory);
alice = authorFactory.createLocalAuthor("Alice", LocalAuthor introducee2 =
fromHexString( getRealLocalAuthor(cryptoComponent, authorFactory);
"A626F080C94771698F86B4B4094C4F560904B53398805AE02BA2343F1829187A"), boolean isAlice =
fromHexString( crypto.isAlice(introducee1.getId(), introducee2.getId());
"60F010187AF91ACA15141E8C811EC8E79C7CAA6461C21A852BB03066C89B0A70")); alice = isAlice ? introducee1 : introducee2;
bob = authorFactory.createLocalAuthor("Bob", bob = isAlice ? introducee2 : introducee1;
fromHexString(
"A0D0FED1CE4674D8B6441AD0A664E41BF60D489F35DA11F52AF923540848546F"),
fromHexString(
"20B25BE7E999F68FE07189449E91984FA79121DBFF28A651669A3CF512D6A758"));
aliceEphemeral = crypto.generateKeyPair(); aliceEphemeral = crypto.generateKeyPair();
bobEphemeral = crypto.generateKeyPair(); bobEphemeral = crypto.generateKeyPair();
} }
@@ -78,6 +75,9 @@ public class IntroductionCryptoImplTest extends BrambleTestCase {
SessionId s1 = crypto.getSessionId(introducer, alice, bob); SessionId s1 = crypto.getSessionId(introducer, alice, bob);
SessionId s2 = crypto.getSessionId(introducer, bob, alice); SessionId s2 = crypto.getSessionId(introducer, bob, alice);
assertEquals(s1, s2); assertEquals(s1, s2);
SessionId s3 = crypto.getSessionId(alice, bob, introducer);
assertNotEquals(s1, s3);
} }
@Test @Test
@@ -88,62 +88,66 @@ public class IntroductionCryptoImplTest extends BrambleTestCase {
@Test @Test
public void testDeriveMasterKey() throws Exception { public void testDeriveMasterKey() throws Exception {
SecretKey aliceMasterKey = crypto.deriveMasterKey(alice.getPublicKey(), SecretKey aliceMasterKey =
alice.getPrivateKey(), bob.getPublicKey(), true); crypto.deriveMasterKey(aliceEphemeral.getPublic().getEncoded(),
SecretKey bobMasterKey = crypto.deriveMasterKey(bob.getPublicKey(), aliceEphemeral.getPrivate().getEncoded(),
bob.getPrivateKey(), alice.getPublicKey(), false); bobEphemeral.getPublic().getEncoded(), true);
SecretKey bobMasterKey =
crypto.deriveMasterKey(bobEphemeral.getPublic().getEncoded(),
bobEphemeral.getPrivate().getEncoded(),
aliceEphemeral.getPublic().getEncoded(), false);
assertArrayEquals(aliceMasterKey.getBytes(), bobMasterKey.getBytes()); assertArrayEquals(aliceMasterKey.getBytes(), bobMasterKey.getBytes());
} }
@Test @Test
public void testAliceAuthMac() throws Exception { public void testAliceAuthMac() throws Exception {
SecretKey aliceMacKey = crypto.deriveMacKey(masterKey, true); SecretKey aliceMacKey = crypto.deriveMacKey(masterKey, true);
Local local = new Local(true, null, -1,
aliceEphemeral.getPublic().getEncoded(),
aliceEphemeral.getPrivate().getEncoded(), aliceTransport,
aliceAcceptTimestamp, aliceMacKey.getBytes());
Remote remote = new Remote(false, bob, null,
bobEphemeral.getPublic().getEncoded(), bobTransport,
bobAcceptTimestamp, null);
byte[] aliceMac = byte[] aliceMac =
crypto.authMac(aliceMacKey, introducer.getId(), alice.getId(), crypto.authMac(aliceMacKey, introducer.getId(), alice.getId(),
bob.getId(), aliceAcceptTimestamp, bobAcceptTimestamp, local, remote);
aliceEphemeral.getPublic().getEncoded(),
bobEphemeral.getPublic().getEncoded(), aliceTransport,
bobTransport, true);
// verify from Bob's perspective
crypto.verifyAuthMac(aliceMac, aliceMacKey, introducer.getId(), crypto.verifyAuthMac(aliceMac, aliceMacKey, introducer.getId(),
bob.getId(), alice.getId(), bobAcceptTimestamp, bob.getId(), remote, alice.getId(), local);
aliceAcceptTimestamp, bobEphemeral.getPublic().getEncoded(),
aliceEphemeral.getPublic().getEncoded(), bobTransport,
aliceTransport, true);
} }
@Test @Test
public void testBobAuthMac() throws Exception { public void testBobAuthMac() throws Exception {
SecretKey bobMacKey = crypto.deriveMacKey(masterKey, false); SecretKey bobMacKey = crypto.deriveMacKey(masterKey, false);
Local local = new Local(false, null, -1,
bobEphemeral.getPublic().getEncoded(),
bobEphemeral.getPrivate().getEncoded(), bobTransport,
bobAcceptTimestamp, bobMacKey.getBytes());
Remote remote = new Remote(true, alice, null,
aliceEphemeral.getPublic().getEncoded(), aliceTransport,
aliceAcceptTimestamp, null);
byte[] bobMac = byte[] bobMac =
crypto.authMac(bobMacKey, introducer.getId(), bob.getId(), crypto.authMac(bobMacKey, introducer.getId(), bob.getId(),
alice.getId(), bobAcceptTimestamp, aliceAcceptTimestamp, local, remote);
bobEphemeral.getPublic().getEncoded(),
aliceEphemeral.getPublic().getEncoded(), bobTransport,
aliceTransport, false);
// verify from Alice's perspective
crypto.verifyAuthMac(bobMac, bobMacKey, introducer.getId(), crypto.verifyAuthMac(bobMac, bobMacKey, introducer.getId(),
alice.getId(), bob.getId(), aliceAcceptTimestamp, alice.getId(), remote, bob.getId(), local);
bobAcceptTimestamp, aliceEphemeral.getPublic().getEncoded(),
bobEphemeral.getPublic().getEncoded(), aliceTransport,
bobTransport, false);
} }
@Test @Test
public void testSign() throws Exception { public void testSign() throws Exception {
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
SecretKey macKey = crypto.deriveMacKey(masterKey, true); SecretKey macKey = crypto.deriveMacKey(masterKey, true);
byte[] signature = byte[] signature = crypto.sign(macKey, alice.getPrivateKey());
crypto.sign(macKey, keyPair.getPrivate().getEncoded()); crypto.verifySignature(macKey, alice.getPublicKey(), signature);
crypto.verifySignature(macKey, keyPair.getPublic().getEncoded(),
signature);
} }
@Test @Test
public void testAliceActivateMac() throws Exception { public void testAliceActivateMac() throws Exception {
SecretKey aliceMacKey = crypto.deriveMacKey(masterKey, true); SecretKey aliceMacKey = crypto.deriveMacKey(masterKey, true);
byte[] aliceMac = crypto.activateMac(aliceMacKey); byte[] aliceMac = crypto.activateMac(aliceMacKey);
crypto.verifyActivateMac(aliceMac, aliceMacKey); crypto.verifyActivateMac(aliceMac, aliceMacKey);
} }
@@ -151,7 +155,6 @@ public class IntroductionCryptoImplTest extends BrambleTestCase {
public void testBobActivateMac() throws Exception { public void testBobActivateMac() throws Exception {
SecretKey bobMacKey = crypto.deriveMacKey(masterKey, false); SecretKey bobMacKey = crypto.deriveMacKey(masterKey, false);
byte[] bobMac = crypto.activateMac(bobMacKey); byte[] bobMac = crypto.activateMac(bobMacKey);
crypto.verifyActivateMac(bobMac, bobMacKey); crypto.verifyActivateMac(bobMac, bobMacKey);
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.introduction; package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -10,7 +9,7 @@ import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.api.introduction.IntroductionConstants.LABEL_SESSION_ID; import static org.briarproject.briar.api.introduction.IntroductionConstants.LABEL_SESSION_ID;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -25,7 +24,7 @@ public class IntroductionCryptoTest extends BrambleMockTestCase {
private final Author introducer = getAuthor(); private final Author introducer = getAuthor();
private final Author alice = getAuthor(), bob = getAuthor(); private final Author alice = getAuthor(), bob = getAuthor();
private final byte[] hash = getRandomBytes(UniqueId.LENGTH); private final byte[] hash = getRandomId();
@Test @Test
public void testGetSessionId() { public void testGetSessionId() {

View File

@@ -634,7 +634,7 @@ public class IntroductionIntegrationTest
// fake a second ACCEPT message from introducee1 // fake a second ACCEPT message from introducee1
Message msg = c1.getMessageEncoder() Message msg = c1.getMessageEncoder()
.encodeAcceptMessage(m.getGroupId(), clock.currentTimeMillis(), .encodeAcceptMessage(m.getGroupId(), m.getTimestamp() + 1,
m.getMessageId(), m.getSessionId(), m.getMessageId(), m.getSessionId(),
m.getEphemeralPublicKey(), m.getAcceptTimestamp(), m.getEphemeralPublicKey(), m.getAcceptTimestamp(),
m.getTransportProperties()); m.getTransportProperties());
@@ -671,7 +671,7 @@ public class IntroductionIntegrationTest
// fake a second DECLINE message also from introducee1 // fake a second DECLINE message also from introducee1
Message msg = c1.getMessageEncoder() Message msg = c1.getMessageEncoder()
.encodeDeclineMessage(m.getGroupId(), clock.currentTimeMillis(), .encodeDeclineMessage(m.getGroupId(), m.getTimestamp() + 1,
m.getMessageId(), m.getSessionId()); m.getMessageId(), m.getSessionId());
c1.getClientHelper().addLocalMessage(msg, new BdfDictionary(), true); c1.getClientHelper().addLocalMessage(msg, new BdfDictionary(), true);
@@ -715,7 +715,7 @@ public class IntroductionIntegrationTest
// fake a second AUTH message also from introducee1 // fake a second AUTH message also from introducee1
Message msg = c1.getMessageEncoder() Message msg = c1.getMessageEncoder()
.encodeAuthMessage(m.getGroupId(), clock.currentTimeMillis(), .encodeAuthMessage(m.getGroupId(), m.getTimestamp() + 1,
m.getMessageId(), m.getSessionId(), m.getMac(), m.getMessageId(), m.getSessionId(), m.getMac(),
m.getSignature()); m.getSignature());
c1.getClientHelper().addLocalMessage(msg, new BdfDictionary(), true); c1.getClientHelper().addLocalMessage(msg, new BdfDictionary(), true);

View File

@@ -59,6 +59,10 @@ interface IntroductionIntegrationTestComponent
void inject(IntroductionIntegrationTest init); void inject(IntroductionIntegrationTest init);
void inject(MessageEncoderParserIntegrationTest init);
void inject(SessionEncoderParserIntegrationTest init);
void inject(IntroductionCryptoIntegrationTest init);
MessageEncoder getMessageEncoder(); MessageEncoder getMessageEncoder();
MessageParser getMessageParser(); MessageParser getMessageParser();
SessionParser getSessionParser(); SessionParser getSessionParser();

View File

@@ -126,8 +126,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH), previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
acceptTimestamp, transportProperties); acceptTimestamp, transportProperties);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateTransportProperties( oneOf(clientHelper).parseAndValidateTransportPropertiesMap(
transportProperties.getDictionary("transportId")); transportProperties);
}}); }});
expectEncodeMetadata(ACCEPT); expectEncodeMetadata(ACCEPT);
BdfMessageContext messageContext = BdfMessageContext messageContext =
@@ -178,6 +178,14 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@Test(expected = FormatException.class)
public void testRejectsNegativeTimestampForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
-1, transportProperties);
validator.validateMessage(message, group, body);
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsEmptyTransportPropertiesForAccept() public void testRejectsEmptyTransportPropertiesForAccept()
throws Exception { throws Exception {
@@ -405,9 +413,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
private void expectEncodeRequestMetadata() { private void expectEncodeRequestMetadata() {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(messageEncoder) oneOf(messageEncoder).encodeRequestMetadata(message.getTimestamp());
.encodeRequestMetadata(message.getTimestamp(), false, false,
false);
will(returnValue(meta)); will(returnValue(meta));
}}); }});
} }

View File

@@ -16,8 +16,6 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
import org.junit.Test; import org.junit.Test;
import java.util.Map; import java.util.Map;
@@ -72,8 +70,8 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES); private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES);
public MessageEncoderParserIntegrationTest() { public MessageEncoderParserIntegrationTest() {
BriarIntegrationTestComponent component = IntroductionIntegrationTestComponent component =
DaggerBriarIntegrationTestComponent.builder().build(); DaggerIntroductionIntegrationTestComponent.builder().build();
component.inject(this); component.inject(this);
messageEncoder = new MessageEncoderImpl(clientHelper, messageFactory); messageEncoder = new MessageEncoderImpl(clientHelper, messageFactory);
@@ -86,13 +84,13 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
@Test @Test
public void testRequestMessageMetadata() throws FormatException { public void testRequestMessageMetadata() throws FormatException {
BdfDictionary d = messageEncoder BdfDictionary d = messageEncoder
.encodeRequestMetadata(timestamp, true, false, false); .encodeRequestMetadata(timestamp);
MessageMetadata meta = messageParser.parseMetadata(d); MessageMetadata meta = messageParser.parseMetadata(d);
assertEquals(REQUEST, meta.getMessageType()); assertEquals(REQUEST, meta.getMessageType());
assertNull(meta.getSessionId()); assertNull(meta.getSessionId());
assertEquals(timestamp, meta.getTimestamp()); assertEquals(timestamp, meta.getTimestamp());
assertTrue(meta.isLocal()); assertFalse(meta.isLocal());
assertFalse(meta.isRead()); assertFalse(meta.isRead());
assertFalse(meta.isVisibleInConversation()); assertFalse(meta.isVisibleInConversation());
assertFalse(meta.isAvailableToAnswer()); assertFalse(meta.isAvailableToAnswer());

View File

@@ -7,13 +7,12 @@ import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageFactory; import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH; import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH;
@@ -28,11 +27,9 @@ public class MessageEncoderTest extends BrambleMockTestCase {
new MessageEncoderImpl(clientHelper, messageFactory); new MessageEncoderImpl(clientHelper, messageFactory);
private final GroupId groupId = new GroupId(getRandomId()); private final GroupId groupId = new GroupId(getRandomId());
private final long timestamp = 42L; private final Message message = getMessage(groupId);
private final Message message = private final long timestamp = message.getTimestamp();
new Message(new MessageId(getRandomId()), groupId, timestamp, private final byte[] body = message.getRaw();
getRandomBytes(48));
private final byte[] body = getRandomBytes(42);
private final Author author = getAuthor(); private final Author author = getAuthor();
private final BdfList authorList = new BdfList(); private final BdfList authorList = new BdfList();
private final String text = getRandomString(MAX_REQUEST_MESSAGE_LENGTH); private final String text = getRandomString(MAX_REQUEST_MESSAGE_LENGTH);

View File

@@ -14,8 +14,6 @@ import org.briarproject.bramble.api.transport.KeySetId;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.introduction.IntroducerSession.Introducee; import org.briarproject.briar.introduction.IntroducerSession.Introducee;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
import org.junit.Test; import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;
@@ -82,8 +80,8 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
private final byte[] remoteMacKey = getRandomBytes(SecretKey.LENGTH); private final byte[] remoteMacKey = getRandomBytes(SecretKey.LENGTH);
public SessionEncoderParserIntegrationTest() { public SessionEncoderParserIntegrationTest() {
BriarIntegrationTestComponent component = IntroductionIntegrationTestComponent component =
DaggerBriarIntegrationTestComponent.builder().build(); DaggerIntroductionIntegrationTestComponent.builder().build();
component.inject(this); component.inject(this);
sessionEncoder = new SessionEncoderImpl(clientHelper); sessionEncoder = new SessionEncoderImpl(clientHelper);

View File

@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.properties.TransportPropertyManager;
import org.briarproject.bramble.api.sync.SyncSessionFactory; import org.briarproject.bramble.api.sync.SyncSessionFactory;
import org.briarproject.bramble.api.transport.KeyManager;
import org.briarproject.bramble.client.ClientModule; import org.briarproject.bramble.client.ClientModule;
import org.briarproject.bramble.contact.ContactModule; import org.briarproject.bramble.contact.ContactModule;
import org.briarproject.bramble.crypto.CryptoModule; import org.briarproject.bramble.crypto.CryptoModule;
@@ -37,8 +36,8 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager
import org.briarproject.briar.blog.BlogModule; import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.client.BriarClientModule; import org.briarproject.briar.client.BriarClientModule;
import org.briarproject.briar.forum.ForumModule; import org.briarproject.briar.forum.ForumModule;
import org.briarproject.briar.introduction.IntroductionCryptoIntegrationTest;
import org.briarproject.briar.introduction.IntroductionModule; import org.briarproject.briar.introduction.IntroductionModule;
import org.briarproject.briar.introduction.IntroductionCryptoImplTest;
import org.briarproject.briar.introduction.MessageEncoderParserIntegrationTest; import org.briarproject.briar.introduction.MessageEncoderParserIntegrationTest;
import org.briarproject.briar.introduction.SessionEncoderParserIntegrationTest; import org.briarproject.briar.introduction.SessionEncoderParserIntegrationTest;
import org.briarproject.briar.messaging.MessagingModule; import org.briarproject.briar.messaging.MessagingModule;
@@ -80,10 +79,6 @@ public interface BriarIntegrationTestComponent {
void inject(BriarIntegrationTest<BriarIntegrationTestComponent> init); void inject(BriarIntegrationTest<BriarIntegrationTestComponent> init);
void inject(MessageEncoderParserIntegrationTest init);
void inject(SessionEncoderParserIntegrationTest init);
void inject(IntroductionCryptoImplTest init);
void inject(BlogModule.EagerSingletons init); void inject(BlogModule.EagerSingletons init);
void inject(ContactModule.EagerSingletons init); void inject(ContactModule.EagerSingletons init);
@@ -146,8 +141,6 @@ public interface BriarIntegrationTestComponent {
TransportPropertyManager getTransportPropertyManager(); TransportPropertyManager getTransportPropertyManager();
KeyManager getKeyManager();
AuthorFactory getAuthorFactory(); AuthorFactory getAuthorFactory();
BlogFactory getBlogFactory(); BlogFactory getBlogFactory();

View File

@@ -1,8 +1,11 @@
package org.briarproject.briar.test; package org.briarproject.briar.test;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.MessageTracker.GroupCount; import org.briarproject.briar.api.client.MessageTracker.GroupCount;
@@ -35,4 +38,12 @@ public class BriarTestUtils {
getRandomBytes(MAX_PUBLIC_KEY_LENGTH)); getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
} }
public static LocalAuthor getRealLocalAuthor(
CryptoComponent cryptoComponent, AuthorFactory authorFactory) {
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
return authorFactory.createLocalAuthor(getRandomString(5),
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
}
} }