mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Renamed "encrypted IVs" as "tags" (actual crypto changes to follow).
This commit is contained in:
@@ -30,7 +30,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
private static final String FRAME_CIPHER_ALGO = "AES/CTR/NoPadding";
|
||||
private static final String SECRET_KEY_ALGO = "AES";
|
||||
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 SIGNATURE_ALGO = "ECDSA";
|
||||
private static final String KEY_DERIVATION_ALGO = "AES/CTR/NoPadding";
|
||||
@@ -38,7 +38,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
|
||||
// Labels for key derivation, null-terminated
|
||||
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[] NEXT = { 'N', 'E', 'X', 'T', 0 };
|
||||
// Context strings for key derivation
|
||||
@@ -71,9 +71,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
else return deriveKey(secret, FRAME, RESPONDER);
|
||||
}
|
||||
|
||||
public ErasableKey deriveIvKey(byte[] secret, boolean initiator) {
|
||||
if(initiator) return deriveKey(secret, IV, INITIATOR);
|
||||
else return deriveKey(secret, IV, RESPONDER);
|
||||
public ErasableKey deriveTagKey(byte[] secret, boolean initiator) {
|
||||
if(initiator) return deriveKey(secret, TAG, INITIATOR);
|
||||
else return deriveKey(secret, TAG, RESPONDER);
|
||||
}
|
||||
|
||||
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() {
|
||||
return keyParser;
|
||||
}
|
||||
@@ -183,4 +175,12 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Cipher getTagCipher() {
|
||||
try {
|
||||
return Cipher.getInstance(TAG_CIPHER_ALGO, PROVIDER);
|
||||
} catch(GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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 java.io.EOFException;
|
||||
@@ -31,11 +31,11 @@ implements ConnectionDecrypter {
|
||||
ConnectionDecrypterImpl(InputStream in, byte[] iv, Cipher frameCipher,
|
||||
ErasableKey frameKey) {
|
||||
super(in);
|
||||
if(iv.length != IV_LENGTH) throw new IllegalArgumentException();
|
||||
if(iv.length != TAG_LENGTH) throw new IllegalArgumentException();
|
||||
this.iv = iv;
|
||||
this.frameCipher = frameCipher;
|
||||
this.frameKey = frameKey;
|
||||
buf = new byte[IV_LENGTH];
|
||||
buf = new byte[TAG_LENGTH];
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
|
||||
@@ -41,20 +41,20 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
|
||||
}
|
||||
|
||||
public void dispatchReader(TransportId t, final BatchTransportReader r) {
|
||||
// Read the encrypted IV
|
||||
final byte[] encryptedIv;
|
||||
// Read the tag
|
||||
final byte[] tag;
|
||||
try {
|
||||
encryptedIv = readIv(r.getInputStream());
|
||||
tag = readTag(r.getInputStream());
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
|
||||
r.dispose(false);
|
||||
return;
|
||||
}
|
||||
// Get the connection context asynchronously
|
||||
recogniser.acceptConnection(t, encryptedIv, new Callback() {
|
||||
recogniser.acceptConnection(t, tag, new Callback() {
|
||||
|
||||
public void connectionAccepted(ConnectionContext ctx) {
|
||||
batchConnFactory.createIncomingConnection(ctx, r, encryptedIv);
|
||||
batchConnFactory.createIncomingConnection(ctx, r, tag);
|
||||
}
|
||||
|
||||
public void connectionRejected() {
|
||||
@@ -68,8 +68,8 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
|
||||
});
|
||||
}
|
||||
|
||||
private byte[] readIv(InputStream in) throws IOException {
|
||||
byte[] b = new byte[TransportConstants.IV_LENGTH];
|
||||
private byte[] readTag(InputStream in) throws IOException {
|
||||
byte[] b = new byte[TransportConstants.TAG_LENGTH];
|
||||
int offset = 0;
|
||||
while(offset < b.length) {
|
||||
int read = in.read(b, offset, b.length - offset);
|
||||
@@ -86,20 +86,20 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
|
||||
|
||||
public void dispatchIncomingConnection(TransportId t,
|
||||
final StreamTransportConnection s) {
|
||||
// Read the encrypted IV
|
||||
final byte[] encryptedIv;
|
||||
// Read the tag
|
||||
final byte[] tag;
|
||||
try {
|
||||
encryptedIv = readIv(s.getInputStream());
|
||||
tag = readTag(s.getInputStream());
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
|
||||
s.dispose(false);
|
||||
return;
|
||||
}
|
||||
// Get the connection context asynchronously
|
||||
recogniser.acceptConnection(t, encryptedIv, new Callback() {
|
||||
recogniser.acceptConnection(t, tag, new Callback() {
|
||||
|
||||
public void connectionAccepted(ConnectionContext ctx) {
|
||||
streamConnFactory.createIncomingConnection(ctx, s, encryptedIv);
|
||||
streamConnFactory.createIncomingConnection(ctx, s, tag);
|
||||
}
|
||||
|
||||
public void connectionRejected() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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 java.io.FilterOutputStream;
|
||||
@@ -20,23 +20,23 @@ implements ConnectionEncrypter {
|
||||
|
||||
private final Cipher frameCipher;
|
||||
private final ErasableKey frameKey;
|
||||
private final byte[] iv, encryptedIv;
|
||||
private final byte[] iv, tag;
|
||||
|
||||
private long capacity, frame = 0L;
|
||||
private boolean ivWritten = false, betweenFrames = false;
|
||||
private boolean tagWritten = false, betweenFrames = false;
|
||||
|
||||
ConnectionEncrypterImpl(OutputStream out, long capacity, byte[] iv,
|
||||
Cipher ivCipher, Cipher frameCipher, ErasableKey ivKey,
|
||||
Cipher tagCipher, Cipher frameCipher, ErasableKey tagKey,
|
||||
ErasableKey frameKey) {
|
||||
super(out);
|
||||
this.capacity = capacity;
|
||||
this.iv = iv;
|
||||
this.frameCipher = frameCipher;
|
||||
this.frameKey = frameKey;
|
||||
// Encrypt the IV
|
||||
// Encrypt the tag
|
||||
try {
|
||||
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey);
|
||||
encryptedIv = ivCipher.doFinal(iv);
|
||||
tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
|
||||
tag = tagCipher.doFinal(iv);
|
||||
} catch(BadPaddingException badCipher) {
|
||||
throw new IllegalArgumentException(badCipher);
|
||||
} catch(IllegalBlockSizeException badCipher) {
|
||||
@@ -44,9 +44,8 @@ implements ConnectionEncrypter {
|
||||
} catch(InvalidKeyException badKey) {
|
||||
throw new IllegalArgumentException(badKey);
|
||||
}
|
||||
if(encryptedIv.length != IV_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
ivKey.erase();
|
||||
if(tag.length != TAG_LENGTH) throw new IllegalArgumentException();
|
||||
tagKey.erase();
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
@@ -55,7 +54,7 @@ implements ConnectionEncrypter {
|
||||
|
||||
public void writeMac(byte[] mac) throws IOException {
|
||||
try {
|
||||
if(!ivWritten || betweenFrames) throw new IllegalStateException();
|
||||
if(!tagWritten || betweenFrames) throw new IllegalStateException();
|
||||
try {
|
||||
out.write(frameCipher.doFinal(mac));
|
||||
} catch(BadPaddingException badCipher) {
|
||||
@@ -78,7 +77,7 @@ implements ConnectionEncrypter {
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
try {
|
||||
if(!ivWritten) writeIv();
|
||||
if(!tagWritten) writeTag();
|
||||
if(betweenFrames) initialiseCipher();
|
||||
byte[] ciphertext = frameCipher.update(new byte[] {(byte) b});
|
||||
if(ciphertext != null) out.write(ciphertext);
|
||||
@@ -97,7 +96,7 @@ implements ConnectionEncrypter {
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
try {
|
||||
if(!ivWritten) writeIv();
|
||||
if(!tagWritten) writeTag();
|
||||
if(betweenFrames) initialiseCipher();
|
||||
byte[] ciphertext = frameCipher.update(b, off, len);
|
||||
if(ciphertext != null) out.write(ciphertext);
|
||||
@@ -108,17 +107,17 @@ implements ConnectionEncrypter {
|
||||
}
|
||||
}
|
||||
|
||||
private void writeIv() throws IOException {
|
||||
assert !ivWritten;
|
||||
private void writeTag() throws IOException {
|
||||
assert !tagWritten;
|
||||
assert !betweenFrames;
|
||||
out.write(encryptedIv);
|
||||
capacity -= encryptedIv.length;
|
||||
ivWritten = true;
|
||||
out.write(tag);
|
||||
capacity -= tag.length;
|
||||
tagWritten = true;
|
||||
betweenFrames = true;
|
||||
}
|
||||
|
||||
private void initialiseCipher() {
|
||||
assert ivWritten;
|
||||
assert tagWritten;
|
||||
assert betweenFrames;
|
||||
if(frame > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
|
||||
IvEncoder.updateIv(iv, frame);
|
||||
|
||||
@@ -27,14 +27,14 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
|
||||
}
|
||||
|
||||
public ConnectionReader createConnectionReader(InputStream in,
|
||||
ConnectionContext ctx, byte[] encryptedIv) {
|
||||
// Decrypt the IV
|
||||
Cipher ivCipher = crypto.getIvCipher();
|
||||
ErasableKey ivKey = crypto.deriveIvKey(ctx.getSecret(), true);
|
||||
ConnectionContext ctx, byte[] tag) {
|
||||
// Decrypt the tag
|
||||
Cipher tagCipher = crypto.getTagCipher();
|
||||
ErasableKey tagKey = crypto.deriveTagKey(ctx.getSecret(), true);
|
||||
byte[] iv;
|
||||
try {
|
||||
ivCipher.init(Cipher.DECRYPT_MODE, ivKey);
|
||||
iv = ivCipher.doFinal(encryptedIv);
|
||||
tagCipher.init(Cipher.DECRYPT_MODE, tagKey);
|
||||
iv = tagCipher.doFinal(tag);
|
||||
} catch(BadPaddingException badCipher) {
|
||||
throw new IllegalArgumentException(badCipher);
|
||||
} catch(IllegalBlockSizeException badCipher) {
|
||||
@@ -42,8 +42,8 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
|
||||
} catch(InvalidKeyException badKey) {
|
||||
throw new IllegalArgumentException(badKey);
|
||||
}
|
||||
ivKey.erase();
|
||||
// Validate the IV
|
||||
tagKey.erase();
|
||||
// Validate the tag
|
||||
int index = ctx.getTransportIndex().getInt();
|
||||
long connection = ctx.getConnectionNumber();
|
||||
if(!IvEncoder.validateIv(iv, index, connection))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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.util.ArrayList;
|
||||
@@ -50,7 +50,7 @@ DatabaseListener {
|
||||
private final CryptoComponent crypto;
|
||||
private final DatabaseComponent db;
|
||||
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 Map<Bytes, Context> expected; // Locking: this
|
||||
|
||||
@@ -62,7 +62,7 @@ DatabaseListener {
|
||||
this.crypto = crypto;
|
||||
this.db = db;
|
||||
this.executor = executor;
|
||||
ivCipher = crypto.getIvCipher();
|
||||
tagCipher = crypto.getTagCipher();
|
||||
localTransportIds = new HashSet<TransportId>();
|
||||
expected = new HashMap<Bytes, Context>();
|
||||
}
|
||||
@@ -87,7 +87,7 @@ DatabaseListener {
|
||||
ConnectionWindow w = db.getConnectionWindow(c, i);
|
||||
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
|
||||
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();
|
||||
}
|
||||
@@ -102,14 +102,14 @@ DatabaseListener {
|
||||
}
|
||||
|
||||
// Locking: this
|
||||
private Bytes calculateIv(Context ctx, byte[] secret) {
|
||||
private Bytes calculateTag(Context ctx, byte[] secret) {
|
||||
byte[] iv = IvEncoder.encodeIv(ctx.transportIndex.getInt(),
|
||||
ctx.connection);
|
||||
ErasableKey ivKey = crypto.deriveIvKey(secret, true);
|
||||
ErasableKey tagKey = crypto.deriveTagKey(secret, true);
|
||||
try {
|
||||
ivCipher.init(Cipher.ENCRYPT_MODE, ivKey);
|
||||
byte[] encryptedIv = ivCipher.doFinal(iv);
|
||||
return new Bytes(encryptedIv);
|
||||
tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
|
||||
byte[] tag = tagCipher.doFinal(iv);
|
||||
return new Bytes(tag);
|
||||
} catch(BadPaddingException badCipher) {
|
||||
throw new RuntimeException(badCipher);
|
||||
} catch(IllegalBlockSizeException badCipher) {
|
||||
@@ -117,16 +117,16 @@ DatabaseListener {
|
||||
} catch(InvalidKeyException badKey) {
|
||||
throw new RuntimeException(badKey);
|
||||
} 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) {
|
||||
executor.execute(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
ConnectionContext ctx = acceptConnection(t, encryptedIv);
|
||||
ConnectionContext ctx = acceptConnection(t, tag);
|
||||
if(ctx == null) callback.connectionRejected();
|
||||
else callback.connectionAccepted(ctx);
|
||||
} catch(DbException e) {
|
||||
@@ -137,13 +137,13 @@ DatabaseListener {
|
||||
}
|
||||
|
||||
// Package access for testing
|
||||
ConnectionContext acceptConnection(TransportId t, byte[] encryptedIv)
|
||||
ConnectionContext acceptConnection(TransportId t, byte[] tag)
|
||||
throws DbException {
|
||||
if(encryptedIv.length != IV_LENGTH)
|
||||
if(tag.length != TAG_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
synchronized(this) {
|
||||
if(!initialised) initialise();
|
||||
Bytes b = new Bytes(encryptedIv);
|
||||
Bytes b = new Bytes(tag);
|
||||
Context ctx = expected.get(b);
|
||||
if(ctx == null || !ctx.transportId.equals(t)) return null;
|
||||
// The IV was expected
|
||||
@@ -173,7 +173,7 @@ DatabaseListener {
|
||||
}
|
||||
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
|
||||
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();
|
||||
return new ConnectionContextImpl(c, i, connection, secret);
|
||||
@@ -227,7 +227,7 @@ DatabaseListener {
|
||||
ConnectionWindow w = db.getConnectionWindow(c, i);
|
||||
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
|
||||
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();
|
||||
} catch(NoSuchContactException e) {
|
||||
@@ -256,7 +256,7 @@ DatabaseListener {
|
||||
ConnectionWindow w = db.getConnectionWindow(c, i);
|
||||
for(Entry<Long, byte[]> e : w.getUnseen().entrySet()) {
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -32,14 +32,14 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
}
|
||||
|
||||
public ConnectionWriter createConnectionWriter(OutputStream out,
|
||||
long capacity, ConnectionContext ctx, byte[] encryptedIv) {
|
||||
// Decrypt the IV
|
||||
Cipher ivCipher = crypto.getIvCipher();
|
||||
ErasableKey ivKey = crypto.deriveIvKey(ctx.getSecret(), true);
|
||||
long capacity, ConnectionContext ctx, byte[] tag) {
|
||||
// Decrypt the tag
|
||||
Cipher tagCipher = crypto.getTagCipher();
|
||||
ErasableKey tagKey = crypto.deriveTagKey(ctx.getSecret(), true);
|
||||
byte[] iv;
|
||||
try {
|
||||
ivCipher.init(Cipher.DECRYPT_MODE, ivKey);
|
||||
iv = ivCipher.doFinal(encryptedIv);
|
||||
tagCipher.init(Cipher.DECRYPT_MODE, tagKey);
|
||||
iv = tagCipher.doFinal(tag);
|
||||
} catch(BadPaddingException badCipher) {
|
||||
throw new RuntimeException(badCipher);
|
||||
} catch(IllegalBlockSizeException badCipher) {
|
||||
@@ -47,8 +47,8 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
} catch(InvalidKeyException badKey) {
|
||||
throw new RuntimeException(badKey);
|
||||
}
|
||||
ivKey.erase();
|
||||
// Validate the IV
|
||||
tagKey.erase();
|
||||
// Validate the tag
|
||||
int index = ctx.getTransportIndex().getInt();
|
||||
long connection = ctx.getConnectionNumber();
|
||||
if(!IvEncoder.validateIv(iv, index, connection))
|
||||
@@ -60,7 +60,7 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
long capacity, boolean initiator, ConnectionContext ctx) {
|
||||
// Derive the keys and erase the secret
|
||||
byte[] secret = ctx.getSecret();
|
||||
ErasableKey ivKey = crypto.deriveIvKey(secret, initiator);
|
||||
ErasableKey tagKey = crypto.deriveTagKey(secret, initiator);
|
||||
ErasableKey frameKey = crypto.deriveFrameKey(secret, initiator);
|
||||
ErasableKey macKey = crypto.deriveMacKey(secret, initiator);
|
||||
ByteUtils.erase(secret);
|
||||
@@ -68,10 +68,10 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
int index = ctx.getTransportIndex().getInt();
|
||||
long connection = ctx.getConnectionNumber();
|
||||
byte[] iv = IvEncoder.encodeIv(index, connection);
|
||||
Cipher ivCipher = crypto.getIvCipher();
|
||||
Cipher tagCipher = crypto.getTagCipher();
|
||||
Cipher frameCipher = crypto.getFrameCipher();
|
||||
ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out,
|
||||
capacity, iv, ivCipher, frameCipher, ivKey, frameKey);
|
||||
capacity, iv, tagCipher, frameCipher, tagKey, frameKey);
|
||||
// Create the writer
|
||||
Mac mac = crypto.getMac();
|
||||
return new ConnectionWriterImpl(encrypter, mac, macKey);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
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;
|
||||
|
||||
class IvEncoder {
|
||||
|
||||
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
|
||||
ByteUtils.writeUint16(index, iv, 4);
|
||||
// Encode the connection number as an unsigned 32-bit integer
|
||||
@@ -15,13 +15,13 @@ class IvEncoder {
|
||||
}
|
||||
|
||||
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
|
||||
ByteUtils.writeUint32(frame, iv, 10);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
@@ -34,12 +34,12 @@ class IvEncoder {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ class BatchConnectionFactoryImpl implements BatchConnectionFactory {
|
||||
}
|
||||
|
||||
public void createIncomingConnection(ConnectionContext ctx,
|
||||
BatchTransportReader r, byte[] encryptedIv) {
|
||||
BatchTransportReader r, byte[] tag) {
|
||||
final IncomingBatchConnection conn = new IncomingBatchConnection(
|
||||
connReaderFactory, db, protoReaderFactory, ctx, r, encryptedIv);
|
||||
connReaderFactory, db, protoReaderFactory, ctx, r, tag);
|
||||
Runnable read = new Runnable() {
|
||||
public void run() {
|
||||
conn.read();
|
||||
|
||||
@@ -29,24 +29,23 @@ class IncomingBatchConnection {
|
||||
private final ProtocolReaderFactory protoFactory;
|
||||
private final ConnectionContext ctx;
|
||||
private final BatchTransportReader reader;
|
||||
private final byte[] encryptedIv;
|
||||
private final byte[] tag;
|
||||
|
||||
IncomingBatchConnection(ConnectionReaderFactory connFactory,
|
||||
DatabaseComponent db, ProtocolReaderFactory protoFactory,
|
||||
ConnectionContext ctx, BatchTransportReader reader,
|
||||
byte[] encryptedIv) {
|
||||
ConnectionContext ctx, BatchTransportReader reader, byte[] tag) {
|
||||
this.connFactory = connFactory;
|
||||
this.db = db;
|
||||
this.protoFactory = protoFactory;
|
||||
this.ctx = ctx;
|
||||
this.reader = reader;
|
||||
this.encryptedIv = encryptedIv;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
void read() {
|
||||
try {
|
||||
ConnectionReader conn = connFactory.createConnectionReader(
|
||||
reader.getInputStream(), ctx, encryptedIv);
|
||||
reader.getInputStream(), ctx, tag);
|
||||
ProtocolReader proto = protoFactory.createProtocolReader(
|
||||
conn.getInputStream());
|
||||
ContactId c = ctx.getContactId();
|
||||
|
||||
@@ -16,31 +16,31 @@ import net.sf.briar.api.transport.StreamTransportConnection;
|
||||
class IncomingStreamConnection extends StreamConnection {
|
||||
|
||||
private final ConnectionContext ctx;
|
||||
private final byte[] encryptedIv;
|
||||
private final byte[] tag;
|
||||
|
||||
IncomingStreamConnection(ConnectionReaderFactory connReaderFactory,
|
||||
ConnectionWriterFactory connWriterFactory, DatabaseComponent db,
|
||||
ProtocolReaderFactory protoReaderFactory,
|
||||
ProtocolWriterFactory protoWriterFactory,
|
||||
ConnectionContext ctx, StreamTransportConnection connection,
|
||||
byte[] encryptedIv) {
|
||||
byte[] tag) {
|
||||
super(connReaderFactory, connWriterFactory, db, protoReaderFactory,
|
||||
protoWriterFactory, ctx.getContactId(), connection);
|
||||
this.ctx = ctx;
|
||||
this.encryptedIv = encryptedIv;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionReader createConnectionReader() throws DbException,
|
||||
IOException {
|
||||
return connReaderFactory.createConnectionReader(
|
||||
connection.getInputStream(), ctx, encryptedIv);
|
||||
connection.getInputStream(), ctx, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionWriter createConnectionWriter() throws DbException,
|
||||
IOException {
|
||||
return connWriterFactory.createConnectionWriter(
|
||||
connection.getOutputStream(), Long.MAX_VALUE, ctx, encryptedIv);
|
||||
connection.getOutputStream(), Long.MAX_VALUE, ctx, tag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,10 @@ class StreamConnectionFactoryImpl implements StreamConnectionFactory {
|
||||
}
|
||||
|
||||
public void createIncomingConnection(ConnectionContext ctx,
|
||||
StreamTransportConnection s, byte[] encryptedIv) {
|
||||
StreamTransportConnection s, byte[] tag) {
|
||||
final StreamConnection conn = new IncomingStreamConnection(
|
||||
connReaderFactory, connWriterFactory, db, protoReaderFactory,
|
||||
protoWriterFactory, ctx, s, encryptedIv);
|
||||
protoWriterFactory, ctx, s, tag);
|
||||
Runnable write = new Runnable() {
|
||||
public void run() {
|
||||
conn.write();
|
||||
|
||||
Reference in New Issue
Block a user