Renamed "encrypted IVs" as "tags" (actual crypto changes to follow).

This commit is contained in:
akwizgran
2011-12-02 12:02:55 +00:00
parent f7360cddde
commit f3fdd85996
26 changed files with 225 additions and 227 deletions

View File

@@ -11,7 +11,7 @@ public interface CryptoComponent {
ErasableKey deriveFrameKey(byte[] secret, boolean initiator); ErasableKey deriveFrameKey(byte[] secret, boolean initiator);
ErasableKey deriveIvKey(byte[] secret, boolean initiator); ErasableKey deriveTagKey(byte[] secret, boolean initiator);
ErasableKey deriveMacKey(byte[] secret, boolean initiator); ErasableKey deriveMacKey(byte[] secret, boolean initiator);
@@ -23,8 +23,6 @@ public interface CryptoComponent {
Cipher getFrameCipher(); Cipher getFrameCipher();
Cipher getIvCipher();
KeyParser getKeyParser(); KeyParser getKeyParser();
Mac getMac(); Mac getMac();
@@ -34,4 +32,6 @@ public interface CryptoComponent {
SecureRandom getSecureRandom(); SecureRandom getSecureRandom();
Signature getSignature(); Signature getSignature();
Cipher getTagCipher();
} }

View File

@@ -6,7 +6,7 @@ import net.sf.briar.api.protocol.TransportIndex;
public interface BatchConnectionFactory { public interface BatchConnectionFactory {
void createIncomingConnection(ConnectionContext ctx, void createIncomingConnection(ConnectionContext ctx,
BatchTransportReader r, byte[] encryptedIv); BatchTransportReader r, byte[] tag);
void createOutgoingConnection(ContactId c, TransportIndex i, void createOutgoingConnection(ContactId c, TransportIndex i,
BatchTransportWriter w); BatchTransportWriter w);

View File

@@ -9,7 +9,7 @@ public interface ConnectionReaderFactory {
* initiator's side of a stream-mode connection. * initiator's side of a stream-mode connection.
*/ */
ConnectionReader createConnectionReader(InputStream in, ConnectionReader createConnectionReader(InputStream in,
ConnectionContext ctx, byte[] encryptedIv); ConnectionContext ctx, byte[] tag);
/** /**
* Creates a connection reader for the responder's side of a stream-mode * Creates a connection reader for the responder's side of a stream-mode

View File

@@ -13,8 +13,7 @@ public interface ConnectionRecogniser {
* Asynchronously calls one of the callback's connectionAccepted(), * Asynchronously calls one of the callback's connectionAccepted(),
* connectionRejected() or handleException() methods. * connectionRejected() or handleException() methods.
*/ */
void acceptConnection(TransportId t, byte[] encryptedIv, void acceptConnection(TransportId t, byte[] tag, Callback c);
Callback c);
interface Callback { interface Callback {

View File

@@ -16,5 +16,5 @@ public interface ConnectionWriterFactory {
* connection. * connection.
*/ */
ConnectionWriter createConnectionWriter(OutputStream out, long capacity, ConnectionWriter createConnectionWriter(OutputStream out, long capacity,
ConnectionContext ctx, byte[] encryptedIv); ConnectionContext ctx, byte[] tag);
} }

View File

@@ -6,7 +6,7 @@ import net.sf.briar.api.protocol.TransportIndex;
public interface StreamConnectionFactory { public interface StreamConnectionFactory {
void createIncomingConnection(ConnectionContext ctx, void createIncomingConnection(ConnectionContext ctx,
StreamTransportConnection s, byte[] encryptedIv); StreamTransportConnection s, byte[] tag);
void createOutgoingConnection(ContactId c, TransportIndex i, void createOutgoingConnection(ContactId c, TransportIndex i,
StreamTransportConnection s); StreamTransportConnection s);

View File

@@ -8,10 +8,10 @@ public interface TransportConstants {
static final int MAX_FRAME_LENGTH = 65536; // 2^16, 64 KiB static final int MAX_FRAME_LENGTH = 65536; // 2^16, 64 KiB
/** /**
* The length in bytes of the encrypted IV that uniquely identifies a * The length in bytes of the pseudo-random tag that uniquely identifies a
* connection. * connection.
*/ */
static final int IV_LENGTH = 16; static final int TAG_LENGTH = 16;
/** /**
* The minimum connection length in bytes that all transport plugins must * The minimum connection length in bytes that all transport plugins must

View File

@@ -30,7 +30,7 @@ class CryptoComponentImpl implements CryptoComponent {
private static final String FRAME_CIPHER_ALGO = "AES/CTR/NoPadding"; private static final String FRAME_CIPHER_ALGO = "AES/CTR/NoPadding";
private static final String SECRET_KEY_ALGO = "AES"; private static final String SECRET_KEY_ALGO = "AES";
private static final int SECRET_KEY_BYTES = 32; // 256 bits private static final int SECRET_KEY_BYTES = 32; // 256 bits
private static final String IV_CIPHER_ALGO = "AES/ECB/NoPadding"; private static final String TAG_CIPHER_ALGO = "AES/ECB/NoPadding";
private static final String MAC_ALGO = "HMacSHA256"; private static final String MAC_ALGO = "HMacSHA256";
private static final String SIGNATURE_ALGO = "ECDSA"; private static final String SIGNATURE_ALGO = "ECDSA";
private static final String KEY_DERIVATION_ALGO = "AES/CTR/NoPadding"; private static final String KEY_DERIVATION_ALGO = "AES/CTR/NoPadding";
@@ -38,7 +38,7 @@ class CryptoComponentImpl implements CryptoComponent {
// Labels for key derivation, null-terminated // Labels for key derivation, null-terminated
private static final byte[] FRAME = { 'F', 'R', 'A', 'M', 'E', 0 }; private static final byte[] FRAME = { 'F', 'R', 'A', 'M', 'E', 0 };
private static final byte[] IV = { 'I', 'V', 0 }; private static final byte[] TAG = { 'T', 'A', 'G', 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 {
else return deriveKey(secret, FRAME, RESPONDER); else return deriveKey(secret, FRAME, RESPONDER);
} }
public ErasableKey deriveIvKey(byte[] secret, boolean initiator) { public ErasableKey deriveTagKey(byte[] secret, boolean initiator) {
if(initiator) return deriveKey(secret, IV, INITIATOR); if(initiator) return deriveKey(secret, TAG, INITIATOR);
else return deriveKey(secret, IV, RESPONDER); else return deriveKey(secret, TAG, RESPONDER);
} }
public ErasableKey deriveMacKey(byte[] secret, boolean initiator) { public ErasableKey deriveMacKey(byte[] secret, boolean initiator) {
@@ -143,14 +143,6 @@ class CryptoComponentImpl implements CryptoComponent {
} }
} }
public Cipher getIvCipher() {
try {
return Cipher.getInstance(IV_CIPHER_ALGO, PROVIDER);
} catch(GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
public KeyParser getKeyParser() { public KeyParser getKeyParser() {
return keyParser; return keyParser;
} }
@@ -183,4 +175,12 @@ class CryptoComponentImpl implements CryptoComponent {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public Cipher getTagCipher() {
try {
return Cipher.getInstance(TAG_CIPHER_ALGO, PROVIDER);
} catch(GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
} }

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
import java.io.EOFException; import java.io.EOFException;
@@ -31,11 +31,11 @@ implements ConnectionDecrypter {
ConnectionDecrypterImpl(InputStream in, byte[] iv, Cipher frameCipher, ConnectionDecrypterImpl(InputStream in, byte[] iv, Cipher frameCipher,
ErasableKey frameKey) { ErasableKey frameKey) {
super(in); super(in);
if(iv.length != IV_LENGTH) throw new IllegalArgumentException(); if(iv.length != TAG_LENGTH) throw new IllegalArgumentException();
this.iv = iv; this.iv = iv;
this.frameCipher = frameCipher; this.frameCipher = frameCipher;
this.frameKey = frameKey; this.frameKey = frameKey;
buf = new byte[IV_LENGTH]; buf = new byte[TAG_LENGTH];
} }
public InputStream getInputStream() { public InputStream getInputStream() {

View File

@@ -41,20 +41,20 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
} }
public void dispatchReader(TransportId t, final BatchTransportReader r) { public void dispatchReader(TransportId t, final BatchTransportReader r) {
// Read the encrypted IV // Read the tag
final byte[] encryptedIv; final byte[] tag;
try { try {
encryptedIv = readIv(r.getInputStream()); tag = readTag(r.getInputStream());
} catch(IOException e) { } catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage()); if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
r.dispose(false); r.dispose(false);
return; return;
} }
// Get the connection context asynchronously // Get the connection context asynchronously
recogniser.acceptConnection(t, encryptedIv, new Callback() { recogniser.acceptConnection(t, tag, new Callback() {
public void connectionAccepted(ConnectionContext ctx) { public void connectionAccepted(ConnectionContext ctx) {
batchConnFactory.createIncomingConnection(ctx, r, encryptedIv); batchConnFactory.createIncomingConnection(ctx, r, tag);
} }
public void connectionRejected() { public void connectionRejected() {
@@ -68,8 +68,8 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
}); });
} }
private byte[] readIv(InputStream in) throws IOException { private byte[] readTag(InputStream in) throws IOException {
byte[] b = new byte[TransportConstants.IV_LENGTH]; byte[] b = new byte[TransportConstants.TAG_LENGTH];
int offset = 0; int offset = 0;
while(offset < b.length) { while(offset < b.length) {
int read = in.read(b, offset, b.length - offset); int read = in.read(b, offset, b.length - offset);
@@ -86,20 +86,20 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
public void dispatchIncomingConnection(TransportId t, public void dispatchIncomingConnection(TransportId t,
final StreamTransportConnection s) { final StreamTransportConnection s) {
// Read the encrypted IV // Read the tag
final byte[] encryptedIv; final byte[] tag;
try { try {
encryptedIv = readIv(s.getInputStream()); tag = readTag(s.getInputStream());
} catch(IOException e) { } catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage()); if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
s.dispose(false); s.dispose(false);
return; return;
} }
// Get the connection context asynchronously // Get the connection context asynchronously
recogniser.acceptConnection(t, encryptedIv, new Callback() { recogniser.acceptConnection(t, tag, new Callback() {
public void connectionAccepted(ConnectionContext ctx) { public void connectionAccepted(ConnectionContext ctx) {
streamConnFactory.createIncomingConnection(ctx, s, encryptedIv); streamConnFactory.createIncomingConnection(ctx, s, tag);
} }
public void connectionRejected() { public void connectionRejected() {

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED; import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
import java.io.FilterOutputStream; import java.io.FilterOutputStream;
@@ -20,23 +20,23 @@ implements ConnectionEncrypter {
private final Cipher frameCipher; private final Cipher frameCipher;
private final ErasableKey frameKey; private final ErasableKey frameKey;
private final byte[] iv, encryptedIv; private final byte[] iv, tag;
private long capacity, frame = 0L; private long capacity, frame = 0L;
private boolean ivWritten = false, betweenFrames = false; private boolean tagWritten = false, betweenFrames = false;
ConnectionEncrypterImpl(OutputStream out, long capacity, byte[] iv, ConnectionEncrypterImpl(OutputStream out, long capacity, byte[] iv,
Cipher ivCipher, Cipher frameCipher, ErasableKey ivKey, Cipher tagCipher, Cipher frameCipher, ErasableKey tagKey,
ErasableKey frameKey) { ErasableKey frameKey) {
super(out); super(out);
this.capacity = capacity; this.capacity = capacity;
this.iv = iv; this.iv = iv;
this.frameCipher = frameCipher; this.frameCipher = frameCipher;
this.frameKey = frameKey; this.frameKey = frameKey;
// Encrypt the IV // Encrypt the tag
try { try {
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
encryptedIv = ivCipher.doFinal(iv); tag = tagCipher.doFinal(iv);
} catch(BadPaddingException badCipher) { } catch(BadPaddingException badCipher) {
throw new IllegalArgumentException(badCipher); throw new IllegalArgumentException(badCipher);
} catch(IllegalBlockSizeException badCipher) { } catch(IllegalBlockSizeException badCipher) {
@@ -44,9 +44,8 @@ implements ConnectionEncrypter {
} catch(InvalidKeyException badKey) { } catch(InvalidKeyException badKey) {
throw new IllegalArgumentException(badKey); throw new IllegalArgumentException(badKey);
} }
if(encryptedIv.length != IV_LENGTH) if(tag.length != TAG_LENGTH) throw new IllegalArgumentException();
throw new IllegalArgumentException(); tagKey.erase();
ivKey.erase();
} }
public OutputStream getOutputStream() { public OutputStream getOutputStream() {
@@ -55,7 +54,7 @@ implements ConnectionEncrypter {
public void writeMac(byte[] mac) throws IOException { public void writeMac(byte[] mac) throws IOException {
try { try {
if(!ivWritten || betweenFrames) throw new IllegalStateException(); if(!tagWritten || betweenFrames) throw new IllegalStateException();
try { try {
out.write(frameCipher.doFinal(mac)); out.write(frameCipher.doFinal(mac));
} catch(BadPaddingException badCipher) { } catch(BadPaddingException badCipher) {
@@ -78,7 +77,7 @@ implements ConnectionEncrypter {
@Override @Override
public void write(int b) throws IOException { public void write(int b) throws IOException {
try { try {
if(!ivWritten) writeIv(); if(!tagWritten) writeTag();
if(betweenFrames) initialiseCipher(); if(betweenFrames) initialiseCipher();
byte[] ciphertext = frameCipher.update(new byte[] {(byte) b}); byte[] ciphertext = frameCipher.update(new byte[] {(byte) b});
if(ciphertext != null) out.write(ciphertext); if(ciphertext != null) out.write(ciphertext);
@@ -97,7 +96,7 @@ implements ConnectionEncrypter {
@Override @Override
public void write(byte[] b, int off, int len) throws IOException { public void write(byte[] b, int off, int len) throws IOException {
try { try {
if(!ivWritten) writeIv(); if(!tagWritten) writeTag();
if(betweenFrames) initialiseCipher(); if(betweenFrames) initialiseCipher();
byte[] ciphertext = frameCipher.update(b, off, len); byte[] ciphertext = frameCipher.update(b, off, len);
if(ciphertext != null) out.write(ciphertext); if(ciphertext != null) out.write(ciphertext);
@@ -108,17 +107,17 @@ implements ConnectionEncrypter {
} }
} }
private void writeIv() throws IOException { private void writeTag() throws IOException {
assert !ivWritten; assert !tagWritten;
assert !betweenFrames; assert !betweenFrames;
out.write(encryptedIv); out.write(tag);
capacity -= encryptedIv.length; capacity -= tag.length;
ivWritten = true; tagWritten = true;
betweenFrames = true; betweenFrames = true;
} }
private void initialiseCipher() { private void initialiseCipher() {
assert ivWritten; assert tagWritten;
assert betweenFrames; assert betweenFrames;
if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException(); if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
IvEncoder.updateIv(iv, frame); IvEncoder.updateIv(iv, frame);

View File

@@ -27,14 +27,14 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
} }
public ConnectionReader createConnectionReader(InputStream in, public ConnectionReader createConnectionReader(InputStream in,
ConnectionContext ctx, byte[] encryptedIv) { ConnectionContext ctx, byte[] tag) {
// Decrypt the IV // Decrypt the tag
Cipher ivCipher = crypto.getIvCipher(); Cipher tagCipher = crypto.getTagCipher();
ErasableKey ivKey = crypto.deriveIvKey(ctx.getSecret(), true); ErasableKey tagKey = crypto.deriveTagKey(ctx.getSecret(), true);
byte[] iv; byte[] iv;
try { try {
ivCipher.init(Cipher.DECRYPT_MODE, ivKey); tagCipher.init(Cipher.DECRYPT_MODE, tagKey);
iv = ivCipher.doFinal(encryptedIv); iv = tagCipher.doFinal(tag);
} catch(BadPaddingException badCipher) { } catch(BadPaddingException badCipher) {
throw new IllegalArgumentException(badCipher); throw new IllegalArgumentException(badCipher);
} catch(IllegalBlockSizeException badCipher) { } catch(IllegalBlockSizeException badCipher) {
@@ -42,8 +42,8 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
} catch(InvalidKeyException badKey) { } catch(InvalidKeyException badKey) {
throw new IllegalArgumentException(badKey); throw new IllegalArgumentException(badKey);
} }
ivKey.erase(); tagKey.erase();
// Validate the IV // Validate the tag
int index = ctx.getTransportIndex().getInt(); int index = ctx.getTransportIndex().getInt();
long connection = ctx.getConnectionNumber(); long connection = ctx.getConnectionNumber();
if(!IvEncoder.validateIv(iv, index, connection)) if(!IvEncoder.validateIv(iv, index, connection))

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -50,7 +50,7 @@ DatabaseListener {
private final CryptoComponent crypto; private final CryptoComponent crypto;
private final DatabaseComponent db; private final DatabaseComponent db;
private final Executor executor; private final Executor executor;
private final Cipher ivCipher; // Locking: this private final Cipher tagCipher; // Locking: this
private final Set<TransportId> localTransportIds; // Locking: this private final Set<TransportId> localTransportIds; // Locking: this
private final Map<Bytes, Context> expected; // Locking: this private final Map<Bytes, Context> expected; // Locking: this
@@ -62,7 +62,7 @@ DatabaseListener {
this.crypto = crypto; this.crypto = crypto;
this.db = db; this.db = db;
this.executor = executor; this.executor = executor;
ivCipher = crypto.getIvCipher(); tagCipher = crypto.getTagCipher();
localTransportIds = new HashSet<TransportId>(); localTransportIds = new HashSet<TransportId>();
expected = new HashMap<Bytes, Context>(); expected = new HashMap<Bytes, Context>();
} }
@@ -87,7 +87,7 @@ DatabaseListener {
ConnectionWindow w = db.getConnectionWindow(c, i); ConnectionWindow w = db.getConnectionWindow(c, i);
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) { for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
Context ctx = new Context(c, t, i, e.getKey()); Context ctx = new Context(c, t, i, e.getKey());
ivs.put(calculateIv(ctx, e.getValue()), ctx); ivs.put(calculateTag(ctx, e.getValue()), ctx);
} }
w.erase(); w.erase();
} }
@@ -102,14 +102,14 @@ DatabaseListener {
} }
// Locking: this // Locking: this
private Bytes calculateIv(Context ctx, byte[] secret) { private Bytes calculateTag(Context ctx, byte[] secret) {
byte[] iv = IvEncoder.encodeIv(ctx.transportIndex.getInt(), byte[] iv = IvEncoder.encodeIv(ctx.transportIndex.getInt(),
ctx.connection); ctx.connection);
ErasableKey ivKey = crypto.deriveIvKey(secret, true); ErasableKey tagKey = crypto.deriveTagKey(secret, true);
try { try {
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
byte[] encryptedIv = ivCipher.doFinal(iv); byte[] tag = tagCipher.doFinal(iv);
return new Bytes(encryptedIv); return new Bytes(tag);
} catch(BadPaddingException badCipher) { } catch(BadPaddingException badCipher) {
throw new RuntimeException(badCipher); throw new RuntimeException(badCipher);
} catch(IllegalBlockSizeException badCipher) { } catch(IllegalBlockSizeException badCipher) {
@@ -117,16 +117,16 @@ DatabaseListener {
} catch(InvalidKeyException badKey) { } catch(InvalidKeyException badKey) {
throw new RuntimeException(badKey); throw new RuntimeException(badKey);
} finally { } finally {
ivKey.erase(); tagKey.erase();
} }
} }
public void acceptConnection(final TransportId t, final byte[] encryptedIv, public void acceptConnection(final TransportId t, final byte[] tag,
final Callback callback) { final Callback callback) {
executor.execute(new Runnable() { executor.execute(new Runnable() {
public void run() { public void run() {
try { try {
ConnectionContext ctx = acceptConnection(t, encryptedIv); ConnectionContext ctx = acceptConnection(t, tag);
if(ctx == null) callback.connectionRejected(); if(ctx == null) callback.connectionRejected();
else callback.connectionAccepted(ctx); else callback.connectionAccepted(ctx);
} catch(DbException e) { } catch(DbException e) {
@@ -137,13 +137,13 @@ DatabaseListener {
} }
// Package access for testing // Package access for testing
ConnectionContext acceptConnection(TransportId t, byte[] encryptedIv) ConnectionContext acceptConnection(TransportId t, byte[] tag)
throws DbException { throws DbException {
if(encryptedIv.length != IV_LENGTH) if(tag.length != TAG_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
synchronized(this) { synchronized(this) {
if(!initialised) initialise(); if(!initialised) initialise();
Bytes b = new Bytes(encryptedIv); Bytes b = new Bytes(tag);
Context ctx = expected.get(b); Context ctx = expected.get(b);
if(ctx == null || !ctx.transportId.equals(t)) return null; if(ctx == null || !ctx.transportId.equals(t)) return null;
// The IV was expected // The IV was expected
@@ -173,7 +173,7 @@ DatabaseListener {
} }
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) { for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
Context ctx1 = new Context(c, t, i, e.getKey()); Context ctx1 = new Context(c, t, i, e.getKey());
expected.put(calculateIv(ctx1, e.getValue()), ctx1); expected.put(calculateTag(ctx1, e.getValue()), ctx1);
} }
w.erase(); w.erase();
return new ConnectionContextImpl(c, i, connection, secret); return new ConnectionContextImpl(c, i, connection, secret);
@@ -227,7 +227,7 @@ DatabaseListener {
ConnectionWindow w = db.getConnectionWindow(c, i); ConnectionWindow w = db.getConnectionWindow(c, i);
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) { for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
Context ctx = new Context(c, t, i, e.getKey()); Context ctx = new Context(c, t, i, e.getKey());
ivs.put(calculateIv(ctx, e.getValue()), ctx); ivs.put(calculateTag(ctx, e.getValue()), ctx);
} }
w.erase(); w.erase();
} catch(NoSuchContactException e) { } catch(NoSuchContactException e) {
@@ -256,7 +256,7 @@ DatabaseListener {
ConnectionWindow w = db.getConnectionWindow(c, i); ConnectionWindow w = db.getConnectionWindow(c, i);
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) { for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
Context ctx = new Context(c, t, i, e.getKey()); Context ctx = new Context(c, t, i, e.getKey());
ivs.put(calculateIv(ctx, e.getValue()), ctx); ivs.put(calculateTag(ctx, e.getValue()), ctx);
} }
w.erase(); w.erase();
} }

View File

@@ -32,14 +32,14 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
} }
public ConnectionWriter createConnectionWriter(OutputStream out, public ConnectionWriter createConnectionWriter(OutputStream out,
long capacity, ConnectionContext ctx, byte[] encryptedIv) { long capacity, ConnectionContext ctx, byte[] tag) {
// Decrypt the IV // Decrypt the tag
Cipher ivCipher = crypto.getIvCipher(); Cipher tagCipher = crypto.getTagCipher();
ErasableKey ivKey = crypto.deriveIvKey(ctx.getSecret(), true); ErasableKey tagKey = crypto.deriveTagKey(ctx.getSecret(), true);
byte[] iv; byte[] iv;
try { try {
ivCipher.init(Cipher.DECRYPT_MODE, ivKey); tagCipher.init(Cipher.DECRYPT_MODE, tagKey);
iv = ivCipher.doFinal(encryptedIv); iv = tagCipher.doFinal(tag);
} catch(BadPaddingException badCipher) { } catch(BadPaddingException badCipher) {
throw new RuntimeException(badCipher); throw new RuntimeException(badCipher);
} catch(IllegalBlockSizeException badCipher) { } catch(IllegalBlockSizeException badCipher) {
@@ -47,8 +47,8 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
} catch(InvalidKeyException badKey) { } catch(InvalidKeyException badKey) {
throw new RuntimeException(badKey); throw new RuntimeException(badKey);
} }
ivKey.erase(); tagKey.erase();
// Validate the IV // Validate the tag
int index = ctx.getTransportIndex().getInt(); int index = ctx.getTransportIndex().getInt();
long connection = ctx.getConnectionNumber(); long connection = ctx.getConnectionNumber();
if(!IvEncoder.validateIv(iv, index, connection)) if(!IvEncoder.validateIv(iv, index, connection))
@@ -60,7 +60,7 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
long capacity, boolean initiator, ConnectionContext ctx) { long capacity, boolean initiator, ConnectionContext ctx) {
// Derive the keys and erase the secret // Derive the keys and erase the secret
byte[] secret = ctx.getSecret(); byte[] secret = ctx.getSecret();
ErasableKey ivKey = crypto.deriveIvKey(secret, initiator); ErasableKey tagKey = crypto.deriveTagKey(secret, initiator);
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator); ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
ErasableKey macKey = crypto.deriveMacKey(secret, initiator); ErasableKey macKey = crypto.deriveMacKey(secret, initiator);
ByteUtils.erase(secret); ByteUtils.erase(secret);
@@ -68,10 +68,10 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
int index = ctx.getTransportIndex().getInt(); int index = ctx.getTransportIndex().getInt();
long connection = ctx.getConnectionNumber(); long connection = ctx.getConnectionNumber();
byte[] iv = IvEncoder.encodeIv(index, connection); byte[] iv = IvEncoder.encodeIv(index, connection);
Cipher ivCipher = crypto.getIvCipher(); Cipher tagCipher = crypto.getTagCipher();
Cipher frameCipher = crypto.getFrameCipher(); Cipher frameCipher = crypto.getFrameCipher();
ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out, ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out,
capacity, iv, ivCipher, frameCipher, ivKey, frameKey); capacity, iv, tagCipher, frameCipher, tagKey, frameKey);
// Create the writer // Create the writer
Mac mac = crypto.getMac(); Mac mac = crypto.getMac();
return new ConnectionWriterImpl(encrypter, mac, macKey); return new ConnectionWriterImpl(encrypter, mac, macKey);

View File

@@ -1,12 +1,12 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import net.sf.briar.util.ByteUtils; import net.sf.briar.util.ByteUtils;
class IvEncoder { class IvEncoder {
static byte[] encodeIv(int index, long connection) { static byte[] encodeIv(int index, long connection) {
byte[] iv = new byte[IV_LENGTH]; byte[] iv = new byte[TAG_LENGTH];
// Encode the transport index as an unsigned 16-bit integer // Encode the transport index as an unsigned 16-bit integer
ByteUtils.writeUint16(index, iv, 4); ByteUtils.writeUint16(index, iv, 4);
// Encode the connection number as an unsigned 32-bit integer // Encode the connection number as an unsigned 32-bit integer
@@ -15,13 +15,13 @@ class IvEncoder {
} }
static void updateIv(byte[] iv, long frame) { static void updateIv(byte[] iv, long frame) {
if(iv.length != IV_LENGTH) throw new IllegalArgumentException(); if(iv.length != TAG_LENGTH) throw new IllegalArgumentException();
// Encode the frame number as an unsigned 32-bit integer // Encode the frame number as an unsigned 32-bit integer
ByteUtils.writeUint32(frame, iv, 10); ByteUtils.writeUint32(frame, iv, 10);
} }
static boolean validateIv(byte[] iv, int index, long connection) { static boolean validateIv(byte[] iv, int index, long connection) {
if(iv.length != IV_LENGTH) return false; if(iv.length != TAG_LENGTH) return false;
// Check that the reserved bits are all zero // Check that the reserved bits are all zero
for(int i = 0; i < 3; i++) if(iv[i] != 0) return false; for(int i = 0; i < 3; i++) if(iv[i] != 0) return false;
for(int i = 10; i < iv.length; i++) if(iv[i] != 0) return false; for(int i = 10; i < iv.length; i++) if(iv[i] != 0) return false;
@@ -34,12 +34,12 @@ class IvEncoder {
} }
static int getTransportIndex(byte[] iv) { static int getTransportIndex(byte[] iv) {
if(iv.length != IV_LENGTH) throw new IllegalArgumentException(); if(iv.length != TAG_LENGTH) throw new IllegalArgumentException();
return ByteUtils.readUint16(iv, 4); return ByteUtils.readUint16(iv, 4);
} }
static long getConnectionNumber(byte[] iv) { static long getConnectionNumber(byte[] iv) {
if(iv.length != IV_LENGTH) throw new IllegalArgumentException(); if(iv.length != TAG_LENGTH) throw new IllegalArgumentException();
return ByteUtils.readUint32(iv, 6); return ByteUtils.readUint32(iv, 6);
} }
} }

View File

@@ -35,9 +35,9 @@ class BatchConnectionFactoryImpl implements BatchConnectionFactory {
} }
public void createIncomingConnection(ConnectionContext ctx, public void createIncomingConnection(ConnectionContext ctx,
BatchTransportReader r, byte[] encryptedIv) { BatchTransportReader r, byte[] tag) {
final IncomingBatchConnection conn = new IncomingBatchConnection( final IncomingBatchConnection conn = new IncomingBatchConnection(
connReaderFactory, db, protoReaderFactory, ctx, r, encryptedIv); connReaderFactory, db, protoReaderFactory, ctx, r, tag);
Runnable read = new Runnable() { Runnable read = new Runnable() {
public void run() { public void run() {
conn.read(); conn.read();

View File

@@ -29,24 +29,23 @@ class IncomingBatchConnection {
private final ProtocolReaderFactory protoFactory; private final ProtocolReaderFactory protoFactory;
private final ConnectionContext ctx; private final ConnectionContext ctx;
private final BatchTransportReader reader; private final BatchTransportReader reader;
private final byte[] encryptedIv; private final byte[] tag;
IncomingBatchConnection(ConnectionReaderFactory connFactory, IncomingBatchConnection(ConnectionReaderFactory connFactory,
DatabaseComponent db, ProtocolReaderFactory protoFactory, DatabaseComponent db, ProtocolReaderFactory protoFactory,
ConnectionContext ctx, BatchTransportReader reader, ConnectionContext ctx, BatchTransportReader reader, byte[] tag) {
byte[] encryptedIv) {
this.connFactory = connFactory; this.connFactory = connFactory;
this.db = db; this.db = db;
this.protoFactory = protoFactory; this.protoFactory = protoFactory;
this.ctx = ctx; this.ctx = ctx;
this.reader = reader; this.reader = reader;
this.encryptedIv = encryptedIv; this.tag = tag;
} }
void read() { void read() {
try { try {
ConnectionReader conn = connFactory.createConnectionReader( ConnectionReader conn = connFactory.createConnectionReader(
reader.getInputStream(), ctx, encryptedIv); reader.getInputStream(), ctx, tag);
ProtocolReader proto = protoFactory.createProtocolReader( ProtocolReader proto = protoFactory.createProtocolReader(
conn.getInputStream()); conn.getInputStream());
ContactId c = ctx.getContactId(); ContactId c = ctx.getContactId();

View File

@@ -16,31 +16,31 @@ import net.sf.briar.api.transport.StreamTransportConnection;
class IncomingStreamConnection extends StreamConnection { class IncomingStreamConnection extends StreamConnection {
private final ConnectionContext ctx; private final ConnectionContext ctx;
private final byte[] encryptedIv; private final byte[] tag;
IncomingStreamConnection(ConnectionReaderFactory connReaderFactory, IncomingStreamConnection(ConnectionReaderFactory connReaderFactory,
ConnectionWriterFactory connWriterFactory, DatabaseComponent db, ConnectionWriterFactory connWriterFactory, DatabaseComponent db,
ProtocolReaderFactory protoReaderFactory, ProtocolReaderFactory protoReaderFactory,
ProtocolWriterFactory protoWriterFactory, ProtocolWriterFactory protoWriterFactory,
ConnectionContext ctx, StreamTransportConnection connection, ConnectionContext ctx, StreamTransportConnection connection,
byte[] encryptedIv) { byte[] tag) {
super(connReaderFactory, connWriterFactory, db, protoReaderFactory, super(connReaderFactory, connWriterFactory, db, protoReaderFactory,
protoWriterFactory, ctx.getContactId(), connection); protoWriterFactory, ctx.getContactId(), connection);
this.ctx = ctx; this.ctx = ctx;
this.encryptedIv = encryptedIv; this.tag = tag;
} }
@Override @Override
protected ConnectionReader createConnectionReader() throws DbException, protected ConnectionReader createConnectionReader() throws DbException,
IOException { IOException {
return connReaderFactory.createConnectionReader( return connReaderFactory.createConnectionReader(
connection.getInputStream(), ctx, encryptedIv); connection.getInputStream(), ctx, tag);
} }
@Override @Override
protected ConnectionWriter createConnectionWriter() throws DbException, protected ConnectionWriter createConnectionWriter() throws DbException,
IOException { IOException {
return connWriterFactory.createConnectionWriter( return connWriterFactory.createConnectionWriter(
connection.getOutputStream(), Long.MAX_VALUE, ctx, encryptedIv); connection.getOutputStream(), Long.MAX_VALUE, ctx, tag);
} }
} }

View File

@@ -34,10 +34,10 @@ class StreamConnectionFactoryImpl implements StreamConnectionFactory {
} }
public void createIncomingConnection(ConnectionContext ctx, public void createIncomingConnection(ConnectionContext ctx,
StreamTransportConnection s, byte[] encryptedIv) { StreamTransportConnection s, byte[] tag) {
final StreamConnection conn = new IncomingStreamConnection( final StreamConnection conn = new IncomingStreamConnection(
connReaderFactory, connWriterFactory, db, protoReaderFactory, connReaderFactory, connWriterFactory, db, protoReaderFactory,
protoWriterFactory, ctx, s, encryptedIv); protoWriterFactory, ctx, s, tag);
Runnable write = new Runnable() { Runnable write = new Runnable() {
public void run() { public void run() {
conn.write(); conn.write();

View File

@@ -52,6 +52,7 @@ import net.sf.briar.api.transport.ConnectionReader;
import net.sf.briar.api.transport.ConnectionReaderFactory; import net.sf.briar.api.transport.ConnectionReaderFactory;
import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.api.transport.ConnectionWriter;
import net.sf.briar.api.transport.ConnectionWriterFactory; import net.sf.briar.api.transport.ConnectionWriterFactory;
import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import net.sf.briar.crypto.CryptoModule; import net.sf.briar.crypto.CryptoModule;
import net.sf.briar.db.DatabaseModule; import net.sf.briar.db.DatabaseModule;
import net.sf.briar.lifecycle.LifecycleModule; import net.sf.briar.lifecycle.LifecycleModule;
@@ -206,13 +207,13 @@ public class ProtocolIntegrationTest extends TestCase {
private void read(byte[] connectionData) throws Exception { private void read(byte[] connectionData) throws Exception {
InputStream in = new ByteArrayInputStream(connectionData); InputStream in = new ByteArrayInputStream(connectionData);
byte[] encryptedIv = new byte[16]; byte[] tag = new byte[TAG_LENGTH];
assertEquals(16, in.read(encryptedIv, 0, 16)); assertEquals(TAG_LENGTH, in.read(tag, 0, TAG_LENGTH));
ConnectionContext ctx = ConnectionContext ctx =
connectionContextFactory.createConnectionContext(contactId, connectionContextFactory.createConnectionContext(contactId,
transportIndex, connection, Arrays.clone(secret)); transportIndex, connection, Arrays.clone(secret));
ConnectionReader r = connectionReaderFactory.createConnectionReader(in, ConnectionReader r = connectionReaderFactory.createConnectionReader(in,
ctx, encryptedIv); ctx, tag);
in = r.getInputStream(); in = r.getInputStream();
ProtocolReader protocolReader = ProtocolReader protocolReader =
protocolReaderFactory.createProtocolReader(in); protocolReaderFactory.createProtocolReader(in);

View File

@@ -29,8 +29,8 @@ public class KeyDerivationTest extends TestCase {
List<ErasableKey> keys = new ArrayList<ErasableKey>(); List<ErasableKey> keys = new ArrayList<ErasableKey>();
keys.add(crypto.deriveFrameKey(secret, true)); keys.add(crypto.deriveFrameKey(secret, true));
keys.add(crypto.deriveFrameKey(secret, false)); keys.add(crypto.deriveFrameKey(secret, false));
keys.add(crypto.deriveIvKey(secret, true)); keys.add(crypto.deriveTagKey(secret, true));
keys.add(crypto.deriveIvKey(secret, false)); keys.add(crypto.deriveTagKey(secret, false));
keys.add(crypto.deriveMacKey(secret, true)); keys.add(crypto.deriveMacKey(secret, true));
keys.add(crypto.deriveMacKey(secret, false)); keys.add(crypto.deriveMacKey(secret, false));
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@@ -25,8 +25,8 @@ public class ConnectionDecrypterImplTest extends TestCase {
private static final int MAC_LENGTH = 32; private static final int MAC_LENGTH = 32;
private final Cipher ivCipher, frameCipher; private final Cipher tagCipher, frameCipher;
private final ErasableKey ivKey, frameKey; private final ErasableKey tagKey, frameKey;
private final TransportIndex transportIndex = new TransportIndex(13); private final TransportIndex transportIndex = new TransportIndex(13);
private final long connection = 12345L; private final long connection = 12345L;
@@ -34,9 +34,9 @@ public class ConnectionDecrypterImplTest extends TestCase {
super(); super();
Injector i = Guice.createInjector(new CryptoModule()); Injector i = Guice.createInjector(new CryptoModule());
CryptoComponent crypto = i.getInstance(CryptoComponent.class); CryptoComponent crypto = i.getInstance(CryptoComponent.class);
ivCipher = crypto.getIvCipher(); tagCipher = crypto.getTagCipher();
frameCipher = crypto.getFrameCipher(); frameCipher = crypto.getFrameCipher();
ivKey = crypto.generateTestKey(); tagKey = crypto.generateTestKey();
frameKey = crypto.generateTestKey(); frameKey = crypto.generateTestKey();
} }
@@ -53,9 +53,9 @@ public class ConnectionDecrypterImplTest extends TestCase {
private void testDecryption(boolean initiator) throws Exception { private void testDecryption(boolean initiator) throws Exception {
// Calculate the plaintext and ciphertext for the IV // Calculate the plaintext and ciphertext for the IV
byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection);
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
byte[] encryptedIv = ivCipher.doFinal(iv); byte[] tag = tagCipher.doFinal(iv);
assertEquals(IV_LENGTH, encryptedIv.length); assertEquals(TAG_LENGTH, tag.length);
// Calculate the expected plaintext for the first frame // Calculate the expected plaintext for the first frame
byte[] ciphertext = new byte[123]; byte[] ciphertext = new byte[123];
byte[] ciphertextMac = new byte[MAC_LENGTH]; byte[] ciphertextMac = new byte[MAC_LENGTH];

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -23,8 +23,8 @@ public class ConnectionEncrypterImplTest extends TestCase {
private static final int MAC_LENGTH = 32; private static final int MAC_LENGTH = 32;
private final Cipher ivCipher, frameCipher; private final Cipher tagCipher, frameCipher;
private final ErasableKey ivKey, frameKey; private final ErasableKey tagKey, frameKey;
private final TransportIndex transportIndex = new TransportIndex(13); private final TransportIndex transportIndex = new TransportIndex(13);
private final long connection = 12345L; private final long connection = 12345L;
@@ -32,9 +32,9 @@ public class ConnectionEncrypterImplTest extends TestCase {
super(); super();
Injector i = Guice.createInjector(new CryptoModule()); Injector i = Guice.createInjector(new CryptoModule());
CryptoComponent crypto = i.getInstance(CryptoComponent.class); CryptoComponent crypto = i.getInstance(CryptoComponent.class);
ivCipher = crypto.getIvCipher(); tagCipher = crypto.getTagCipher();
frameCipher = crypto.getFrameCipher(); frameCipher = crypto.getFrameCipher();
ivKey = crypto.generateTestKey(); tagKey = crypto.generateTestKey();
frameKey = crypto.generateTestKey(); frameKey = crypto.generateTestKey();
} }
@@ -51,9 +51,9 @@ public class ConnectionEncrypterImplTest extends TestCase {
private void testEncryption(boolean initiator) throws Exception { private void testEncryption(boolean initiator) throws Exception {
// Calculate the expected ciphertext for the IV // Calculate the expected ciphertext for the IV
byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection);
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
byte[] encryptedIv = ivCipher.doFinal(iv); byte[] tag = tagCipher.doFinal(iv);
assertEquals(IV_LENGTH, encryptedIv.length); assertEquals(TAG_LENGTH, tag.length);
// Calculate the expected ciphertext for the first frame // Calculate the expected ciphertext for the first frame
byte[] plaintext = new byte[123]; byte[] plaintext = new byte[123];
byte[] plaintextMac = new byte[MAC_LENGTH]; byte[] plaintextMac = new byte[MAC_LENGTH];
@@ -76,7 +76,7 @@ public class ConnectionEncrypterImplTest extends TestCase {
offset); offset);
// Concatenate the ciphertexts // Concatenate the ciphertexts
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(encryptedIv); out.write(tag);
out.write(ciphertext); out.write(ciphertext);
out.write(ciphertext1); out.write(ciphertext1);
byte[] expected = out.toByteArray(); byte[] expected = out.toByteArray();
@@ -84,7 +84,7 @@ public class ConnectionEncrypterImplTest extends TestCase {
out.reset(); out.reset();
iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); iv = IvEncoder.encodeIv(transportIndex.getInt(), connection);
ConnectionEncrypter e = new ConnectionEncrypterImpl(out, Long.MAX_VALUE, ConnectionEncrypter e = new ConnectionEncrypterImpl(out, Long.MAX_VALUE,
iv, ivCipher, frameCipher, ivKey, frameKey); iv, tagCipher, frameCipher, tagKey, frameKey);
e.getOutputStream().write(plaintext); e.getOutputStream().write(plaintext);
e.writeMac(plaintextMac); e.writeMac(plaintextMac);
e.getOutputStream().write(plaintext1); e.getOutputStream().write(plaintext1);

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@@ -83,7 +83,7 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
assertNull(c.acceptConnection(transportId, new byte[IV_LENGTH])); assertNull(c.acceptConnection(transportId, new byte[TAG_LENGTH]));
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -111,18 +111,18 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// The IV should not be expected by the wrong transport // The tag should not be expected by the wrong transport
TransportId wrong = new TransportId(TestUtils.getRandomId()); TransportId wrong = new TransportId(TestUtils.getRandomId());
assertNull(c.acceptConnection(wrong, encryptedIv)); assertNull(c.acceptConnection(wrong, tag));
// The IV should be expected by the right transport // The tag should be expected by the right transport
ConnectionContext ctx = c.acceptConnection(transportId, encryptedIv); ConnectionContext ctx = c.acceptConnection(transportId, tag);
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId()); assertEquals(contactId, ctx.getContactId());
assertEquals(remoteIndex, ctx.getTransportIndex()); assertEquals(remoteIndex, ctx.getTransportIndex());
assertEquals(3, ctx.getConnectionNumber()); assertEquals(3, ctx.getConnectionNumber());
// The IV should no longer be expected // The tag should no longer be expected
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
// The window should have advanced // The window should have advanced
Map<Long, byte[]> unseen = window.getUnseen(); Map<Long, byte[]> unseen = window.getUnseen();
assertEquals(19, unseen.size()); assertEquals(19, unseen.size());
@@ -152,15 +152,15 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Ensure the recogniser is initialised // Ensure the recogniser is initialised
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, new byte[IV_LENGTH])); assertNull(c.acceptConnection(transportId, new byte[TAG_LENGTH]));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
// Remove the contact // Remove the contact
c.eventOccurred(new ContactRemovedEvent(contactId)); c.eventOccurred(new ContactRemovedEvent(contactId));
// The IV should not be expected // The tag should not be expected
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -179,12 +179,12 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Remove the contact // Remove the contact
c.eventOccurred(new ContactRemovedEvent(contactId)); c.eventOccurred(new ContactRemovedEvent(contactId));
// The IV should not be expected // The tag should not be expected
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -216,21 +216,21 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// The IV should not be expected // The tag should not be expected
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
// Add the transport // Add the transport
c.eventOccurred(new TransportAddedEvent(transportId)); c.eventOccurred(new TransportAddedEvent(transportId));
// The IV should be expected // The tag should be expected
ConnectionContext ctx = c.acceptConnection(transportId, encryptedIv); ConnectionContext ctx = c.acceptConnection(transportId, tag);
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId()); assertEquals(contactId, ctx.getContactId());
assertEquals(remoteIndex, ctx.getTransportIndex()); assertEquals(remoteIndex, ctx.getTransportIndex());
assertEquals(3, ctx.getConnectionNumber()); assertEquals(3, ctx.getConnectionNumber());
// The IV should no longer be expected // The tag should no longer be expected
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
// The window should have advanced // The window should have advanced
Map<Long, byte[]> unseen = window.getUnseen(); Map<Long, byte[]> unseen = window.getUnseen();
assertEquals(19, unseen.size()); assertEquals(19, unseen.size());
@@ -264,19 +264,19 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Add the transport // Add the transport
c.eventOccurred(new TransportAddedEvent(transportId)); c.eventOccurred(new TransportAddedEvent(transportId));
// The IV should be expected // The tag should be expected
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
ConnectionContext ctx = c.acceptConnection(transportId, encryptedIv); ConnectionContext ctx = c.acceptConnection(transportId, tag);
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId()); assertEquals(contactId, ctx.getContactId());
assertEquals(remoteIndex, ctx.getTransportIndex()); assertEquals(remoteIndex, ctx.getTransportIndex());
assertEquals(3, ctx.getConnectionNumber()); assertEquals(3, ctx.getConnectionNumber());
// The IV should no longer be expected // The tag should no longer be expected
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
// The window should have advanced // The window should have advanced
Map<Long, byte[]> unseen = window.getUnseen(); Map<Long, byte[]> unseen = window.getUnseen();
assertEquals(19, unseen.size()); assertEquals(19, unseen.size());
@@ -311,22 +311,22 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// The IV should not be expected // The tag should not be expected
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
// Update the contact // Update the contact
c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId, c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId,
remoteTransports)); remoteTransports));
// The IV should be expected // The tag should be expected
ConnectionContext ctx = c.acceptConnection(transportId, encryptedIv); ConnectionContext ctx = c.acceptConnection(transportId, tag);
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId()); assertEquals(contactId, ctx.getContactId());
assertEquals(remoteIndex, ctx.getTransportIndex()); assertEquals(remoteIndex, ctx.getTransportIndex());
assertEquals(3, ctx.getConnectionNumber()); assertEquals(3, ctx.getConnectionNumber());
// The IV should no longer be expected // The tag should no longer be expected
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
// The window should have advanced // The window should have advanced
Map<Long, byte[]> unseen = window.getUnseen(); Map<Long, byte[]> unseen = window.getUnseen();
assertEquals(19, unseen.size()); assertEquals(19, unseen.size());
@@ -360,20 +360,20 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Update the contact // Update the contact
c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId, c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId,
remoteTransports)); remoteTransports));
// The IV should be expected // The tag should be expected
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
ConnectionContext ctx = c.acceptConnection(transportId, encryptedIv); ConnectionContext ctx = c.acceptConnection(transportId, tag);
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId()); assertEquals(contactId, ctx.getContactId());
assertEquals(remoteIndex, ctx.getTransportIndex()); assertEquals(remoteIndex, ctx.getTransportIndex());
assertEquals(3, ctx.getConnectionNumber()); assertEquals(3, ctx.getConnectionNumber());
// The IV should no longer be expected // The tag should no longer be expected
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
// The window should have advanced // The window should have advanced
Map<Long, byte[]> unseen = window.getUnseen(); Map<Long, byte[]> unseen = window.getUnseen();
assertEquals(19, unseen.size()); assertEquals(19, unseen.size());
@@ -403,16 +403,16 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Ensure the recogniser is initialised // Ensure the recogniser is initialised
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, new byte[IV_LENGTH])); assertNull(c.acceptConnection(transportId, new byte[TAG_LENGTH]));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
// Update the contact // Update the contact
c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId, c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId,
Collections.<Transport>emptyList())); Collections.<Transport>emptyList()));
// The IV should not be expected // The tag should not be expected
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -433,13 +433,13 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Update the contact // Update the contact
c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId, c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId,
Collections.<Transport>emptyList())); Collections.<Transport>emptyList()));
// The IV should not be expected // The tag should not be expected
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -499,24 +499,24 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Ensure the recogniser is initialised // Ensure the recogniser is initialised
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, new byte[IV_LENGTH])); assertNull(c.acceptConnection(transportId, new byte[TAG_LENGTH]));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
// Update the contact // Update the contact
c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId, c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId,
remoteTransports1)); remoteTransports1));
// The IV should not be expected by the old transport // The tag should not be expected by the old transport
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
// The IV should be expected by the new transport // The tag should be expected by the new transport
ConnectionContext ctx = c.acceptConnection(transportId1, encryptedIv); ConnectionContext ctx = c.acceptConnection(transportId1, tag);
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId()); assertEquals(contactId, ctx.getContactId());
assertEquals(remoteIndex, ctx.getTransportIndex()); assertEquals(remoteIndex, ctx.getTransportIndex());
assertEquals(3, ctx.getConnectionNumber()); assertEquals(3, ctx.getConnectionNumber());
// The IV should no longer be expected // The tag should no longer be expected
assertNull(c.acceptConnection(transportId1, encryptedIv)); assertNull(c.acceptConnection(transportId1, tag));
// The window should have advanced // The window should have advanced
Map<Long, byte[]> unseen = window.getUnseen(); Map<Long, byte[]> unseen = window.getUnseen();
assertEquals(19, unseen.size()); assertEquals(19, unseen.size());
@@ -576,22 +576,22 @@ public class ConnectionRecogniserImplTest extends TestCase {
Executor executor = new ImmediateExecutor(); Executor executor = new ImmediateExecutor();
ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db, ConnectionRecogniserImpl c = new ConnectionRecogniserImpl(crypto, db,
executor); executor);
byte[] encryptedIv = calculateIv(); byte[] tag = calculateTag();
// Update the contact // Update the contact
c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId, c.eventOccurred(new RemoteTransportsUpdatedEvent(contactId,
remoteTransports1)); remoteTransports1));
// The IV should not be expected by the old transport // The tag should not be expected by the old transport
assertFalse(c.isInitialised()); assertFalse(c.isInitialised());
assertNull(c.acceptConnection(transportId, encryptedIv)); assertNull(c.acceptConnection(transportId, tag));
assertTrue(c.isInitialised()); assertTrue(c.isInitialised());
// The IV should be expected by the new transport // The tag should be expected by the new transport
ConnectionContext ctx = c.acceptConnection(transportId1, encryptedIv); ConnectionContext ctx = c.acceptConnection(transportId1, tag);
assertNotNull(ctx); assertNotNull(ctx);
assertEquals(contactId, ctx.getContactId()); assertEquals(contactId, ctx.getContactId());
assertEquals(remoteIndex, ctx.getTransportIndex()); assertEquals(remoteIndex, ctx.getTransportIndex());
assertEquals(3, ctx.getConnectionNumber()); assertEquals(3, ctx.getConnectionNumber());
// The IV should no longer be expected // The tag should no longer be expected
assertNull(c.acceptConnection(transportId1, encryptedIv)); assertNull(c.acceptConnection(transportId1, tag));
// The window should have advanced // The window should have advanced
Map<Long, byte[]> unseen = window.getUnseen(); Map<Long, byte[]> unseen = window.getUnseen();
assertEquals(19, unseen.size()); assertEquals(19, unseen.size());
@@ -608,17 +608,17 @@ public class ConnectionRecogniserImplTest extends TestCase {
}; };
} }
private byte[] calculateIv() throws Exception { private byte[] calculateTag() throws Exception {
// Calculate the shared secret for connection number 3 // Calculate the shared secret for connection number 3
byte[] secret = inSecret; byte[] secret = inSecret;
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
secret = crypto.deriveNextSecret(secret, remoteIndex.getInt(), i); secret = crypto.deriveNextSecret(secret, remoteIndex.getInt(), i);
} }
// Calculate the expected IV for connection number 3 // Calculate the expected tag for connection number 3
ErasableKey ivKey = crypto.deriveIvKey(secret, true); ErasableKey tagKey = crypto.deriveTagKey(secret, true);
Cipher ivCipher = crypto.getIvCipher(); Cipher tagCipher = crypto.getTagCipher();
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
byte[] iv = IvEncoder.encodeIv(remoteIndex.getInt(), 3); byte[] iv = IvEncoder.encodeIv(remoteIndex.getInt(), 3);
return ivCipher.doFinal(iv); return tagCipher.doFinal(iv);
} }
} }

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport; package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@@ -28,10 +28,10 @@ import com.google.inject.Injector;
public class FrameReadWriteTest extends TestCase { public class FrameReadWriteTest extends TestCase {
private final CryptoComponent crypto; private final CryptoComponent crypto;
private final Cipher ivCipher, frameCipher; private final Cipher tagCipher, frameCipher;
private final Random random; private final Random random;
private final byte[] outSecret; private final byte[] outSecret;
private final ErasableKey ivKey, frameKey, macKey; private final ErasableKey tagKey, frameKey, macKey;
private final Mac mac; private final Mac mac;
private final TransportIndex transportIndex = new TransportIndex(13); private final TransportIndex transportIndex = new TransportIndex(13);
private final long connection = 12345L; private final long connection = 12345L;
@@ -40,13 +40,13 @@ public class FrameReadWriteTest extends TestCase {
super(); super();
Injector i = Guice.createInjector(new CryptoModule()); Injector i = Guice.createInjector(new CryptoModule());
crypto = i.getInstance(CryptoComponent.class); crypto = i.getInstance(CryptoComponent.class);
ivCipher = crypto.getIvCipher(); tagCipher = crypto.getTagCipher();
frameCipher = crypto.getFrameCipher(); frameCipher = crypto.getFrameCipher();
random = new Random(); random = new Random();
// Since we're sending frames to ourselves, we only need outgoing keys // Since we're sending frames to ourselves, we only need outgoing keys
outSecret = new byte[32]; outSecret = new byte[32];
random.nextBytes(outSecret); random.nextBytes(outSecret);
ivKey = crypto.deriveIvKey(outSecret, true); tagKey = crypto.deriveTagKey(outSecret, true);
frameKey = crypto.deriveFrameKey(outSecret, true); frameKey = crypto.deriveFrameKey(outSecret, true);
macKey = crypto.deriveMacKey(outSecret, true); macKey = crypto.deriveMacKey(outSecret, true);
mac = crypto.getMac(); mac = crypto.getMac();
@@ -65,9 +65,9 @@ public class FrameReadWriteTest extends TestCase {
private void testWriteAndRead(boolean initiator) throws Exception { private void testWriteAndRead(boolean initiator) throws Exception {
// Create and encrypt the IV // Create and encrypt the IV
byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); byte[] iv = IvEncoder.encodeIv(transportIndex.getInt(), connection);
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey); tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
byte[] encryptedIv = ivCipher.doFinal(iv); byte[] tag = tagCipher.doFinal(iv);
assertEquals(IV_LENGTH, encryptedIv.length); assertEquals(TAG_LENGTH, tag.length);
// Generate two random frames // Generate two random frames
byte[] frame = new byte[12345]; byte[] frame = new byte[12345];
random.nextBytes(frame); random.nextBytes(frame);
@@ -75,12 +75,12 @@ public class FrameReadWriteTest extends TestCase {
random.nextBytes(frame1); random.nextBytes(frame1);
// Copy the keys - the copies will be erased // Copy the keys - the copies will be erased
ErasableKey frameCopy = frameKey.copy(); ErasableKey frameCopy = frameKey.copy();
ErasableKey ivCopy = ivKey.copy(); ErasableKey tagCopy = tagKey.copy();
ErasableKey macCopy = macKey.copy(); ErasableKey macCopy = macKey.copy();
// Write the frames // Write the frames
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out, ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out,
Long.MAX_VALUE, iv, ivCipher, frameCipher, ivCopy, frameCopy); Long.MAX_VALUE, iv, tagCipher, frameCipher, tagCopy, frameCopy);
ConnectionWriter writer = new ConnectionWriterImpl(encrypter, mac, ConnectionWriter writer = new ConnectionWriterImpl(encrypter, mac,
macCopy); macCopy);
OutputStream out1 = writer.getOutputStream(); OutputStream out1 = writer.getOutputStream();
@@ -90,12 +90,12 @@ public class FrameReadWriteTest extends TestCase {
out1.flush(); out1.flush();
// Read the IV back // Read the IV back
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
byte[] recoveredEncryptedIv = new byte[IV_LENGTH]; byte[] recoveredTag = new byte[TAG_LENGTH];
assertEquals(IV_LENGTH, in.read(recoveredEncryptedIv)); assertEquals(TAG_LENGTH, in.read(recoveredTag));
assertArrayEquals(encryptedIv, recoveredEncryptedIv); assertArrayEquals(tag, recoveredTag);
// Decrypt the IV // Decrypt the IV
ivCipher.init(Cipher.DECRYPT_MODE, ivKey); tagCipher.init(Cipher.DECRYPT_MODE, tagKey);
byte[] recoveredIv = ivCipher.doFinal(recoveredEncryptedIv); byte[] recoveredIv = tagCipher.doFinal(recoveredTag);
iv = IvEncoder.encodeIv(transportIndex.getInt(), connection); iv = IvEncoder.encodeIv(transportIndex.getInt(), connection);
assertArrayEquals(iv, recoveredIv); assertArrayEquals(iv, recoveredIv);
// Read the frames back // Read the frames back

View File

@@ -1,6 +1,6 @@
package net.sf.briar.transport.batch; package net.sf.briar.transport.batch;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH; import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -170,11 +170,11 @@ public class BatchConnectionReadWriteTest extends TestCase {
// Create a connection recogniser and recognise the connection // Create a connection recogniser and recognise the connection
ByteArrayInputStream in = new ByteArrayInputStream(b); ByteArrayInputStream in = new ByteArrayInputStream(b);
ConnectionRecogniser rec = bob.getInstance(ConnectionRecogniser.class); ConnectionRecogniser rec = bob.getInstance(ConnectionRecogniser.class);
byte[] encryptedIv = new byte[IV_LENGTH]; byte[] tag = new byte[TAG_LENGTH];
int read = in.read(encryptedIv); int read = in.read(tag);
assertEquals(encryptedIv.length, read); assertEquals(tag.length, read);
TestCallback callback = new TestCallback(); TestCallback callback = new TestCallback();
rec.acceptConnection(transportId, encryptedIv, callback); rec.acceptConnection(transportId, tag, callback);
callback.latch.await(); callback.latch.await();
ConnectionContext ctx = callback.ctx; ConnectionContext ctx = callback.ctx;
assertNotNull(ctx); assertNotNull(ctx);
@@ -187,7 +187,7 @@ public class BatchConnectionReadWriteTest extends TestCase {
bob.getInstance(ProtocolReaderFactory.class); bob.getInstance(ProtocolReaderFactory.class);
BatchTransportReader reader = new TestBatchTransportReader(in); BatchTransportReader reader = new TestBatchTransportReader(in);
IncomingBatchConnection batchIn = new IncomingBatchConnection( IncomingBatchConnection batchIn = new IncomingBatchConnection(
connFactory, db, protoFactory, ctx, reader, encryptedIv); connFactory, db, protoFactory, ctx, reader, tag);
// No messages should have been added yet // No messages should have been added yet
assertFalse(listener.messagesAdded); assertFalse(listener.messagesAdded);
// Read whatever needs to be read // Read whatever needs to be read