Files
briar/components/net/sf/briar/transport/ConnectionDispatcherImpl.java
akwizgran f6ae4734ce Forward secrecy.
Each connection's keys are derived from a secret that is erased after
deriving the keys and the secret for the next connection.
2011-11-16 15:35:16 +00:00

116 lines
3.4 KiB
Java

package net.sf.briar.transport;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.protocol.TransportId;
import net.sf.briar.api.protocol.TransportIndex;
import net.sf.briar.api.transport.BatchConnectionFactory;
import net.sf.briar.api.transport.BatchTransportReader;
import net.sf.briar.api.transport.BatchTransportWriter;
import net.sf.briar.api.transport.ConnectionContext;
import net.sf.briar.api.transport.ConnectionDispatcher;
import net.sf.briar.api.transport.ConnectionRecogniser;
import net.sf.briar.api.transport.StreamConnectionFactory;
import net.sf.briar.api.transport.StreamTransportConnection;
import net.sf.briar.api.transport.TransportConstants;
import com.google.inject.Inject;
public class ConnectionDispatcherImpl implements ConnectionDispatcher {
private static final Logger LOG =
Logger.getLogger(ConnectionDispatcherImpl.class.getName());
private final ConnectionRecogniser recogniser;
private final BatchConnectionFactory batchConnFactory;
private final StreamConnectionFactory streamConnFactory;
@Inject
ConnectionDispatcherImpl(ConnectionRecogniser recogniser,
BatchConnectionFactory batchConnFactory,
StreamConnectionFactory streamConnFactory) {
this.recogniser = recogniser;
this.batchConnFactory = batchConnFactory;
this.streamConnFactory = streamConnFactory;
}
public void dispatchReader(TransportId t, BatchTransportReader r) {
// Read the encrypted IV
byte[] encryptedIv;
try {
encryptedIv = readIv(r.getInputStream());
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
r.dispose(false);
return;
}
// Get the connection context, or null if the IV wasn't expected
ConnectionContext ctx;
try {
ctx = recogniser.acceptConnection(encryptedIv);
} catch(DbException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
r.dispose(false);
return;
}
if(ctx == null) {
r.dispose(false);
return;
}
batchConnFactory.createIncomingConnection(ctx, r, encryptedIv);
}
private byte[] readIv(InputStream in) throws IOException {
byte[] b = new byte[TransportConstants.IV_LENGTH];
int offset = 0;
while(offset < b.length) {
int read = in.read(b, offset, b.length - offset);
if(read == -1) throw new IOException();
offset += read;
}
return b;
}
public void dispatchWriter(ContactId c, TransportIndex i,
BatchTransportWriter w) {
batchConnFactory.createOutgoingConnection(c, i, w);
}
public void dispatchIncomingConnection(TransportId t,
StreamTransportConnection s) {
// Read the encrypted IV
byte[] encryptedIv;
try {
encryptedIv = readIv(s.getInputStream());
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
s.dispose(false);
return;
}
// Get the connection context, or null if the IV wasn't expected
ConnectionContext ctx;
try {
ctx = recogniser.acceptConnection(encryptedIv);
} catch(DbException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
s.dispose(false);
return;
}
if(ctx == null) {
s.dispose(false);
return;
}
streamConnFactory.createIncomingConnection(ctx, s, encryptedIv);
}
public void dispatchOutgoingConnection(ContactId c, TransportIndex i,
StreamTransportConnection s) {
streamConnFactory.createOutgoingConnection(c, i, s);
}
}