mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 20:59:54 +01:00
Added a random salt to prevent ID clashes between anonymous messages.
This commit is contained in:
@@ -2,6 +2,7 @@ package net.sf.briar.api.crypto;
|
|||||||
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
@@ -36,5 +37,7 @@ public interface CryptoComponent {
|
|||||||
|
|
||||||
MessageDigest getMessageDigest();
|
MessageDigest getMessageDigest();
|
||||||
|
|
||||||
|
SecureRandom getSecureRandom();
|
||||||
|
|
||||||
Signature getSignature();
|
Signature getSignature();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ public interface Message {
|
|||||||
/** The maximum length of a signature in bytes. */
|
/** The maximum length of a signature in bytes. */
|
||||||
static final int MAX_SIGNATURE_LENGTH = 100;
|
static final int MAX_SIGNATURE_LENGTH = 100;
|
||||||
|
|
||||||
|
/** The length of the random salt in bytes. */
|
||||||
|
static final int SALT_LENGTH = 8;
|
||||||
|
|
||||||
/** Returns the message's unique identifier. */
|
/** Returns the message's unique identifier. */
|
||||||
MessageId getId();
|
MessageId getId();
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.security.KeyPairGenerator;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -205,6 +206,11 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SecureRandom getSecureRandom() {
|
||||||
|
// FIXME: Implement a PRNG (pony/rainbow/nyancat generator)
|
||||||
|
return new SecureRandom();
|
||||||
|
}
|
||||||
|
|
||||||
public Signature getSignature() {
|
public Signature getSignature() {
|
||||||
try {
|
try {
|
||||||
return Signature.getInstance(SIGNATURE_ALGO, PROVIDER);
|
return Signature.getInstance(SIGNATURE_ALGO, PROVIDER);
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ DatabaseCleaner.Callback {
|
|||||||
*/
|
*/
|
||||||
protected boolean storeGroupMessage(Txn txn, Message m, ContactId sender)
|
protected boolean storeGroupMessage(Txn txn, Message m, ContactId sender)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
if(m.getGroup() == null) throw new IllegalArgumentException();
|
assert m.getGroup() != null;
|
||||||
boolean stored = db.addGroupMessage(txn, m);
|
boolean stored = db.addGroupMessage(txn, m);
|
||||||
// Mark the message as seen by the sender
|
// Mark the message as seen by the sender
|
||||||
MessageId id = m.getId();
|
MessageId id = m.getId();
|
||||||
@@ -228,7 +228,8 @@ DatabaseCleaner.Callback {
|
|||||||
*/
|
*/
|
||||||
protected boolean storePrivateMessage(Txn txn, Message m, ContactId c,
|
protected boolean storePrivateMessage(Txn txn, Message m, ContactId c,
|
||||||
boolean incoming) throws DbException {
|
boolean incoming) throws DbException {
|
||||||
if(m.getGroup() != null) throw new IllegalArgumentException();
|
assert m.getGroup() == null;
|
||||||
|
assert m.getAuthor() == null;
|
||||||
if(!db.addPrivateMessage(txn, m, c)) return false;
|
if(!db.addPrivateMessage(txn, m, c)) return false;
|
||||||
MessageId id = m.getId();
|
MessageId id = m.getId();
|
||||||
if(incoming) db.setStatus(txn, c, id, Status.SEEN);
|
if(incoming) db.setStatus(txn, c, id, Status.SEEN);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.io.IOException;
|
|||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
|
|
||||||
import net.sf.briar.api.crypto.CryptoComponent;
|
import net.sf.briar.api.crypto.CryptoComponent;
|
||||||
@@ -23,12 +24,14 @@ import com.google.inject.Inject;
|
|||||||
class MessageEncoderImpl implements MessageEncoder {
|
class MessageEncoderImpl implements MessageEncoder {
|
||||||
|
|
||||||
private final Signature signature;
|
private final Signature signature;
|
||||||
|
private final SecureRandom random;
|
||||||
private final MessageDigest messageDigest;
|
private final MessageDigest messageDigest;
|
||||||
private final WriterFactory writerFactory;
|
private final WriterFactory writerFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MessageEncoderImpl(CryptoComponent crypto, WriterFactory writerFactory) {
|
MessageEncoderImpl(CryptoComponent crypto, WriterFactory writerFactory) {
|
||||||
signature = crypto.getSignature();
|
signature = crypto.getSignature();
|
||||||
|
random = crypto.getSecureRandom();
|
||||||
messageDigest = crypto.getMessageDigest();
|
messageDigest = crypto.getMessageDigest();
|
||||||
this.writerFactory = writerFactory;
|
this.writerFactory = writerFactory;
|
||||||
}
|
}
|
||||||
@@ -79,6 +82,9 @@ class MessageEncoderImpl implements MessageEncoder {
|
|||||||
if(author == null) w.writeNull();
|
if(author == null) w.writeNull();
|
||||||
else author.writeTo(w);
|
else author.writeTo(w);
|
||||||
w.writeInt64(timestamp);
|
w.writeInt64(timestamp);
|
||||||
|
byte[] salt = new byte[Message.SALT_LENGTH];
|
||||||
|
random.nextBytes(salt);
|
||||||
|
w.writeBytes(salt);
|
||||||
w.writeBytes(body);
|
w.writeBytes(body);
|
||||||
// Sign the message with the author's private key, if there is one
|
// Sign the message with the author's private key, if there is one
|
||||||
if(authorKey == null) {
|
if(authorKey == null) {
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ class MessageReader implements ObjectReader<Message> {
|
|||||||
// Read the timestamp
|
// Read the timestamp
|
||||||
long timestamp = r.readInt64();
|
long timestamp = r.readInt64();
|
||||||
if(timestamp < 0L) throw new FormatException();
|
if(timestamp < 0L) throw new FormatException();
|
||||||
|
// Read the salt
|
||||||
|
byte[] salt = r.readBytes(Message.SALT_LENGTH);
|
||||||
|
if(salt.length != Message.SALT_LENGTH) throw new FormatException();
|
||||||
// Skip the message body
|
// Skip the message body
|
||||||
r.readBytes(Message.MAX_BODY_LENGTH);
|
r.readBytes(Message.MAX_BODY_LENGTH);
|
||||||
// Record the length of the data covered by the author's signature
|
// Record the length of the data covered by the author's signature
|
||||||
|
|||||||
Reference in New Issue
Block a user