Offer IDs no longer need to be calculated or echoed in requests.

The initiator flag in the transport protocol makes this unnecessary by
linking the two sides of a stream-mode connection, making it
impossible for an attacker to replay the responder's side of a
different connection.
This commit is contained in:
akwizgran
2011-09-12 16:21:17 +01:00
parent 7ed747b2a3
commit 64548375cc
27 changed files with 45 additions and 194 deletions

View File

@@ -815,7 +815,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
db.abortTransaction(txn);
throw e;
}
r.writeRequest(o.getId(), request, offered.size());
r.writeRequest(request, offered.size());
} finally {
subscriptionLock.readLock().unlock();
}

View File

@@ -627,7 +627,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
db.abortTransaction(txn);
throw e;
}
r.writeRequest(o.getId(), request, offered.size());
r.writeRequest(request, offered.size());
}
}
}

View File

@@ -4,9 +4,8 @@ import java.util.Collection;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.OfferId;
interface OfferFactory {
Offer createOffer(OfferId id, Collection<MessageId> offered);
Offer createOffer(Collection<MessageId> offered);
}

View File

@@ -4,11 +4,10 @@ import java.util.Collection;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.OfferId;
class OfferFactoryImpl implements OfferFactory {
public Offer createOffer(OfferId id, Collection<MessageId> offered) {
return new OfferImpl(id, offered);
public Offer createOffer(Collection<MessageId> offered) {
return new OfferImpl(offered);
}
}

View File

@@ -1,20 +0,0 @@
package net.sf.briar.protocol;
import java.io.IOException;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.protocol.UniqueId;
import net.sf.briar.api.serial.ObjectReader;
import net.sf.briar.api.serial.Reader;
class OfferIdReader implements ObjectReader<OfferId> {
public OfferId readObject(Reader r) throws IOException {
r.readUserDefinedTag(Tags.OFFER_ID);
byte[] b = r.readBytes(UniqueId.LENGTH);
if(b.length != UniqueId.LENGTH) throw new FormatException();
return new OfferId(b);
}
}

View File

@@ -4,22 +4,15 @@ import java.util.Collection;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.OfferId;
class OfferImpl implements Offer {
private final OfferId id;
private final Collection<MessageId> offered;
OfferImpl(OfferId id, Collection<MessageId> offered) {
this.id = id;
OfferImpl(Collection<MessageId> offered) {
this.offered = offered;
}
public OfferId getId() {
return id;
}
public Collection<MessageId> getMessageIds() {
return offered;
}

View File

@@ -1,14 +1,11 @@
package net.sf.briar.protocol;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.Collection;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.serial.Consumer;
@@ -17,36 +14,29 @@ import net.sf.briar.api.serial.Reader;
class OfferReader implements ObjectReader<Offer> {
private final MessageDigest messageDigest;
private final ObjectReader<MessageId> messageIdReader;
private final OfferFactory offerFactory;
OfferReader(CryptoComponent crypto, ObjectReader<MessageId> messageIdReader,
OfferReader(ObjectReader<MessageId> messageIdReader,
OfferFactory offerFactory) {
messageDigest = crypto.getMessageDigest();
this.messageIdReader = messageIdReader;
this.offerFactory = offerFactory;
}
public Offer readObject(Reader r) throws IOException {
// Initialise the consumers
// Initialise the consumer
Consumer counting =
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
DigestingConsumer digesting = new DigestingConsumer(messageDigest);
messageDigest.reset();
// Read the data
r.addConsumer(counting);
r.addConsumer(digesting);
r.readUserDefinedTag(Tags.OFFER);
r.addObjectReader(Tags.MESSAGE_ID, messageIdReader);
Collection<MessageId> messages = r.readList(MessageId.class);
if(messages.size() > Offer.MAX_IDS_PER_OFFER)
throw new FormatException();
r.removeObjectReader(Tags.MESSAGE_ID);
r.removeConsumer(digesting);
r.removeConsumer(counting);
// Build and return the offer
OfferId id = new OfferId(messageDigest.digest());
return offerFactory.createOffer(id, messages);
return offerFactory.createOffer(messages);
}
}

View File

@@ -12,7 +12,6 @@ import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageEncoder;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.ProtocolReaderFactory;
import net.sf.briar.api.protocol.Request;
import net.sf.briar.api.protocol.SubscriptionUpdate;
@@ -82,21 +81,14 @@ public class ProtocolModule extends AbstractModule {
}
@Provides
ObjectReader<OfferId> getOfferIdReader() {
return new OfferIdReader();
}
@Provides
ObjectReader<Offer> getOfferReader(CryptoComponent crypto,
ObjectReader<MessageId> messageIdReader,
ObjectReader<Offer> getOfferReader(ObjectReader<MessageId> messageIdReader,
OfferFactory offerFactory) {
return new OfferReader(crypto, messageIdReader, offerFactory);
return new OfferReader(messageIdReader, offerFactory);
}
@Provides
ObjectReader<Request> getRequestReader(ObjectReader<OfferId> offerIdReader,
RequestFactory requestFactory) {
return new RequestReader(offerIdReader, requestFactory);
ObjectReader<Request> getRequestReader(RequestFactory requestFactory) {
return new RequestReader(requestFactory);
}
@Provides

View File

@@ -2,10 +2,9 @@ package net.sf.briar.protocol;
import java.util.BitSet;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.Request;
interface RequestFactory {
Request createRequest(OfferId offerId, BitSet requested);
Request createRequest(BitSet requested);
}

View File

@@ -2,12 +2,11 @@ package net.sf.briar.protocol;
import java.util.BitSet;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.Request;
class RequestFactoryImpl implements RequestFactory {
public Request createRequest(OfferId offerId, BitSet requested) {
return new RequestImpl(offerId, requested);
public Request createRequest(BitSet requested) {
return new RequestImpl(requested);
}
}

View File

@@ -2,23 +2,16 @@ package net.sf.briar.protocol;
import java.util.BitSet;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.Request;
class RequestImpl implements Request {
private final OfferId offerId;
private final BitSet requested;
RequestImpl(OfferId offerId, BitSet requested) {
this.offerId = offerId;
RequestImpl(BitSet requested) {
this.requested = requested;
}
public OfferId getOfferId() {
return offerId;
}
public BitSet getBitmap() {
return requested;
}

View File

@@ -3,7 +3,6 @@ package net.sf.briar.protocol;
import java.io.IOException;
import java.util.BitSet;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Request;
import net.sf.briar.api.protocol.Tags;
@@ -13,12 +12,9 @@ import net.sf.briar.api.serial.Reader;
class RequestReader implements ObjectReader<Request> {
private final ObjectReader<OfferId> offerIdReader;
private final RequestFactory requestFactory;
RequestReader(ObjectReader<OfferId> offerIdReader,
RequestFactory requestFactory) {
this.offerIdReader = offerIdReader;
RequestReader(RequestFactory requestFactory) {
this.requestFactory = requestFactory;
}
@@ -29,8 +25,6 @@ class RequestReader implements ObjectReader<Request> {
// Read the data
r.addConsumer(counting);
r.readUserDefinedTag(Tags.REQUEST);
r.addObjectReader(Tags.OFFER_ID, offerIdReader);
OfferId offerId = r.readUserDefined(Tags.OFFER_ID, OfferId.class);
byte[] bitmap = r.readBytes(ProtocolConstants.MAX_PACKET_LENGTH);
r.removeConsumer(counting);
// Convert the bitmap into a BitSet
@@ -41,6 +35,6 @@ class RequestReader implements ObjectReader<Request> {
if((bitmap[i] & bit) != 0) b.set(i * 8 + j);
}
}
return requestFactory.createRequest(offerId, b);
return requestFactory.createRequest(b);
}
}

View File

@@ -2,12 +2,9 @@ package net.sf.briar.protocol.writers;
import java.io.IOException;
import java.io.OutputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.protocol.writers.OfferWriter;
import net.sf.briar.api.serial.Writer;
@@ -17,21 +14,17 @@ class OfferWriterImpl implements OfferWriter {
private final OutputStream out;
private final Writer w;
private final MessageDigest messageDigest;
private boolean started = false;
private int idsWritten = 0;
OfferWriterImpl(OutputStream out, WriterFactory writerFactory,
MessageDigest messageDigest) {
this.out = new DigestOutputStream(out, messageDigest);
OfferWriterImpl(OutputStream out, WriterFactory writerFactory) {
this.out = out;
w = writerFactory.createWriter(out);
this.messageDigest = messageDigest;
}
public boolean writeMessageId(MessageId m) throws IOException {
if(!started) {
messageDigest.reset();
w.writeUserDefinedTag(Tags.OFFER);
w.writeListStart();
started = true;
@@ -42,9 +35,8 @@ class OfferWriterImpl implements OfferWriter {
return true;
}
public OfferId finish() throws IOException {
public void finish() throws IOException {
if(!started) {
messageDigest.reset();
w.writeUserDefinedTag(Tags.OFFER);
w.writeListStart();
started = true;
@@ -52,6 +44,5 @@ class OfferWriterImpl implements OfferWriter {
w.writeListEnd();
out.flush();
started = false;
return new OfferId(messageDigest.digest());
}
}

View File

@@ -36,7 +36,7 @@ class ProtocolWriterFactoryImpl implements ProtocolWriterFactory {
}
public OfferWriter createOfferWriter(OutputStream out) {
return new OfferWriterImpl(out, writerFactory, messageDigest);
return new OfferWriterImpl(out, writerFactory);
}
public RequestWriter createRequestWriter(OutputStream out) {

View File

@@ -4,7 +4,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.BitSet;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.protocol.writers.RequestWriter;
import net.sf.briar.api.serial.Writer;
@@ -20,11 +19,9 @@ class RequestWriterImpl implements RequestWriter {
w = writerFactory.createWriter(out);
}
public void writeRequest(OfferId offerId, BitSet b, int length)
public void writeRequest(BitSet b, int length)
throws IOException {
w.writeUserDefinedTag(Tags.REQUEST);
w.writeUserDefinedTag(Tags.OFFER_ID);
w.writeBytes(offerId.getBytes());
// If the number of bits isn't a multiple of 8, round up to a byte
int bytes = length % 8 == 0 ? length / 8 : length / 8 + 1;
byte[] bitmap = new byte[bytes];