mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 19:29:06 +01:00
Moved batch ID calculation off the IO thread.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -10,7 +12,6 @@ import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.protocol.Ack;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.PacketFactory;
|
||||
import net.sf.briar.api.protocol.ProtocolConstants;
|
||||
import net.sf.briar.api.protocol.Types;
|
||||
import net.sf.briar.api.protocol.UniqueId;
|
||||
import net.sf.briar.api.serial.Consumer;
|
||||
@@ -28,8 +29,7 @@ class AckReader implements ObjectReader<Ack> {
|
||||
|
||||
public Ack readObject(Reader r) throws IOException {
|
||||
// Initialise the consumer
|
||||
Consumer counting =
|
||||
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
|
||||
// Read the data
|
||||
r.addConsumer(counting);
|
||||
r.readStructId(Types.ACK);
|
||||
|
||||
@@ -1,52 +1,41 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.crypto.CryptoComponent;
|
||||
import net.sf.briar.api.crypto.MessageDigest;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.ProtocolConstants;
|
||||
import net.sf.briar.api.protocol.Types;
|
||||
import net.sf.briar.api.protocol.UnverifiedBatch;
|
||||
import net.sf.briar.api.serial.Consumer;
|
||||
import net.sf.briar.api.serial.CountingConsumer;
|
||||
import net.sf.briar.api.serial.DigestingConsumer;
|
||||
import net.sf.briar.api.serial.ObjectReader;
|
||||
import net.sf.briar.api.serial.Reader;
|
||||
|
||||
class BatchReader implements ObjectReader<UnverifiedBatch> {
|
||||
|
||||
private final MessageDigest messageDigest;
|
||||
private final ObjectReader<UnverifiedMessage> messageReader;
|
||||
private final UnverifiedBatchFactory batchFactory;
|
||||
|
||||
BatchReader(CryptoComponent crypto,
|
||||
ObjectReader<UnverifiedMessage> messageReader,
|
||||
BatchReader(ObjectReader<UnverifiedMessage> messageReader,
|
||||
UnverifiedBatchFactory batchFactory) {
|
||||
messageDigest = crypto.getMessageDigest();
|
||||
this.messageReader = messageReader;
|
||||
this.batchFactory = batchFactory;
|
||||
}
|
||||
|
||||
public UnverifiedBatch readObject(Reader r) throws IOException {
|
||||
// Initialise the consumers
|
||||
Consumer counting =
|
||||
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
DigestingConsumer digesting = new DigestingConsumer(messageDigest);
|
||||
// Read and digest the data
|
||||
// Initialise the consumer
|
||||
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
|
||||
// Read the data
|
||||
r.addConsumer(counting);
|
||||
r.addConsumer(digesting);
|
||||
r.readStructId(Types.BATCH);
|
||||
r.addObjectReader(Types.MESSAGE, messageReader);
|
||||
List<UnverifiedMessage> messages = r.readList(UnverifiedMessage.class);
|
||||
r.removeObjectReader(Types.MESSAGE);
|
||||
r.removeConsumer(digesting);
|
||||
r.removeConsumer(counting);
|
||||
if(messages.isEmpty()) throw new FormatException();
|
||||
// Build and return the batch
|
||||
BatchId id = new BatchId(messageDigest.digest());
|
||||
return batchFactory.createUnverifiedBatch(id, messages);
|
||||
return batchFactory.createUnverifiedBatch( messages);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_BODY_LENGTH;
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_SIGNATURE_LENGTH;
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_SUBJECT_LENGTH;
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.SALT_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.protocol.Author;
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
import net.sf.briar.api.protocol.ProtocolConstants;
|
||||
import net.sf.briar.api.protocol.Types;
|
||||
import net.sf.briar.api.protocol.UniqueId;
|
||||
import net.sf.briar.api.serial.CopyingConsumer;
|
||||
@@ -27,8 +32,7 @@ class MessageReader implements ObjectReader<UnverifiedMessage> {
|
||||
|
||||
public UnverifiedMessage readObject(Reader r) throws IOException {
|
||||
CopyingConsumer copying = new CopyingConsumer();
|
||||
CountingConsumer counting =
|
||||
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
CountingConsumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
|
||||
r.addConsumer(copying);
|
||||
r.addConsumer(counting);
|
||||
// Read the initial tag
|
||||
@@ -61,16 +65,15 @@ class MessageReader implements ObjectReader<UnverifiedMessage> {
|
||||
r.removeObjectReader(Types.AUTHOR);
|
||||
}
|
||||
// Read the subject
|
||||
String subject = r.readString(ProtocolConstants.MAX_SUBJECT_LENGTH);
|
||||
String subject = r.readString(MAX_SUBJECT_LENGTH);
|
||||
// Read the timestamp
|
||||
long timestamp = r.readInt64();
|
||||
if(timestamp < 0L) throw new FormatException();
|
||||
// Read the salt
|
||||
byte[] salt = r.readBytes(ProtocolConstants.SALT_LENGTH);
|
||||
if(salt.length != ProtocolConstants.SALT_LENGTH)
|
||||
throw new FormatException();
|
||||
byte[] salt = r.readBytes(SALT_LENGTH);
|
||||
if(salt.length != SALT_LENGTH) throw new FormatException();
|
||||
// Read the message body
|
||||
byte[] body = r.readBytes(ProtocolConstants.MAX_BODY_LENGTH);
|
||||
byte[] body = r.readBytes(MAX_BODY_LENGTH);
|
||||
// Record the offset of the body within the message
|
||||
int bodyStart = (int) counting.getCount() - body.length;
|
||||
// Record the length of the data covered by the author's signature
|
||||
@@ -78,13 +81,13 @@ class MessageReader implements ObjectReader<UnverifiedMessage> {
|
||||
// Read the author's signature, if there is one
|
||||
byte[] authorSig = null;
|
||||
if(author == null) r.readNull();
|
||||
else authorSig = r.readBytes(ProtocolConstants.MAX_SIGNATURE_LENGTH);
|
||||
else authorSig = r.readBytes(MAX_SIGNATURE_LENGTH);
|
||||
// Record the length of the data covered by the group's signature
|
||||
int signedByGroup = (int) counting.getCount();
|
||||
// Read the group's signature, if there is one
|
||||
byte[] groupSig = null;
|
||||
if(group == null || group.getPublicKey() == null) r.readNull();
|
||||
else groupSig = r.readBytes(ProtocolConstants.MAX_SIGNATURE_LENGTH);
|
||||
else groupSig = r.readBytes(MAX_SIGNATURE_LENGTH);
|
||||
// That's all, folks
|
||||
r.removeConsumer(counting);
|
||||
r.removeConsumer(copying);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -10,7 +12,6 @@ import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
import net.sf.briar.api.protocol.Offer;
|
||||
import net.sf.briar.api.protocol.PacketFactory;
|
||||
import net.sf.briar.api.protocol.ProtocolConstants;
|
||||
import net.sf.briar.api.protocol.Types;
|
||||
import net.sf.briar.api.protocol.UniqueId;
|
||||
import net.sf.briar.api.serial.Consumer;
|
||||
@@ -28,8 +29,7 @@ class OfferReader implements ObjectReader<Offer> {
|
||||
|
||||
public Offer readObject(Reader r) throws IOException {
|
||||
// Initialise the consumer
|
||||
Consumer counting =
|
||||
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
|
||||
// Read the data
|
||||
r.addConsumer(counting);
|
||||
r.readStructId(Types.OFFER);
|
||||
|
||||
@@ -51,10 +51,10 @@ public class ProtocolModule extends AbstractModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
ObjectReader<UnverifiedBatch> getBatchReader(CryptoComponent crypto,
|
||||
ObjectReader<UnverifiedBatch> getBatchReader(
|
||||
ObjectReader<UnverifiedMessage> messageReader,
|
||||
UnverifiedBatchFactory batchFactory) {
|
||||
return new BatchReader(crypto, messageReader, batchFactory);
|
||||
return new BatchReader(messageReader, batchFactory);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.BitSet;
|
||||
|
||||
import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.protocol.PacketFactory;
|
||||
import net.sf.briar.api.protocol.ProtocolConstants;
|
||||
import net.sf.briar.api.protocol.Request;
|
||||
import net.sf.briar.api.protocol.Types;
|
||||
import net.sf.briar.api.serial.Consumer;
|
||||
@@ -23,14 +24,13 @@ class RequestReader implements ObjectReader<Request> {
|
||||
|
||||
public Request readObject(Reader r) throws IOException {
|
||||
// Initialise the consumer
|
||||
Consumer counting =
|
||||
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
|
||||
// Read the data
|
||||
r.addConsumer(counting);
|
||||
r.readStructId(Types.REQUEST);
|
||||
int padding = r.readUint7();
|
||||
if(padding > 7) throw new FormatException();
|
||||
byte[] bitmap = r.readBytes(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
byte[] bitmap = r.readBytes(MAX_PACKET_LENGTH);
|
||||
r.removeConsumer(counting);
|
||||
// Convert the bitmap into a BitSet
|
||||
int length = bitmap.length * 8 - padding;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.PacketFactory;
|
||||
import net.sf.briar.api.protocol.ProtocolConstants;
|
||||
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||
import net.sf.briar.api.protocol.Types;
|
||||
import net.sf.briar.api.serial.Consumer;
|
||||
@@ -27,8 +28,7 @@ class SubscriptionUpdateReader implements ObjectReader<SubscriptionUpdate> {
|
||||
|
||||
public SubscriptionUpdate readObject(Reader r) throws IOException {
|
||||
// Initialise the consumer
|
||||
Consumer counting =
|
||||
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
|
||||
// Read the data
|
||||
r.addConsumer(counting);
|
||||
r.readStructId(Types.SUBSCRIPTION_UPDATE);
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PROPERTIES_PER_TRANSPORT;
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PROPERTY_LENGTH;
|
||||
import static net.sf.briar.api.protocol.ProtocolConstants.MAX_TRANSPORTS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -8,7 +13,6 @@ import java.util.Set;
|
||||
|
||||
import net.sf.briar.api.FormatException;
|
||||
import net.sf.briar.api.protocol.PacketFactory;
|
||||
import net.sf.briar.api.protocol.ProtocolConstants;
|
||||
import net.sf.briar.api.protocol.Transport;
|
||||
import net.sf.briar.api.protocol.TransportId;
|
||||
import net.sf.briar.api.protocol.TransportIndex;
|
||||
@@ -32,16 +36,14 @@ class TransportUpdateReader implements ObjectReader<TransportUpdate> {
|
||||
|
||||
public TransportUpdate readObject(Reader r) throws IOException {
|
||||
// Initialise the consumer
|
||||
Consumer counting =
|
||||
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
|
||||
Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH);
|
||||
// Read the data
|
||||
r.addConsumer(counting);
|
||||
r.readStructId(Types.TRANSPORT_UPDATE);
|
||||
r.addObjectReader(Types.TRANSPORT, transportReader);
|
||||
Collection<Transport> transports = r.readList(Transport.class);
|
||||
r.removeObjectReader(Types.TRANSPORT);
|
||||
if(transports.size() > ProtocolConstants.MAX_TRANSPORTS)
|
||||
throw new FormatException();
|
||||
if(transports.size() > MAX_TRANSPORTS) throw new FormatException();
|
||||
long timestamp = r.readInt64();
|
||||
r.removeConsumer(counting);
|
||||
// Check for duplicate IDs or indices
|
||||
@@ -65,14 +67,13 @@ class TransportUpdateReader implements ObjectReader<TransportUpdate> {
|
||||
TransportId id = new TransportId(b);
|
||||
// Read the index
|
||||
int i = r.readInt32();
|
||||
if(i < 0 || i >= ProtocolConstants.MAX_TRANSPORTS)
|
||||
throw new FormatException();
|
||||
if(i < 0 || i >= MAX_TRANSPORTS) throw new FormatException();
|
||||
TransportIndex index = new TransportIndex(i);
|
||||
// Read the properties
|
||||
r.setMaxStringLength(ProtocolConstants.MAX_PROPERTY_LENGTH);
|
||||
r.setMaxStringLength(MAX_PROPERTY_LENGTH);
|
||||
Map<String, String> m = r.readMap(String.class, String.class);
|
||||
r.resetMaxStringLength();
|
||||
if(m.size() > ProtocolConstants.MAX_PROPERTIES_PER_TRANSPORT)
|
||||
if(m.size() > MAX_PROPERTIES_PER_TRANSPORT)
|
||||
throw new FormatException();
|
||||
return new Transport(id, index, m);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@ package net.sf.briar.protocol;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.UnverifiedBatch;
|
||||
|
||||
interface UnverifiedBatchFactory {
|
||||
|
||||
UnverifiedBatch createUnverifiedBatch(BatchId id,
|
||||
UnverifiedBatch createUnverifiedBatch(
|
||||
Collection<UnverifiedMessage> messages);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package net.sf.briar.protocol;
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sf.briar.api.crypto.CryptoComponent;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.UnverifiedBatch;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
@@ -17,8 +16,8 @@ class UnverifiedBatchFactoryImpl implements UnverifiedBatchFactory {
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
public UnverifiedBatch createUnverifiedBatch(BatchId id,
|
||||
public UnverifiedBatch createUnverifiedBatch(
|
||||
Collection<UnverifiedMessage> messages) {
|
||||
return new UnverifiedBatchImpl(crypto, id, messages);
|
||||
return new UnverifiedBatchImpl(crypto, messages);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,32 +24,34 @@ import net.sf.briar.api.protocol.UnverifiedBatch;
|
||||
class UnverifiedBatchImpl implements UnverifiedBatch {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final BatchId id;
|
||||
private final Collection<UnverifiedMessage> messages;
|
||||
private final MessageDigest batchDigest, messageDigest;
|
||||
|
||||
// Initialise lazily - the batch may be empty or contain unsigned messages
|
||||
private MessageDigest messageDigest = null;
|
||||
// Initialise lazily - the batch may contain unsigned messages
|
||||
private KeyParser keyParser = null;
|
||||
private Signature signature = null;
|
||||
|
||||
UnverifiedBatchImpl(CryptoComponent crypto, BatchId id,
|
||||
UnverifiedBatchImpl(CryptoComponent crypto,
|
||||
Collection<UnverifiedMessage> messages) {
|
||||
this.crypto = crypto;
|
||||
this.id = id;
|
||||
this.messages = messages;
|
||||
batchDigest = crypto.getMessageDigest();
|
||||
messageDigest = crypto.getMessageDigest();
|
||||
}
|
||||
|
||||
public Batch verify() throws GeneralSecurityException {
|
||||
List<Message> verified = new ArrayList<Message>();
|
||||
for(UnverifiedMessage m : messages) verified.add(verify(m));
|
||||
BatchId id = new BatchId(batchDigest.digest());
|
||||
return new BatchImpl(id, Collections.unmodifiableList(verified));
|
||||
}
|
||||
|
||||
private Message verify(UnverifiedMessage m)
|
||||
throws GeneralSecurityException {
|
||||
// Hash the message, including the signatures, to get the message ID
|
||||
// The batch ID is the hash of the concatenated messages
|
||||
byte[] raw = m.getRaw();
|
||||
if(messageDigest == null) messageDigest = crypto.getMessageDigest();
|
||||
batchDigest.update(raw);
|
||||
// Hash the message, including the signatures, to get the message ID
|
||||
messageDigest.update(raw);
|
||||
MessageId id = new MessageId(messageDigest.digest());
|
||||
// Verify the author's signature, if there is one
|
||||
|
||||
Reference in New Issue
Block a user