Skip to content
Snippets Groups Projects
Commit 6da30ca4 authored by akwizgran's avatar akwizgran
Browse files

Plan B: Remove error correction and reliability layers and the

consequent distinction between segments and frames.
parent 899ec5e1
No related branches found
No related tags found
No related merge requests found
Showing
with 23 additions and 322 deletions
...@@ -9,10 +9,10 @@ import javax.crypto.Mac; ...@@ -9,10 +9,10 @@ import javax.crypto.Mac;
public interface CryptoComponent { public interface CryptoComponent {
ErasableKey deriveSegmentKey(byte[] secret, boolean initiator);
ErasableKey deriveTagKey(byte[] secret, boolean initiator); ErasableKey deriveTagKey(byte[] secret, boolean initiator);
ErasableKey deriveFrameKey(byte[] secret, boolean initiator);
ErasableKey deriveMacKey(byte[] secret, boolean initiator); ErasableKey deriveMacKey(byte[] secret, boolean initiator);
byte[] deriveNextSecret(byte[] secret, int index, long connection); byte[] deriveNextSecret(byte[] secret, int index, long connection);
...@@ -27,11 +27,11 @@ public interface CryptoComponent { ...@@ -27,11 +27,11 @@ public interface CryptoComponent {
SecureRandom getSecureRandom(); SecureRandom getSecureRandom();
Cipher getSegmentCipher(); Cipher getTagCipher();
Cipher getFrameCipher();
Signature getSignature(); Signature getSignature();
Cipher getTagCipher();
Mac getMac(); Mac getMac();
} }
package net.sf.briar.api.plugins;
import java.io.IOException;
import net.sf.briar.api.transport.Segment;
public interface SegmentSink {
/** Writes the given segment. */
void writeSegment(Segment s) throws IOException;
/**
* Returns the maximum length in bytes of the segments this sink accepts.
*/
int getMaxSegmentLength();
}
package net.sf.briar.api.plugins;
import java.io.IOException;
import net.sf.briar.api.transport.Segment;
public interface SegmentSource {
/**
* Attempts to read a segment into the given buffer and returns true if a
* segment was read, or false if no more segments can be read.
*/
boolean readSegment(Segment s) throws IOException;
/**
* Returns the maximum length in bytes of the segments this source returns.
*/
int getMaxSegmentLength();
}
package net.sf.briar.api.plugins.duplex;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.plugins.Plugin;
/**
* An interface for transport plugins that support duplex segmented
* communication.
*/
public interface DuplexSegmentedPlugin extends Plugin {
/**
* Attempts to create and return a connection to the given contact using
* the current transport and configuration properties. Returns null if a
* connection could not be created.
*/
DuplexSegmentedTransportConnection createConnection(ContactId c);
/**
* Starts the invitation process from the inviter's side. Returns null if
* no connection can be established within the given timeout.
*/
DuplexSegmentedTransportConnection sendInvitation(int code, long timeout);
/**
* Starts the invitation process from the invitee's side. Returns null if
* no connection can be established within the given timeout.
*/
DuplexSegmentedTransportConnection acceptInvitation(int code, long timeout);
}
package net.sf.briar.api.plugins.duplex;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.plugins.PluginCallback;
/**
* An interface for handling connections created by a duplex segmented
* transport plugin.
*/
public interface DuplexSegmentedPluginCallback extends PluginCallback {
void incomingConnectionCreated(DuplexSegmentedTransportConnection d);
void outgoingConnectionCreated(ContactId c,
DuplexSegmentedTransportConnection d);
}
package net.sf.briar.api.plugins.duplex;
import java.util.concurrent.Executor;
public interface DuplexSegmentedPluginFactory {
DuplexSegmentedPlugin createPlugin(Executor pluginExecutor,
DuplexSegmentedPluginCallback callback);
}
package net.sf.briar.api.plugins.duplex;
import net.sf.briar.api.plugins.SegmentSink;
import net.sf.briar.api.plugins.SegmentSource;
/**
* An interface for reading and writing data over a duplex segmented transport.
* The connection is not responsible for encrypting/decrypting or authenticating
* the data.
*/
public interface DuplexSegmentedTransportConnection extends SegmentSource,
SegmentSink {
/** Returns the maximum length of a segment in bytes. */
int getMaximumSegmentLength();
/**
* Returns true if the output stream should be flushed after each packet.
*/
boolean shouldFlush();
/**
* Closes the connection and disposes of any associated resources. The
* first argument indicates whether the connection is being closed because
* of an exception and the second argument indicates whether the connection
* was recognised, which may affect how resources are disposed of.
*/
void dispose(boolean exception, boolean recognised);
}
package net.sf.briar.api.plugins.simplex;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.plugins.Plugin;
/**
* An interface for transport plugins that support simplex segmented
* communication.
*/
public interface SimplexSegmentedPlugin extends Plugin {
/**
* Attempts to create and return a reader for the given contact using the
* current transport and configuration properties. Returns null if a reader
* could not be created.
*/
SimplexSegmentedTransportReader createReader(ContactId c);
/**
* Attempts to create and return a writer for the given contact using the
* current transport and configuration properties. Returns null if a writer
* could not be created.
*/
SimplexSegmentedTransportWriter createWriter(ContactId c);
/**
* Starts the invitation process from the inviter's side. Returns null if
* no connection can be established within the given timeout.
*/
SimplexSegmentedTransportWriter sendInvitation(int code, long timeout);
/**
* Starts the invitation process from the invitee's side. Returns null if
* no connection can be established within the given timeout.
*/
SimplexSegmentedTransportReader acceptInvitation(int code, long timeout);
/**
* Continues the invitation process from the invitee's side. Returns null
* if no connection can be established within the given timeout.
*/
SimplexSegmentedTransportWriter sendInvitationResponse(int code,
long timeout);
/**
* Continues the invitation process from the inviter's side. Returns null
* if no connection can be established within the given timeout.
*/
SimplexSegmentedTransportReader acceptInvitationResponse(int code,
long timeout);
}
package net.sf.briar.api.plugins.simplex;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.plugins.PluginCallback;
/**
* An interface for handling readers and writers created by a simplex
* segmented transport plugin.
*/
public interface SimplexSegmentedPluginCallback extends PluginCallback {
void readerCreated(SimplexSegmentedTransportReader r);
void writerCreated(ContactId c, SimplexSegmentedTransportWriter w);
}
package net.sf.briar.api.plugins.simplex;
import java.util.concurrent.Executor;
public interface SimplexSegmentedPluginFactory {
SimplexSegmentedPlugin createPlugin(Executor pluginExecutor,
SimplexSegmentedPluginCallback callback);
}
package net.sf.briar.api.plugins.simplex;
import net.sf.briar.api.plugins.SegmentSource;
/**
* An interface for reading data from a simplex segmented transport. The reader
* is not responsible for decrypting or authenticating the data before
* returning it.
*/
public interface SimplexSegmentedTransportReader extends SegmentSource {
/**
* Closes the reader and disposes of any associated resources. The first
* argument indicates whether the reader is being closed because of an
* exception and the second argument indicates whether the connection was
* recognised, which may affect how resources are disposed of.
*/
void dispose(boolean exception, boolean recognised);
}
package net.sf.briar.api.plugins.simplex;
import net.sf.briar.api.plugins.SegmentSink;
/**
* An interface for writing data to a simplex segmented transport. The writer is
* not responsible for authenticating or encrypting the data before writing it.
*/
public interface SimplexSegmentedTransportWriter extends SegmentSink {
/** Returns the capacity of the transport in bytes. */
long getCapacity();
/** Returns the maximum length of a segment in bytes. */
int getMaximumSegmentLength();
/**
* Returns true if the output stream should be flushed after each packet.
*/
boolean shouldFlush();
/**
* Closes the writer and disposes of any associated resources. The
* argument indicates whether the writer is being closed because of an
* exception, which may affect how resources are disposed of.
*/
void dispose(boolean exception);
}
...@@ -9,7 +9,7 @@ import net.sf.briar.api.transport.ConnectionContext; ...@@ -9,7 +9,7 @@ import net.sf.briar.api.transport.ConnectionContext;
public interface DuplexConnectionFactory { public interface DuplexConnectionFactory {
void createIncomingConnection(ConnectionContext ctx, TransportId t, void createIncomingConnection(ConnectionContext ctx, TransportId t,
DuplexTransportConnection d, byte[] tag); DuplexTransportConnection d);
void createOutgoingConnection(ContactId c, TransportId t, TransportIndex i, void createOutgoingConnection(ContactId c, TransportId t, TransportIndex i,
DuplexTransportConnection d); DuplexTransportConnection d);
......
...@@ -10,7 +10,7 @@ import net.sf.briar.api.transport.ConnectionContext; ...@@ -10,7 +10,7 @@ import net.sf.briar.api.transport.ConnectionContext;
public interface SimplexConnectionFactory { public interface SimplexConnectionFactory {
void createIncomingConnection(ConnectionContext ctx, TransportId t, void createIncomingConnection(ConnectionContext ctx, TransportId t,
SimplexTransportReader r, byte[] tag); SimplexTransportReader r);
void createOutgoingConnection(ContactId c, TransportId t, TransportIndex i, void createOutgoingConnection(ContactId c, TransportId t, TransportIndex i,
SimplexTransportWriter w); SimplexTransportWriter w);
......
...@@ -2,35 +2,12 @@ package net.sf.briar.api.transport; ...@@ -2,35 +2,12 @@ package net.sf.briar.api.transport;
import java.io.InputStream; import java.io.InputStream;
import net.sf.briar.api.plugins.SegmentSource;
public interface ConnectionReaderFactory { public interface ConnectionReaderFactory {
/** /**
* Creates a connection reader for a simplex connection or the initiator's * Creates a connection reader for a simplex connection or one side of a
* side of a duplex connection. The secret is erased before this method * duplex connection. The secret is erased before this method returns.
* returns.
*/ */
ConnectionReader createConnectionReader(InputStream in, byte[] secret, ConnectionReader createConnectionReader(InputStream in, byte[] secret,
byte[] bufferedTag); boolean initiator);
/**
* Creates a connection reader for a simplex connection or the initiator's
* side of a duplex connection. The secret is erased before this method
* returns.
*/
ConnectionReader createConnectionReader(SegmentSource in, byte[] secret,
Segment bufferedSegment);
/**
* Creates a connection reader for the responder's side of a duplex
* connection. The secret is erased before this method returns.
*/
ConnectionReader createConnectionReader(InputStream in, byte[] secret);
/**
* Creates a connection reader for the responder's side of a duplex
* connection. The secret is erased before this method returns.
*/
ConnectionReader createConnectionReader(SegmentSource in, byte[] secret);
} }
...@@ -2,8 +2,6 @@ package net.sf.briar.api.transport; ...@@ -2,8 +2,6 @@ package net.sf.briar.api.transport;
import java.io.OutputStream; import java.io.OutputStream;
import net.sf.briar.api.plugins.SegmentSink;
public interface ConnectionWriterFactory { public interface ConnectionWriterFactory {
/** /**
...@@ -12,11 +10,4 @@ public interface ConnectionWriterFactory { ...@@ -12,11 +10,4 @@ public interface ConnectionWriterFactory {
*/ */
ConnectionWriter createConnectionWriter(OutputStream out, long capacity, ConnectionWriter createConnectionWriter(OutputStream out, long capacity,
byte[] secret, boolean initiator); byte[] secret, boolean initiator);
/**
* Creates a connection writer for a simplex connection or one side of a
* duplex connection. The secret is erased before this method returns.
*/
ConnectionWriter createConnectionWriter(SegmentSink out, long capacity,
byte[] secret, boolean initiator);
} }
package net.sf.briar.api.transport;
public interface Segment {
byte[] getBuffer();
int getLength();
long getSegmentNumber();
void setLength(int length);
void setSegmentNumber(long segmentNumber);
}
...@@ -2,21 +2,15 @@ package net.sf.briar.api.transport; ...@@ -2,21 +2,15 @@ package net.sf.briar.api.transport;
public interface TransportConstants { public interface TransportConstants {
/** The maximum length of a segment in bytes, including the tag. */ /** The length of the connection tag in bytes. */
static final int MAX_SEGMENT_LENGTH = 65536; // 2^16, 64 KiB
/** The length of the segment tag in bytes. */
static final int TAG_LENGTH = 16; static final int TAG_LENGTH = 16;
/** The maximum length of a frame in bytes, including the header and MAC. */ /** The maximum length of a frame in bytes, including the header and MAC. */
static final int MAX_FRAME_LENGTH = MAX_SEGMENT_LENGTH - TAG_LENGTH; static final int MAX_FRAME_LENGTH = 65536; // 2^16, 64 KiB
/** The length of the frame header in bytes. */ /** The length of the frame header in bytes. */
static final int FRAME_HEADER_LENGTH = 8; static final int FRAME_HEADER_LENGTH = 8;
/** The length of the ack header in bytes. */
static final int ACK_HEADER_LENGTH = 5;
/** The length of the MAC in bytes. */ /** The length of the MAC in bytes. */
static final int MAC_LENGTH = 32; static final int MAC_LENGTH = 32;
...@@ -29,7 +23,4 @@ public interface TransportConstants { ...@@ -29,7 +23,4 @@ public interface TransportConstants {
/** The size of the connection reordering window. */ /** The size of the connection reordering window. */
static final int CONNECTION_WINDOW_SIZE = 32; static final int CONNECTION_WINDOW_SIZE = 32;
/** The size of the frame reordering window. */
static final int FRAME_WINDOW_SIZE = 32;
} }
...@@ -33,12 +33,12 @@ class CryptoComponentImpl implements CryptoComponent { ...@@ -33,12 +33,12 @@ class CryptoComponentImpl implements CryptoComponent {
private static final String DIGEST_ALGO = "SHA-256"; private static final String DIGEST_ALGO = "SHA-256";
private static final String SIGNATURE_ALGO = "ECDSA"; private static final String SIGNATURE_ALGO = "ECDSA";
private static final String TAG_CIPHER_ALGO = "AES/ECB/NoPadding"; private static final String TAG_CIPHER_ALGO = "AES/ECB/NoPadding";
private static final String SEGMENT_CIPHER_ALGO = "AES/CTR/NoPadding"; private static final String FRAME_CIPHER_ALGO = "AES/CTR/NoPadding";
private static final String MAC_ALGO = "HMacSHA256"; private static final String MAC_ALGO = "HMacSHA256";
// Labels for key derivation, null-terminated // Labels for key derivation, null-terminated
private static final byte[] TAG = { 'T', 'A', 'G', 0 }; private static final byte[] TAG = { 'T', 'A', 'G', 0 };
private static final byte[] SEGMENT = { 'S', 'E', 'G', 0 }; private static final byte[] FRAME = { 'F', 'R', 'A', 'M', 'E', 0 };
private static final byte[] MAC = { 'M', 'A', 'C', 0 }; private static final byte[] MAC = { 'M', 'A', 'C', 0 };
private static final byte[] NEXT = { 'N', 'E', 'X', 'T', 0 }; private static final byte[] NEXT = { 'N', 'E', 'X', 'T', 0 };
// Context strings for key derivation // Context strings for key derivation
...@@ -71,9 +71,9 @@ class CryptoComponentImpl implements CryptoComponent { ...@@ -71,9 +71,9 @@ class CryptoComponentImpl implements CryptoComponent {
else return deriveKey(secret, TAG, RESPONDER); else return deriveKey(secret, TAG, RESPONDER);
} }
public ErasableKey deriveSegmentKey(byte[] secret, boolean initiator) { public ErasableKey deriveFrameKey(byte[] secret, boolean initiator) {
if(initiator) return deriveKey(secret, SEGMENT, INITIATOR); if(initiator) return deriveKey(secret, FRAME, INITIATOR);
else return deriveKey(secret, SEGMENT, RESPONDER); else return deriveKey(secret, FRAME, RESPONDER);
} }
public ErasableKey deriveMacKey(byte[] secret, boolean initiator) { public ErasableKey deriveMacKey(byte[] secret, boolean initiator) {
...@@ -168,9 +168,9 @@ class CryptoComponentImpl implements CryptoComponent { ...@@ -168,9 +168,9 @@ class CryptoComponentImpl implements CryptoComponent {
} }
} }
public Cipher getSegmentCipher() { public Cipher getFrameCipher() {
try { try {
return Cipher.getInstance(SEGMENT_CIPHER_ALGO, PROVIDER); return Cipher.getInstance(FRAME_CIPHER_ALGO, PROVIDER);
} catch(GeneralSecurityException e) { } catch(GeneralSecurityException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
......
...@@ -19,7 +19,7 @@ import net.sf.briar.api.transport.ConnectionWriterFactory; ...@@ -19,7 +19,7 @@ import net.sf.briar.api.transport.ConnectionWriterFactory;
import com.google.inject.Inject; import com.google.inject.Inject;
class StreamConnectionFactoryImpl implements DuplexConnectionFactory { class DuplexConnectionFactoryImpl implements DuplexConnectionFactory {
private final Executor dbExecutor, verificationExecutor; private final Executor dbExecutor, verificationExecutor;
private final DatabaseComponent db; private final DatabaseComponent db;
...@@ -30,7 +30,7 @@ class StreamConnectionFactoryImpl implements DuplexConnectionFactory { ...@@ -30,7 +30,7 @@ class StreamConnectionFactoryImpl implements DuplexConnectionFactory {
private final ProtocolWriterFactory protoWriterFactory; private final ProtocolWriterFactory protoWriterFactory;
@Inject @Inject
StreamConnectionFactoryImpl(@DatabaseExecutor Executor dbExecutor, DuplexConnectionFactoryImpl(@DatabaseExecutor Executor dbExecutor,
@VerificationExecutor Executor verificationExecutor, @VerificationExecutor Executor verificationExecutor,
DatabaseComponent db, ConnectionRegistry connRegistry, DatabaseComponent db, ConnectionRegistry connRegistry,
ConnectionReaderFactory connReaderFactory, ConnectionReaderFactory connReaderFactory,
...@@ -48,11 +48,11 @@ class StreamConnectionFactoryImpl implements DuplexConnectionFactory { ...@@ -48,11 +48,11 @@ class StreamConnectionFactoryImpl implements DuplexConnectionFactory {
} }
public void createIncomingConnection(ConnectionContext ctx, TransportId t, public void createIncomingConnection(ConnectionContext ctx, TransportId t,
DuplexTransportConnection d, byte[] tag) { DuplexTransportConnection d) {
final DuplexConnection conn = new IncomingDuplexConnection(dbExecutor, final DuplexConnection conn = new IncomingDuplexConnection(dbExecutor,
verificationExecutor, db, connRegistry, connReaderFactory, verificationExecutor, db, connRegistry, connReaderFactory,
connWriterFactory, protoReaderFactory, protoWriterFactory, connWriterFactory, protoReaderFactory, protoWriterFactory,
ctx, t, d, tag); ctx, t, d);
Runnable write = new Runnable() { Runnable write = new Runnable() {
public void run() { public void run() {
conn.write(); conn.write();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment