Refactor KeyManager and TagRecogniser. #55

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

View File

@@ -1,36 +0,0 @@
package org.briarproject.api.transport;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
public class Endpoint {
protected final ContactId contactId;
protected final TransportId transportId;
private final long epoch;
private final boolean alice;
public Endpoint(ContactId contactId, TransportId transportId, long epoch,
boolean alice) {
this.contactId = contactId;
this.transportId = transportId;
this.epoch = epoch;
this.alice = alice;
}
public ContactId getContactId() {
return contactId;
}
public TransportId getTransportId() {
return transportId;
}
public long getEpoch() {
return epoch;
}
public boolean getAlice() {
return alice;
}
}

View File

@@ -0,0 +1,51 @@
package org.briarproject.api.transport;
import org.briarproject.api.crypto.SecretKey;
import static org.briarproject.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
/**
* Contains transport keys for receiving streams from a given contact over a
* given transport in a given rotation period.
*/
public class IncomingKeys {
private final SecretKey tagKey, headerKey;
private final long rotationPeriod, windowBase;
private final byte[] windowBitmap;
public IncomingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod) {
this(tagKey, headerKey, rotationPeriod, 0,
new byte[REORDERING_WINDOW_SIZE / 8]);
}
public IncomingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod, long windowBase, byte[] windowBitmap) {
this.tagKey = tagKey;
this.headerKey = headerKey;
this.rotationPeriod = rotationPeriod;
this.windowBase = windowBase;
this.windowBitmap = windowBitmap;
}
public SecretKey getTagKey() {
return tagKey;
}
public SecretKey getHeaderKey() {
return headerKey;
}
public long getRotationPeriod() {
return rotationPeriod;
}
public long getWindowBase() {
return windowBase;
}
public byte[] getWindowBitmap() {
return windowBitmap;
}
}

View File

@@ -0,0 +1,36 @@
package org.briarproject.api.transport;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.Service;
import java.util.Collection;
/**
* Responsible for managing transport keys and recognising the pseudo-random
* tags of incoming streams.
*/
public interface KeyManager extends Service {
/**
* Informs the key manager that a new contact has been added.
* {@link StreamContext StreamContexts} for the contact can be created
* after this method has returned.
*/
void contactAdded(ContactId c, Collection<TransportKeys> keys);
/**
* Returns a {@link StreamContext} for sending a stream to the given
* contact over the given transport, or null if an error occurs or the
* contact does not support the transport.
*/
StreamContext getStreamContext(ContactId c, TransportId t);
/**
* Looks up the given tag and returns a {@link StreamContext} for reading
* from the corresponding stream if the tag was expected, or null if the
* tag was unexpected.
*/
StreamContext recogniseTag(TransportId t, byte[] tag) throws DbException;
}

View File

@@ -0,0 +1,42 @@
package org.briarproject.api.transport;
import org.briarproject.api.crypto.SecretKey;
/**
* Contains transport keys for sending streams to a given contact over a given
* transport in a given rotation period.
*/
public class OutgoingKeys {
private final SecretKey tagKey, headerKey;
private final long rotationPeriod, streamCounter;
public OutgoingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod) {
this(tagKey, headerKey, rotationPeriod, 0);
}
public OutgoingKeys(SecretKey tagKey, SecretKey headerKey,
long rotationPeriod, long streamCounter) {
this.tagKey = tagKey;
this.headerKey = headerKey;
this.rotationPeriod = rotationPeriod;
this.streamCounter = streamCounter;
}
public SecretKey getTagKey() {
return tagKey;
}
public SecretKey getHeaderKey() {
return headerKey;
}
public long getRotationPeriod() {
return rotationPeriod;
}
public long getStreamCounter() {
return streamCounter;
}
}

View File

@@ -2,22 +2,22 @@ package org.briarproject.api.transport;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
import org.briarproject.api.crypto.SecretKey;
public class StreamContext {
private final ContactId contactId;
private final TransportId transportId;
private final byte[] secret;
private final SecretKey tagKey, headerKey;
private final long streamNumber;
private final boolean alice;
public StreamContext(ContactId contactId, TransportId transportId,
byte[] secret, long streamNumber, boolean alice) {
SecretKey tagKey, SecretKey headerKey, long streamNumber) {
this.contactId = contactId;
this.transportId = transportId;
this.secret = secret;
this.tagKey = tagKey;
this.headerKey = headerKey;
this.streamNumber = streamNumber;
this.alice = alice;
}
public ContactId getContactId() {
@@ -28,15 +28,15 @@ public class StreamContext {
return transportId;
}
public byte[] getSecret() {
return secret;
public SecretKey getTagKey() {
return tagKey;
}
public SecretKey getHeaderKey() {
return headerKey;
}
public long getStreamNumber() {
return streamNumber;
}
public boolean getAlice() {
return alice;
}
}

View File

@@ -2,6 +2,8 @@ package org.briarproject.api.transport;
import java.io.InputStream;
import org.briarproject.api.crypto.SecretKey;
public interface StreamReaderFactory {
/**
@@ -15,5 +17,5 @@ public interface StreamReaderFactory {
* invitation stream.
*/
InputStream createInvitationStreamReader(InputStream in,
byte[] secret, boolean alice);
SecretKey headerKey);
}

View File

@@ -2,6 +2,8 @@ package org.briarproject.api.transport;
import java.io.OutputStream;
import org.briarproject.api.crypto.SecretKey;
public interface StreamWriterFactory {
/**
@@ -15,5 +17,5 @@ public interface StreamWriterFactory {
* invitation stream.
*/
OutputStream createInvitationStreamWriter(OutputStream out,
byte[] secret, boolean alice);
SecretKey headerKey);
}

View File

@@ -1,26 +0,0 @@
package org.briarproject.api.transport;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
import org.briarproject.api.db.DbException;
/** Keeps track of expected tags and uses them to recognise incoming streams. */
public interface TagRecogniser {
/**
* Looks up the given tag and returns a {@link StreamContext} for reading
* from the stream if the tag was expected, or null if the tag was
* unexpected.
*/
StreamContext recogniseTag(TransportId t, byte[] tag) throws DbException;
void addSecret(TemporarySecret s);
void removeSecret(ContactId c, TransportId t, long period);
void removeSecrets(ContactId c);
void removeSecrets(TransportId t);
void removeSecrets();
}

View File

@@ -1,73 +0,0 @@
package org.briarproject.api.transport;
import static org.briarproject.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
public class TemporarySecret extends Endpoint {
private final long period, outgoing, centre;
private final byte[] secret, bitmap;
/** Creates a temporary secret with the given reordering window. */
public TemporarySecret(ContactId contactId, TransportId transportId,
long epoch, boolean alice, long period, byte[] secret,
long outgoing, long centre, byte[] bitmap) {
super(contactId, transportId, epoch, alice);
this.period = period;
this.secret = secret;
this.outgoing = outgoing;
this.centre = centre;
this.bitmap = bitmap;
}
/** Creates a temporary secret with a new reordering window. */
public TemporarySecret(ContactId contactId, TransportId transportId,
long epoch, boolean alice, long period, byte[] secret) {
this(contactId, transportId, epoch, alice, period, secret, 0, 0,
new byte[REORDERING_WINDOW_SIZE / 8]);
}
/** Creates a temporary secret derived from the given endpoint. */
public TemporarySecret(Endpoint ep, long period, byte[] secret) {
this(ep.getContactId(), ep.getTransportId(), ep.getEpoch(),
ep.getAlice(), period, secret);
}
public long getPeriod() {
return period;
}
public byte[] getSecret() {
return secret;
}
public long getOutgoingStreamCounter() {
return outgoing;
}
public long getWindowCentre() {
return centre;
}
public byte[] getWindowBitmap() {
return bitmap;
}
@Override
public int hashCode() {
int periodHashCode = (int) (period ^ (period >>> 32));
return contactId.hashCode() ^ transportId.hashCode() ^ periodHashCode;
}
@Override
public boolean equals(Object o) {
if (o instanceof TemporarySecret) {
TemporarySecret s = (TemporarySecret) o;
return contactId.equals(s.contactId) &&
transportId.equals(s.transportId) && period == s.period;
}
return false;
}
}

View File

@@ -28,8 +28,8 @@ public interface TransportConstants {
*/
int MIN_STREAM_LENGTH = 64 * 1024; // 64 KiB
/** The maximum difference between two communicating devices' clocks. */
int MAX_CLOCK_DIFFERENCE = 60 * 60 * 1000; // 1 hour
/** The maximum difference in milliseconds between two peers' clocks. */
int MAX_CLOCK_DIFFERENCE = 24 * 60 * 60 * 1000; // 24 hours
/** The size of the reordering window. */
int REORDERING_WINDOW_SIZE = 32;

View File

@@ -0,0 +1,44 @@
package org.briarproject.api.transport;
import org.briarproject.api.TransportId;
/** Keys for communicating with a given contact over a given transport. */
public class TransportKeys {
private final TransportId transportId;
private final IncomingKeys inPrev, inCurr, inNext;
private final OutgoingKeys outCurr;
public TransportKeys(TransportId transportId, IncomingKeys inPrev,
IncomingKeys inCurr, IncomingKeys inNext, OutgoingKeys outCurr) {
this.transportId = transportId;
this.inPrev = inPrev;
this.inCurr = inCurr;
this.inNext = inNext;
this.outCurr = outCurr;
}
public TransportId getTransportId() {
return transportId;
}
public IncomingKeys getPreviousIncomingKeys() {
return inPrev;
}
public IncomingKeys getCurrentIncomingKeys() {
return inCurr;
}
public IncomingKeys getNextIncomingKeys() {
return inNext;
}
public OutgoingKeys getCurrentOutgoingKeys() {
return outCurr;
}
public long getRotationPeriod() {
return outCurr.getRotationPeriod();
}
}