Use PublicKey and PrivateKey everywhere.

This commit is contained in:
akwizgran
2019-04-23 13:31:09 +01:00
parent 0e77a47cc1
commit de8a60ea21
55 changed files with 558 additions and 463 deletions

View File

@@ -1,6 +1,8 @@
package org.briarproject.bramble.api.client; package org.briarproject.bramble.api.client;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -96,14 +98,18 @@ public interface ClientHelper {
BdfList toList(Author a); BdfList toList(Author a);
byte[] sign(String label, BdfList toSign, byte[] privateKey) byte[] sign(String label, BdfList toSign, PrivateKey privateKey)
throws FormatException, GeneralSecurityException; throws FormatException, GeneralSecurityException;
void verifySignature(byte[] signature, String label, BdfList signed, void verifySignature(byte[] signature, String label, BdfList signed,
byte[] publicKey) throws FormatException, GeneralSecurityException; PublicKey publicKey)
throws FormatException, GeneralSecurityException;
Author parseAndValidateAuthor(BdfList author) throws FormatException; Author parseAndValidateAuthor(BdfList author) throws FormatException;
PublicKey parseAndValidateAgreementPublicKey(byte[] publicKeyBytes)
throws FormatException;
TransportProperties parseAndValidateTransportProperties( TransportProperties parseAndValidateTransportProperties(
BdfDictionary properties) throws FormatException; BdfDictionary properties) throws FormatException;

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.api.contact; package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -8,7 +9,6 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8; import static org.briarproject.bramble.util.StringUtils.toUtf8;
@Immutable @Immutable
@@ -21,21 +21,17 @@ public class Contact {
@Nullable @Nullable
private final String alias; private final String alias;
@Nullable @Nullable
private final byte[] handshakePublicKey; private final PublicKey handshakePublicKey;
private final boolean verified; private final boolean verified;
public Contact(ContactId id, Author author, AuthorId localAuthorId, public Contact(ContactId id, Author author, AuthorId localAuthorId,
@Nullable String alias, @Nullable byte[] handshakePublicKey, @Nullable String alias, @Nullable PublicKey handshakePublicKey,
boolean verified) { boolean verified) {
if (alias != null) { if (alias != null) {
int aliasLength = toUtf8(alias).length; int aliasLength = toUtf8(alias).length;
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH) if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
if (handshakePublicKey != null && (handshakePublicKey.length == 0 ||
handshakePublicKey.length > MAX_PUBLIC_KEY_LENGTH)) {
throw new IllegalArgumentException();
}
this.id = id; this.id = id;
this.author = author; this.author = author;
this.localAuthorId = localAuthorId; this.localAuthorId = localAuthorId;
@@ -62,7 +58,7 @@ public class Contact {
} }
@Nullable @Nullable
public byte[] getHandshakePublicKey() { public PublicKey getHandshakePublicKey() {
return handshakePublicKey; return handshakePublicKey;
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.api.contact; package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
@@ -9,12 +10,12 @@ import javax.annotation.concurrent.Immutable;
public class PendingContact { public class PendingContact {
private final PendingContactId id; private final PendingContactId id;
private final byte[] publicKey; private final PublicKey publicKey;
private final String alias; private final String alias;
private final PendingContactState state; private final PendingContactState state;
private final long timestamp; private final long timestamp;
public PendingContact(PendingContactId id, byte[] publicKey, public PendingContact(PendingContactId id, PublicKey publicKey,
String alias, PendingContactState state, long timestamp) { String alias, PendingContactState state, long timestamp) {
this.id = id; this.id = id;
this.publicKey = publicKey; this.publicKey = publicKey;
@@ -27,7 +28,7 @@ public class PendingContact {
return id; return id;
} }
public byte[] getPublicKey() { public PublicKey getPublicKey() {
return publicKey; return publicKey;
} }

View File

@@ -55,7 +55,7 @@ public interface CryptoComponent {
* signature, to prevent it from being repurposed or colliding with a * signature, to prevent it from being repurposed or colliding with a
* signature created for another purpose * signature created for another purpose
*/ */
byte[] sign(String label, byte[] toSign, byte[] privateKey) byte[] sign(String label, byte[] toSign, PrivateKey privateKey)
throws GeneralSecurityException; throws GeneralSecurityException;
/** /**
@@ -68,7 +68,7 @@ public interface CryptoComponent {
* @return true if the signature was valid, false otherwise. * @return true if the signature was valid, false otherwise.
*/ */
boolean verifySignature(byte[] signature, String label, byte[] signed, boolean verifySignature(byte[] signature, String label, byte[] signed,
byte[] publicKey) throws GeneralSecurityException; PublicKey publicKey) throws GeneralSecurityException;
/** /**
* Returns the hash of the given inputs. The inputs are unambiguously * Returns the hash of the given inputs. The inputs are unambiguously

View File

@@ -15,6 +15,8 @@ public class KeyPair {
private final PrivateKey privateKey; private final PrivateKey privateKey;
public KeyPair(PublicKey publicKey, PrivateKey privateKey) { public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
if (!publicKey.getKeyType().equals(privateKey.getKeyType()))
throw new IllegalArgumentException();
this.publicKey = publicKey; this.publicKey = publicKey;
this.privateKey = privateKey; this.privateKey = privateKey;
} }

View File

@@ -4,6 +4,8 @@ import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
@@ -622,8 +624,8 @@ public interface DatabaseComponent {
/** /**
* Sets the handshake key pair for the identity with the given ID. * Sets the handshake key pair for the identity with the given ID.
*/ */
void setHandshakeKeyPair(Transaction txn, AuthorId local, byte[] publicKey, void setHandshakeKeyPair(Transaction txn, AuthorId local,
byte[] privateKey) throws DbException; PublicKey publicKey, PrivateKey privateKey) throws DbException;
/** /**
* Sets the reordering window for the given transport key set in the given * Sets the reordering window for the given transport key set in the given

View File

@@ -1,13 +1,14 @@
package org.briarproject.bramble.api.identity; package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.Nameable; import org.briarproject.bramble.api.Nameable;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.util.StringUtils.toUtf8;
/** /**
* A pseudonym for a user. * A pseudonym for a user.
@@ -24,14 +25,14 @@ public class Author implements Nameable {
private final AuthorId id; private final AuthorId id;
private final int formatVersion; private final int formatVersion;
private final String name; private final String name;
private final byte[] publicKey; private final PublicKey publicKey;
public Author(AuthorId id, int formatVersion, String name, public Author(AuthorId id, int formatVersion, String name,
byte[] publicKey) { PublicKey publicKey) {
int nameLength = StringUtils.toUtf8(name).length; int nameLength = toUtf8(name).length;
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH) if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH) if (!publicKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.id = id; this.id = id;
this.formatVersion = formatVersion; this.formatVersion = formatVersion;
@@ -63,7 +64,7 @@ public class Author implements Nameable {
/** /**
* Returns the public key used to verify the pseudonym's signatures. * Returns the public key used to verify the pseudonym's signatures.
*/ */
public byte[] getPublicKey() { public PublicKey getPublicKey() {
return publicKey; return publicKey;
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.api.identity; package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault @NotNullByDefault
@@ -9,12 +10,12 @@ public interface AuthorFactory {
* Creates an author with the current format version and the given name and * Creates an author with the current format version and the given name and
* public key. * public key.
*/ */
Author createAuthor(String name, byte[] publicKey); Author createAuthor(String name, PublicKey publicKey);
/** /**
* Creates an author with the given format version, name and public key. * Creates an author with the given format version, name and public key.
*/ */
Author createAuthor(int formatVersion, String name, byte[] publicKey); Author createAuthor(int formatVersion, String name, PublicKey publicKey);
/** /**
* Creates a local author with the current format version and the given * Creates a local author with the current format version and the given

View File

@@ -1,13 +1,13 @@
package org.briarproject.bramble.api.identity; package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Arrays;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -15,15 +15,24 @@ public class Identity {
private final LocalAuthor localAuthor; private final LocalAuthor localAuthor;
@Nullable @Nullable
private final byte[] handshakePublicKey, handshakePrivateKey; private final PublicKey handshakePublicKey;
@Nullable
private final PrivateKey handshakePrivateKey;
private final long created; private final long created;
public Identity(LocalAuthor localAuthor, public Identity(LocalAuthor localAuthor,
@Nullable byte[] handshakePublicKey, @Nullable PublicKey handshakePublicKey,
@Nullable byte[] handshakePrivateKey, long created) { @Nullable PrivateKey handshakePrivateKey, long created) {
if (handshakePublicKey != null) { if (handshakePublicKey != null) {
int keyLength = handshakePublicKey.length; if (handshakePrivateKey == null)
if (keyLength == 0 || keyLength > MAX_AGREEMENT_PUBLIC_KEY_BYTES) throw new IllegalArgumentException();
if (!handshakePublicKey.getKeyType().equals(KEY_TYPE_AGREEMENT))
throw new IllegalArgumentException();
}
if (handshakePrivateKey != null) {
if (handshakePublicKey == null)
throw new IllegalArgumentException();
if (!handshakePrivateKey.getKeyType().equals(KEY_TYPE_AGREEMENT))
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
this.localAuthor = localAuthor; this.localAuthor = localAuthor;
@@ -57,7 +66,7 @@ public class Identity {
* Returns the public key used for handshaking, or null if no key exists. * Returns the public key used for handshaking, or null if no key exists.
*/ */
@Nullable @Nullable
public byte[] getHandshakePublicKey() { public PublicKey getHandshakePublicKey() {
return handshakePublicKey; return handshakePublicKey;
} }
@@ -65,7 +74,7 @@ public class Identity {
* Returns the private key used for handshaking, or null if no key exists. * Returns the private key used for handshaking, or null if no key exists.
*/ */
@Nullable @Nullable
public byte[] getHandshakePrivateKey() { public PrivateKey getHandshakePrivateKey() {
return handshakePrivateKey; return handshakePrivateKey;
} }
@@ -76,21 +85,4 @@ public class Identity {
public long getTimeCreated() { public long getTimeCreated() {
return created; return created;
} }
@Override
public int hashCode() {
return localAuthor.getId().hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof Identity) {
Identity i = (Identity) o;
return created == i.created &&
localAuthor.equals(i.localAuthor) &&
Arrays.equals(handshakePublicKey, i.handshakePublicKey) &&
Arrays.equals(handshakePrivateKey, i.handshakePrivateKey);
}
return false;
}
} }

View File

@@ -1,6 +1,7 @@
package org.briarproject.bramble.api.identity; package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.CryptoExecutor; import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
@@ -41,9 +42,6 @@ public interface IdentityManager {
* Returns the cached handshake keys or loads them from the database. * Returns the cached handshake keys or loads them from the database.
* <p/> * <p/>
* Read-only. * Read-only.
*
* @return A two-element array containing the public key in the first
* element and the private key in the second
*/ */
byte[][] getHandshakeKeys(Transaction txn) throws DbException; KeyPair getHandshakeKeys(Transaction txn) throws DbException;
} }

View File

@@ -1,9 +1,13 @@
package org.briarproject.bramble.api.identity; package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
/** /**
* A pseudonym for the local user. * A pseudonym for the local user.
*/ */
@@ -11,18 +15,20 @@ import javax.annotation.concurrent.Immutable;
@NotNullByDefault @NotNullByDefault
public class LocalAuthor extends Author { public class LocalAuthor extends Author {
private final byte[] privateKey; private final PrivateKey privateKey;
public LocalAuthor(AuthorId id, int formatVersion, String name, public LocalAuthor(AuthorId id, int formatVersion, String name,
byte[] publicKey, byte[] privateKey) { PublicKey publicKey, PrivateKey privateKey) {
super(id, formatVersion, name, publicKey); super(id, formatVersion, name, publicKey);
if (!privateKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
throw new IllegalArgumentException();
this.privateKey = privateKey; this.privateKey = privateKey;
} }
/** /**
* Returns the private key used to generate the pseudonym's signatures. * Returns the private key used to generate the pseudonym's signatures.
*/ */
public byte[] getPrivateKey() { public PrivateKey getPrivateKey() {
return privateKey; return privateKey;
} }
} }

View File

@@ -5,7 +5,13 @@ import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.crypto.SignaturePrivateKey;
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.Identity;
@@ -32,9 +38,9 @@ import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION; import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_PUBLIC_KEY_BYTES;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION; import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.api.plugin.TransportId.MAX_TRANSPORT_ID_LENGTH; import static org.briarproject.bramble.api.plugin.TransportId.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH; import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH; import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH;
@@ -101,10 +107,28 @@ public class TestUtils {
return new SecretKey(getRandomBytes(SecretKey.LENGTH)); return new SecretKey(getRandomBytes(SecretKey.LENGTH));
} }
public static PublicKey getSignaturePublicKey() {
byte[] key = getRandomBytes(MAX_SIGNATURE_PUBLIC_KEY_BYTES);
return new SignaturePublicKey(key);
}
public static PrivateKey getSignaturePrivateKey() {
return new SignaturePrivateKey(getRandomBytes(123));
}
public static PublicKey getAgreementPublicKey() {
byte[] key = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
return new AgreementPublicKey(key);
}
public static PrivateKey getAgreementPrivateKey() {
return new AgreementPrivateKey(getRandomBytes(123));
}
public static Identity getIdentity() { public static Identity getIdentity() {
LocalAuthor localAuthor = getLocalAuthor(); LocalAuthor localAuthor = getLocalAuthor();
byte[] handshakePub = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); PublicKey handshakePub = getAgreementPublicKey();
byte[] handshakePriv = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); PrivateKey handshakePriv = getAgreementPrivateKey();
return new Identity(localAuthor, handshakePub, handshakePriv, return new Identity(localAuthor, handshakePub, handshakePriv,
timestamp); timestamp);
} }
@@ -113,8 +137,8 @@ public class TestUtils {
AuthorId id = new AuthorId(getRandomId()); AuthorId id = new AuthorId(getRandomId());
int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH); int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH);
String name = getRandomString(nameLength); String name = getRandomString(nameLength);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); PublicKey publicKey = getSignaturePublicKey();
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); PrivateKey privateKey = getSignaturePrivateKey();
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey); return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey);
} }
@@ -122,7 +146,7 @@ public class TestUtils {
AuthorId id = new AuthorId(getRandomId()); AuthorId id = new AuthorId(getRandomId());
int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH); int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH);
String name = getRandomString(nameLength); String name = getRandomString(nameLength);
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); PublicKey publicKey = getSignaturePublicKey();
return new Author(id, FORMAT_VERSION, name, publicKey); return new Author(id, FORMAT_VERSION, name, publicKey);
} }
@@ -155,7 +179,7 @@ public class TestUtils {
public static PendingContact getPendingContact(int nameLength) { public static PendingContact getPendingContact(int nameLength) {
PendingContactId id = new PendingContactId(getRandomId()); PendingContactId id = new PendingContactId(getRandomId());
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); PublicKey publicKey = getAgreementPublicKey();
String alias = getRandomString(nameLength); String alias = getRandomString(nameLength);
return new PendingContact(id, publicKey, alias, WAITING_FOR_CONNECTION, return new PendingContact(id, publicKey, alias, WAITING_FOR_CONNECTION,
timestamp); timestamp);
@@ -179,7 +203,7 @@ public class TestUtils {
boolean verified) { boolean verified) {
return new Contact(c, remote, local, return new Contact(c, remote, local,
getRandomString(MAX_AUTHOR_NAME_LENGTH), getRandomString(MAX_AUTHOR_NAME_LENGTH),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), verified); getAgreementPublicKey(), verified);
} }
public static double getMedian(Collection<? extends Number> samples) { public static double getMedian(Collection<? extends Number> samples) {

View File

@@ -3,6 +3,9 @@ package org.briarproject.bramble.client;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyParser;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.BdfReader; import org.briarproject.bramble.api.data.BdfReader;
@@ -305,14 +308,15 @@ class ClientHelperImpl implements ClientHelper {
} }
@Override @Override
public byte[] sign(String label, BdfList toSign, byte[] privateKey) public byte[] sign(String label, BdfList toSign, PrivateKey privateKey)
throws FormatException, GeneralSecurityException { throws FormatException, GeneralSecurityException {
return crypto.sign(label, toByteArray(toSign), privateKey); return crypto.sign(label, toByteArray(toSign), privateKey);
} }
@Override @Override
public void verifySignature(byte[] signature, String label, BdfList signed, public void verifySignature(byte[] signature, String label, BdfList signed,
byte[] publicKey) throws FormatException, GeneralSecurityException { PublicKey publicKey)
throws FormatException, GeneralSecurityException {
if (!crypto.verifySignature(signature, label, toByteArray(signed), if (!crypto.verifySignature(signature, label, toByteArray(signed),
publicKey)) { publicKey)) {
throw new GeneralSecurityException("Invalid signature"); throw new GeneralSecurityException("Invalid signature");
@@ -327,11 +331,29 @@ class ClientHelperImpl implements ClientHelper {
if (formatVersion != FORMAT_VERSION) throw new FormatException(); if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = author.getString(1); String name = author.getString(1);
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH); checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
byte[] publicKey = author.getRaw(2); byte[] publicKeyBytes = author.getRaw(2);
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH); checkLength(publicKeyBytes, 1, MAX_PUBLIC_KEY_LENGTH);
KeyParser parser = crypto.getSignatureKeyParser();
PublicKey publicKey;
try {
publicKey = parser.parsePublicKey(publicKeyBytes);
} catch (GeneralSecurityException e) {
throw new FormatException();
}
return authorFactory.createAuthor(formatVersion, name, publicKey); return authorFactory.createAuthor(formatVersion, name, publicKey);
} }
@Override
public PublicKey parseAndValidateAgreementPublicKey(byte[] publicKeyBytes)
throws FormatException {
KeyParser parser = crypto.getAgreementKeyParser();
try {
return parser.parsePublicKey(publicKeyBytes);
} catch (GeneralSecurityException e) {
throw new FormatException();
}
}
@Override @Override
public TransportProperties parseAndValidateTransportProperties( public TransportProperties parseAndValidateTransportProperties(
BdfDictionary properties) throws FormatException { BdfDictionary properties) throws FormatException {

View File

@@ -39,8 +39,8 @@ class PendingContactFactoryImpl implements PendingContactFactory {
PublicKey publicKey = parseHandshakeLink(link); PublicKey publicKey = parseHandshakeLink(link);
PendingContactId id = getPendingContactId(publicKey); PendingContactId id = getPendingContactId(publicKey);
long timestamp = clock.currentTimeMillis(); long timestamp = clock.currentTimeMillis();
return new PendingContact(id, publicKey.getEncoded(), alias, return new PendingContact(id, publicKey, alias, WAITING_FOR_CONNECTION,
WAITING_FOR_CONNECTION, timestamp); timestamp);
} }
private PublicKey parseHandshakeLink(String link) throws FormatException { private PublicKey parseHandshakeLink(String link) throws FormatException {

View File

@@ -36,6 +36,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT; import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES; import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.bramble.util.LogUtils.now;
@@ -200,21 +201,22 @@ class CryptoComponentImpl implements CryptoComponent {
} }
@Override @Override
public byte[] sign(String label, byte[] toSign, byte[] privateKey) public byte[] sign(String label, byte[] toSign, PrivateKey privateKey)
throws GeneralSecurityException { throws GeneralSecurityException {
PrivateKey key = signatureKeyParser.parsePrivateKey(privateKey);
Signature sig = new EdSignature(); Signature sig = new EdSignature();
sig.initSign(key); sig.initSign(privateKey);
updateSignature(sig, label, toSign); updateSignature(sig, label, toSign);
return sig.sign(); return sig.sign();
} }
@Override @Override
public boolean verifySignature(byte[] signature, String label, public boolean verifySignature(byte[] signature, String label,
byte[] signed, byte[] publicKey) throws GeneralSecurityException { byte[] signed, PublicKey publicKey)
PublicKey key = signatureKeyParser.parsePublicKey(publicKey); throws GeneralSecurityException {
if (!publicKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
throw new IllegalArgumentException();
Signature sig = new EdSignature(); Signature sig = new EdSignature();
sig.initVerify(key); sig.initVerify(publicKey);
updateSignature(sig, label, signed); updateSignature(sig, label, signed);
return sig.verify(signature); return sig.verify(signature);
} }

View File

@@ -5,6 +5,8 @@ import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.PendingContactState; import org.briarproject.bramble.api.contact.PendingContactState;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DataTooNewException; import org.briarproject.bramble.api.db.DataTooNewException;
import org.briarproject.bramble.api.db.DataTooOldException; import org.briarproject.bramble.api.db.DataTooOldException;
@@ -689,8 +691,8 @@ interface Database<T> {
/** /**
* Sets the handshake key pair for the identity with the given ID. * Sets the handshake key pair for the identity with the given ID.
*/ */
void setHandshakeKeyPair(T txn, AuthorId local, byte[] publicKey, void setHandshakeKeyPair(T txn, AuthorId local, PublicKey publicKey,
byte[] privateKey) throws DbException; PrivateKey privateKey) throws DbException;
/** /**
* Marks the given message as shared. * Marks the given message as shared.

View File

@@ -7,6 +7,8 @@ import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent; import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
import org.briarproject.bramble.api.contact.event.ContactVerifiedEvent; import org.briarproject.bramble.api.contact.event.ContactVerifiedEvent;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.CommitAction; import org.briarproject.bramble.api.db.CommitAction;
import org.briarproject.bramble.api.db.CommitAction.Visitor; import org.briarproject.bramble.api.db.CommitAction.Visitor;
@@ -1037,7 +1039,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
@Override @Override
public void setHandshakeKeyPair(Transaction transaction, AuthorId local, public void setHandshakeKeyPair(Transaction transaction, AuthorId local,
byte[] publicKey, byte[] privateKey) throws DbException { PublicKey publicKey, PrivateKey privateKey) throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException(); if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsIdentity(txn, local)) if (!db.containsIdentity(txn, local))

View File

@@ -5,7 +5,13 @@ import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.PendingContactState; import org.briarproject.bramble.api.contact.PendingContactState;
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.crypto.SignaturePrivateKey;
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
import org.briarproject.bramble.api.db.DataTooNewException; import org.briarproject.bramble.api.db.DataTooNewException;
import org.briarproject.bramble.api.db.DataTooOldException; import org.briarproject.bramble.api.db.DataTooOldException;
import org.briarproject.bramble.api.db.DbClosedException; import org.briarproject.bramble.api.db.DbClosedException;
@@ -677,7 +683,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.setBytes(1, remote.getId().getBytes()); ps.setBytes(1, remote.getId().getBytes());
ps.setInt(2, remote.getFormatVersion()); ps.setInt(2, remote.getFormatVersion());
ps.setString(3, remote.getName()); ps.setString(3, remote.getName());
ps.setBytes(4, remote.getPublicKey()); ps.setBytes(4, remote.getPublicKey().getEncoded());
ps.setBytes(5, local.getBytes()); ps.setBytes(5, local.getBytes());
ps.setBoolean(6, verified); ps.setBoolean(6, verified);
int affected = ps.executeUpdate(); int affected = ps.executeUpdate();
@@ -887,12 +893,12 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.setBytes(1, local.getId().getBytes()); ps.setBytes(1, local.getId().getBytes());
ps.setInt(2, local.getFormatVersion()); ps.setInt(2, local.getFormatVersion());
ps.setString(3, local.getName()); ps.setString(3, local.getName());
ps.setBytes(4, local.getPublicKey()); ps.setBytes(4, local.getPublicKey().getEncoded());
ps.setBytes(5, local.getPrivateKey()); ps.setBytes(5, local.getPrivateKey().getEncoded());
if (i.getHandshakePublicKey() == null) ps.setNull(6, BINARY); if (i.getHandshakePublicKey() == null) ps.setNull(6, BINARY);
else ps.setBytes(6, i.getHandshakePublicKey()); else ps.setBytes(6, i.getHandshakePublicKey().getEncoded());
if (i.getHandshakePrivateKey() == null) ps.setNull(7, BINARY); if (i.getHandshakePrivateKey() == null) ps.setNull(7, BINARY);
else ps.setBytes(7, i.getHandshakePrivateKey()); else ps.setBytes(7, i.getHandshakePrivateKey().getEncoded());
ps.setLong(8, i.getTimeCreated()); ps.setLong(8, i.getTimeCreated());
int affected = ps.executeUpdate(); int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException(); if (affected != 1) throw new DbStateException();
@@ -1068,7 +1074,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " VALUES (?, ?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, p.getId().getBytes()); ps.setBytes(1, p.getId().getBytes());
ps.setBytes(2, p.getPublicKey()); ps.setBytes(2, p.getPublicKey().getEncoded());
ps.setString(3, p.getAlias()); ps.setString(3, p.getAlias());
ps.setInt(4, p.getState().getValue()); ps.setInt(4, p.getState().getValue());
ps.setLong(5, p.getTimestamp()); ps.setLong(5, p.getTimestamp());
@@ -1444,14 +1450,16 @@ abstract class JdbcDatabase implements Database<Connection> {
int formatVersion = rs.getInt(2); int formatVersion = rs.getInt(2);
String name = rs.getString(3); String name = rs.getString(3);
String alias = rs.getString(4); String alias = rs.getString(4);
byte[] publicKey = rs.getBytes(5); PublicKey publicKey = new SignaturePublicKey(rs.getBytes(5));
byte[] handshakePublicKey = rs.getBytes(6); byte[] handshakePub = rs.getBytes(6);
AuthorId localAuthorId = new AuthorId(rs.getBytes(7)); AuthorId localAuthorId = new AuthorId(rs.getBytes(7));
boolean verified = rs.getBoolean(8); boolean verified = rs.getBoolean(8);
rs.close(); rs.close();
ps.close(); ps.close();
Author author = Author author =
new Author(authorId, formatVersion, name, publicKey); new Author(authorId, formatVersion, name, publicKey);
PublicKey handshakePublicKey = handshakePub == null ?
null : new AgreementPublicKey(handshakePub);
return new Contact(c, author, localAuthorId, alias, return new Contact(c, author, localAuthorId, alias,
handshakePublicKey, verified); handshakePublicKey, verified);
} catch (SQLException e) { } catch (SQLException e) {
@@ -1479,12 +1487,14 @@ abstract class JdbcDatabase implements Database<Connection> {
int formatVersion = rs.getInt(3); int formatVersion = rs.getInt(3);
String name = rs.getString(4); String name = rs.getString(4);
String alias = rs.getString(5); String alias = rs.getString(5);
byte[] publicKey = rs.getBytes(6); PublicKey publicKey = new SignaturePublicKey(rs.getBytes(6));
byte[] handshakePublicKey = rs.getBytes(7); byte[] handshakePub = rs.getBytes(7);
AuthorId localAuthorId = new AuthorId(rs.getBytes(8)); AuthorId localAuthorId = new AuthorId(rs.getBytes(8));
boolean verified = rs.getBoolean(9); boolean verified = rs.getBoolean(9);
Author author = Author author =
new Author(authorId, formatVersion, name, publicKey); new Author(authorId, formatVersion, name, publicKey);
PublicKey handshakePublicKey = handshakePub == null ?
null : new AgreementPublicKey(handshakePub);
contacts.add(new Contact(contactId, author, localAuthorId, contacts.add(new Contact(contactId, author, localAuthorId,
alias, handshakePublicKey, verified)); alias, handshakePublicKey, verified));
} }
@@ -1540,12 +1550,14 @@ abstract class JdbcDatabase implements Database<Connection> {
int formatVersion = rs.getInt(2); int formatVersion = rs.getInt(2);
String name = rs.getString(3); String name = rs.getString(3);
String alias = rs.getString(4); String alias = rs.getString(4);
byte[] publicKey = rs.getBytes(5); PublicKey publicKey = new SignaturePublicKey(rs.getBytes(5));
byte[] handshakePublicKey = rs.getBytes(6); byte[] handshakePub = rs.getBytes(6);
AuthorId localAuthorId = new AuthorId(rs.getBytes(7)); AuthorId localAuthorId = new AuthorId(rs.getBytes(7));
boolean verified = rs.getBoolean(8); boolean verified = rs.getBoolean(8);
Author author = Author author =
new Author(remote, formatVersion, name, publicKey); new Author(remote, formatVersion, name, publicKey);
PublicKey handshakePublicKey = handshakePub == null ?
null : new AgreementPublicKey(handshakePub);
contacts.add(new Contact(contactId, author, localAuthorId, contacts.add(new Contact(contactId, author, localAuthorId,
alias, handshakePublicKey, verified)); alias, handshakePublicKey, verified));
} }
@@ -1756,16 +1768,20 @@ abstract class JdbcDatabase implements Database<Connection> {
if (!rs.next()) throw new DbStateException(); if (!rs.next()) throw new DbStateException();
int formatVersion = rs.getInt(1); int formatVersion = rs.getInt(1);
String name = rs.getString(2); String name = rs.getString(2);
byte[] publicKey = rs.getBytes(3); PublicKey publicKey = new SignaturePublicKey(rs.getBytes(3));
byte[] privateKey = rs.getBytes(4); PrivateKey privateKey = new SignaturePrivateKey(rs.getBytes(4));
byte[] handshakePublicKey = rs.getBytes(5); byte[] handshakePub = rs.getBytes(5);
byte[] handshakePrivateKey = rs.getBytes(6); byte[] handshakePriv = rs.getBytes(6);
long created = rs.getLong(7); long created = rs.getLong(7);
if (rs.next()) throw new DbStateException(); if (rs.next()) throw new DbStateException();
rs.close(); rs.close();
ps.close(); ps.close();
LocalAuthor local = new LocalAuthor(a, formatVersion, name, LocalAuthor local = new LocalAuthor(a, formatVersion, name,
publicKey, privateKey); publicKey, privateKey);
PublicKey handshakePublicKey = handshakePub == null ?
null : new AgreementPublicKey(handshakePub);
PrivateKey handshakePrivateKey = handshakePriv == null ?
null : new AgreementPrivateKey(handshakePriv);
return new Identity(local, handshakePublicKey, handshakePrivateKey, return new Identity(local, handshakePublicKey, handshakePrivateKey,
created); created);
} catch (SQLException e) { } catch (SQLException e) {
@@ -1792,13 +1808,17 @@ abstract class JdbcDatabase implements Database<Connection> {
AuthorId authorId = new AuthorId(rs.getBytes(1)); AuthorId authorId = new AuthorId(rs.getBytes(1));
int formatVersion = rs.getInt(2); int formatVersion = rs.getInt(2);
String name = rs.getString(3); String name = rs.getString(3);
byte[] publicKey = rs.getBytes(4); PublicKey publicKey = new SignaturePublicKey(rs.getBytes(4));
byte[] privateKey = rs.getBytes(5); PrivateKey privateKey = new SignaturePrivateKey(rs.getBytes(5));
byte[] handshakePublicKey = rs.getBytes(6); byte[] handshakePub = rs.getBytes(6);
byte[] handshakePrivateKey = rs.getBytes(7); byte[] handshakePriv = rs.getBytes(7);
long created = rs.getLong(8); long created = rs.getLong(8);
LocalAuthor local = new LocalAuthor(authorId, formatVersion, LocalAuthor local = new LocalAuthor(authorId, formatVersion,
name, publicKey, privateKey); name, publicKey, privateKey);
PublicKey handshakePublicKey = handshakePub == null ?
null : new AgreementPublicKey(handshakePub);
PrivateKey handshakePrivateKey = handshakePriv == null ?
null : new AgreementPrivateKey(handshakePriv);
identities.add(new Identity(local, handshakePublicKey, identities.add(new Identity(local, handshakePublicKey,
handshakePrivateKey, created)); handshakePrivateKey, created));
} }
@@ -2395,7 +2415,7 @@ abstract class JdbcDatabase implements Database<Connection> {
List<PendingContact> pendingContacts = new ArrayList<>(); List<PendingContact> pendingContacts = new ArrayList<>();
while (rs.next()) { while (rs.next()) {
PendingContactId id = new PendingContactId(rs.getBytes(1)); PendingContactId id = new PendingContactId(rs.getBytes(1));
byte[] publicKey = rs.getBytes(2); PublicKey publicKey = new AgreementPublicKey(rs.getBytes(2));
String alias = rs.getString(3); String alias = rs.getString(3);
PendingContactState state = PendingContactState state =
PendingContactState.fromValue(rs.getInt(4)); PendingContactState.fromValue(rs.getInt(4));
@@ -3182,15 +3202,15 @@ abstract class JdbcDatabase implements Database<Connection> {
@Override @Override
public void setHandshakeKeyPair(Connection txn, AuthorId local, public void setHandshakeKeyPair(Connection txn, AuthorId local,
byte[] publicKey, byte[] privateKey) throws DbException { PublicKey publicKey, PrivateKey privateKey) throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
String sql = "UPDATE localAuthors" String sql = "UPDATE localAuthors"
+ " SET handshakePublicKey = ?, handshakePrivateKey = ?" + " SET handshakePublicKey = ?, handshakePrivateKey = ?"
+ " WHERE authorId = ?"; + " WHERE authorId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, publicKey); ps.setBytes(1, publicKey.getEncoded());
ps.setBytes(2, privateKey); ps.setBytes(2, privateKey.getEncoded());
ps.setBytes(3, local.getBytes()); ps.setBytes(3, local.getBytes());
int affected = ps.executeUpdate(); int affected = ps.executeUpdate();
if (affected < 0 || affected > 1) throw new DbStateException(); if (affected < 0 || affected > 1) throw new DbStateException();

View File

@@ -2,13 +2,13 @@ package org.briarproject.bramble.identity;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
@@ -16,6 +16,8 @@ import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION; import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorId.LABEL; import static org.briarproject.bramble.api.identity.AuthorId.LABEL;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES; import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -29,13 +31,13 @@ class AuthorFactoryImpl implements AuthorFactory {
} }
@Override @Override
public Author createAuthor(String name, byte[] publicKey) { public Author createAuthor(String name, PublicKey publicKey) {
return createAuthor(FORMAT_VERSION, name, publicKey); return createAuthor(FORMAT_VERSION, name, publicKey);
} }
@Override @Override
public Author createAuthor(int formatVersion, String name, public Author createAuthor(int formatVersion, String name,
byte[] publicKey) { PublicKey publicKey) {
AuthorId id = getId(formatVersion, name, publicKey); AuthorId id = getId(formatVersion, name, publicKey);
return new Author(id, formatVersion, name, publicKey); return new Author(id, formatVersion, name, publicKey);
} }
@@ -43,16 +45,17 @@ class AuthorFactoryImpl implements AuthorFactory {
@Override @Override
public LocalAuthor createLocalAuthor(String name) { public LocalAuthor createLocalAuthor(String name) {
KeyPair signatureKeyPair = crypto.generateSignatureKeyPair(); KeyPair signatureKeyPair = crypto.generateSignatureKeyPair();
byte[] publicKey = signatureKeyPair.getPublic().getEncoded(); PublicKey publicKey = signatureKeyPair.getPublic();
byte[] privateKey = signatureKeyPair.getPrivate().getEncoded(); PrivateKey privateKey = signatureKeyPair.getPrivate();
AuthorId id = getId(FORMAT_VERSION, name, publicKey); AuthorId id = getId(FORMAT_VERSION, name, publicKey);
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey); return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey);
} }
private AuthorId getId(int formatVersion, String name, byte[] publicKey) { private AuthorId getId(int formatVersion, String name,
PublicKey publicKey) {
byte[] formatVersionBytes = new byte[INT_32_BYTES]; byte[] formatVersionBytes = new byte[INT_32_BYTES];
ByteUtils.writeUint32(formatVersion, formatVersionBytes, 0); writeUint32(formatVersion, formatVersionBytes, 0);
return new AuthorId(crypto.hash(LABEL, formatVersionBytes, return new AuthorId(crypto.hash(LABEL, formatVersionBytes,
StringUtils.toUtf8(name), publicKey)); toUtf8(name), publicKey.getEncoded()));
} }
} }

View File

@@ -2,6 +2,8 @@ package org.briarproject.bramble.identity;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
@@ -73,8 +75,8 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
long start = now(); long start = now();
LocalAuthor localAuthor = authorFactory.createLocalAuthor(name); LocalAuthor localAuthor = authorFactory.createLocalAuthor(name);
KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair();
byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded(); PublicKey handshakePub = handshakeKeyPair.getPublic();
byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded(); PrivateKey handshakePriv = handshakeKeyPair.getPrivate();
logDuration(LOG, "Creating identity", start); logDuration(LOG, "Creating identity", start);
return new Identity(localAuthor, handshakePub, handshakePriv, return new Identity(localAuthor, handshakePub, handshakePriv,
clock.currentTimeMillis()); clock.currentTimeMillis());
@@ -98,9 +100,9 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
} else if (shouldStoreKeys) { } else if (shouldStoreKeys) {
// Handshake keys were generated when loading the identity - // Handshake keys were generated when loading the identity -
// store them // store them
byte[] handshakePub = PublicKey handshakePub =
requireNonNull(cached.getHandshakePublicKey()); requireNonNull(cached.getHandshakePublicKey());
byte[] handshakePriv = PrivateKey handshakePriv =
requireNonNull(cached.getHandshakePrivateKey()); requireNonNull(cached.getHandshakePrivateKey());
db.setHandshakeKeyPair(txn, cached.getId(), handshakePub, db.setHandshakeKeyPair(txn, cached.getId(), handshakePub,
handshakePriv); handshakePriv);
@@ -122,12 +124,12 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
} }
@Override @Override
public byte[][] getHandshakeKeys(Transaction txn) throws DbException { public KeyPair getHandshakeKeys(Transaction txn) throws DbException {
Identity cached = getCachedIdentity(txn); Identity cached = getCachedIdentity(txn);
return new byte[][] { PublicKey handshakePub = requireNonNull(cached.getHandshakePublicKey());
cached.getHandshakePublicKey(), PrivateKey handshakePriv =
cached.getHandshakePrivateKey() requireNonNull(cached.getHandshakePrivateKey());
}; return new KeyPair(handshakePub, handshakePriv);
} }
/** /**
@@ -159,8 +161,8 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
LOG.info("Identity loaded"); LOG.info("Identity loaded");
if (i.hasHandshakeKeyPair()) return i; if (i.hasHandshakeKeyPair()) return i;
KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair();
byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded(); PublicKey handshakePub = handshakeKeyPair.getPublic();
byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded(); PrivateKey handshakePriv = handshakeKeyPair.getPrivate();
LOG.info("Handshake key pair generated"); LOG.info("Handshake key pair generated");
shouldStoreKeys = true; shouldStoreKeys = true;
return new Identity(i.getLocalAuthor(), handshakePub, handshakePriv, return new Identity(i.getLocalAuthor(), handshakePub, handshakePriv,

View File

@@ -3,6 +3,9 @@ package org.briarproject.bramble.client;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyParser;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
@@ -43,6 +46,8 @@ import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSignaturePrivateKey;
import static org.briarproject.bramble.test.TestUtils.getSignaturePublicKey;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -66,6 +71,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
context.mock(CryptoComponent.class); context.mock(CryptoComponent.class);
private final AuthorFactory authorFactory = private final AuthorFactory authorFactory =
context.mock(AuthorFactory.class); context.mock(AuthorFactory.class);
private final KeyParser keyParser = context.mock(KeyParser.class);
private final GroupId groupId = new GroupId(getRandomId()); private final GroupId groupId = new GroupId(getRandomId());
private final BdfDictionary dictionary = new BdfDictionary(); private final BdfDictionary dictionary = new BdfDictionary();
@@ -262,24 +268,25 @@ public class ClientHelperImplTest extends BrambleTestCase {
@Test @Test
public void testSign() throws Exception { public void testSign() throws Exception {
byte[] privateKey = getRandomBytes(42); PrivateKey privateKey = getSignaturePrivateKey();
byte[] signed = getRandomBytes(42); byte[] signature = getRandomBytes(42);
byte[] bytes = expectToByteArray(list); byte[] bytes = expectToByteArray(list);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(cryptoComponent).sign(label, bytes, privateKey); oneOf(cryptoComponent).sign(label, bytes, privateKey);
will(returnValue(signed)); will(returnValue(signature));
}}); }});
assertArrayEquals(signed, clientHelper.sign(label, list, privateKey)); assertArrayEquals(signature,
clientHelper.sign(label, list, privateKey));
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@Test @Test
public void testVerifySignature() throws Exception { public void testVerifySignature() throws Exception {
byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH); byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
byte[] publicKey = getRandomBytes(42);
byte[] signed = expectToByteArray(list); byte[] signed = expectToByteArray(list);
PublicKey publicKey = getSignaturePublicKey();
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(cryptoComponent).verifySignature(signature, label, signed, oneOf(cryptoComponent).verifySignature(signature, label, signed,
@@ -294,8 +301,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
@Test @Test
public void testVerifyWrongSignature() throws Exception { public void testVerifyWrongSignature() throws Exception {
byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH); byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
byte[] publicKey = getRandomBytes(42);
byte[] signed = expectToByteArray(list); byte[] signed = expectToByteArray(list);
PublicKey publicKey = getSignaturePublicKey();
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(cryptoComponent).verifySignature(signature, label, signed, oneOf(cryptoComponent).verifySignature(signature, label, signed,
@@ -315,6 +322,10 @@ public class ClientHelperImplTest extends BrambleTestCase {
@Test @Test
public void testParsesAndEncodesAuthor() throws Exception { public void testParsesAndEncodesAuthor() throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(cryptoComponent).getSignatureKeyParser();
will(returnValue(keyParser));
oneOf(keyParser).parsePublicKey(author.getPublicKey().getEncoded());
will(returnValue(author.getPublicKey()));
oneOf(authorFactory).createAuthor(author.getFormatVersion(), oneOf(authorFactory).createAuthor(author.getFormatVersion(),
author.getName(), author.getPublicKey()); author.getName(), author.getPublicKey());
will(returnValue(author)); will(returnValue(author));
@@ -329,10 +340,14 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList authorList = BdfList.of( BdfList authorList = BdfList.of(
author.getFormatVersion(), author.getFormatVersion(),
author.getName(), author.getName(),
author.getPublicKey() author.getPublicKey().getEncoded()
); );
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(cryptoComponent).getSignatureKeyParser();
will(returnValue(keyParser));
oneOf(keyParser).parsePublicKey(author.getPublicKey().getEncoded());
will(returnValue(author.getPublicKey()));
oneOf(authorFactory).createAuthor(author.getFormatVersion(), oneOf(authorFactory).createAuthor(author.getFormatVersion(),
author.getName(), author.getPublicKey()); author.getName(), author.getPublicKey());
will(returnValue(author)); will(returnValue(author));
@@ -355,7 +370,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList invalidAuthor = BdfList.of( BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(), author.getFormatVersion(),
author.getName(), author.getName(),
author.getPublicKey(), author.getPublicKey().getEncoded(),
"foo" "foo"
); );
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
@@ -366,7 +381,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList invalidAuthor = BdfList.of( BdfList invalidAuthor = BdfList.of(
null, null,
author.getName(), author.getName(),
author.getPublicKey() author.getPublicKey().getEncoded()
); );
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
} }
@@ -377,7 +392,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList invalidAuthor = BdfList.of( BdfList invalidAuthor = BdfList.of(
"foo", "foo",
author.getName(), author.getName(),
author.getPublicKey() author.getPublicKey().getEncoded()
); );
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
} }
@@ -387,7 +402,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList invalidAuthor = BdfList.of( BdfList invalidAuthor = BdfList.of(
author.getFormatVersion() + 1, author.getFormatVersion() + 1,
author.getName(), author.getName(),
author.getPublicKey() author.getPublicKey().getEncoded()
); );
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
} }
@@ -397,7 +412,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList invalidAuthor = BdfList.of( BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(), author.getFormatVersion(),
"", "",
author.getPublicKey() author.getPublicKey().getEncoded()
); );
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
} }
@@ -407,7 +422,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList invalidAuthor = BdfList.of( BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(), author.getFormatVersion(),
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), getRandomString(MAX_AUTHOR_NAME_LENGTH + 1),
author.getPublicKey() author.getPublicKey().getEncoded()
); );
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
} }
@@ -417,7 +432,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
BdfList invalidAuthor = BdfList.of( BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(), author.getFormatVersion(),
null, null,
author.getPublicKey() author.getPublicKey().getEncoded()
); );
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
} }
@@ -472,6 +487,24 @@ public class ClientHelperImplTest extends BrambleTestCase {
clientHelper.parseAndValidateAuthor(invalidAuthor); clientHelper.parseAndValidateAuthor(invalidAuthor);
} }
@Test(expected = FormatException.class)
public void testRejectsAuthorWithInvalidPublicKey() throws Exception {
BdfList invalidAuthor = BdfList.of(
author.getFormatVersion(),
author.getName(),
author.getPublicKey().getEncoded()
);
context.checking(new Expectations() {{
oneOf(cryptoComponent).getSignatureKeyParser();
will(returnValue(keyParser));
oneOf(keyParser).parsePublicKey(author.getPublicKey().getEncoded());
will(throwException(new GeneralSecurityException()));
}});
clientHelper.parseAndValidateAuthor(invalidAuthor);
}
private byte[] expectToByteArray(BdfList list) throws Exception { private byte[] expectToByteArray(BdfList list) throws Exception {
BdfWriter bdfWriter = context.mock(BdfWriter.class); BdfWriter bdfWriter = context.mock(BdfWriter.class);

View File

@@ -21,7 +21,7 @@ import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LAB
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES; import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION; import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
@@ -34,12 +34,11 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
private final CryptoComponent crypto = context.mock(CryptoComponent.class); private final CryptoComponent crypto = context.mock(CryptoComponent.class);
private final Clock clock = context.mock(Clock.class); private final Clock clock = context.mock(Clock.class);
private final KeyParser keyParser = context.mock(KeyParser.class); private final KeyParser keyParser = context.mock(KeyParser.class);
private final PublicKey publicKey = context.mock(PublicKey.class);
private final PendingContactFactory pendingContactFactory = private final PendingContactFactory pendingContactFactory =
new PendingContactFactoryImpl(crypto, clock); new PendingContactFactoryImpl(crypto, clock);
private final String alias = getRandomString(MAX_AUTHOR_NAME_LENGTH); private final String alias = getRandomString(MAX_AUTHOR_NAME_LENGTH);
private final byte[] publicKeyBytes = getRandomBytes(RAW_LINK_BYTES - 1); private final PublicKey publicKey = getAgreementPublicKey();
private final byte[] idBytes = getRandomId(); private final byte[] idBytes = getRandomId();
private final long timestamp = System.currentTimeMillis(); private final long timestamp = System.currentTimeMillis();
@@ -64,7 +63,7 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(crypto).getAgreementKeyParser(); oneOf(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
oneOf(keyParser).parsePublicKey(with(equal(publicKeyBytes))); oneOf(keyParser).parsePublicKey(publicKey.getEncoded());
will(throwException(new GeneralSecurityException())); will(throwException(new GeneralSecurityException()));
}}); }});
@@ -95,11 +94,9 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(crypto).getAgreementKeyParser(); oneOf(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
oneOf(keyParser).parsePublicKey(with(equal(publicKeyBytes))); oneOf(keyParser).parsePublicKey(publicKey.getEncoded());
will(returnValue(publicKey)); will(returnValue(publicKey));
allowing(publicKey).getEncoded(); oneOf(crypto).hash(ID_LABEL, publicKey.getEncoded());
will(returnValue(publicKeyBytes));
oneOf(crypto).hash(ID_LABEL, publicKeyBytes);
will(returnValue(idBytes)); will(returnValue(idBytes));
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(timestamp)); will(returnValue(timestamp));
@@ -108,7 +105,8 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
PendingContact p = PendingContact p =
pendingContactFactory.createPendingContact(link, alias); pendingContactFactory.createPendingContact(link, alias);
assertArrayEquals(idBytes, p.getId().getBytes()); assertArrayEquals(idBytes, p.getId().getBytes());
assertArrayEquals(publicKeyBytes, p.getPublicKey()); assertArrayEquals(publicKey.getEncoded(),
p.getPublicKey().getEncoded());
assertEquals(alias, p.getAlias()); assertEquals(alias, p.getAlias());
assertEquals(WAITING_FOR_CONNECTION, p.getState()); assertEquals(WAITING_FOR_CONNECTION, p.getState());
assertEquals(timestamp, p.getTimestamp()); assertEquals(timestamp, p.getTimestamp());
@@ -121,6 +119,7 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
private String encodeLink(int formatVersion) { private String encodeLink(int formatVersion) {
byte[] rawLink = new byte[RAW_LINK_BYTES]; byte[] rawLink = new byte[RAW_LINK_BYTES];
rawLink[0] = (byte) formatVersion; rawLink[0] = (byte) formatVersion;
byte[] publicKeyBytes = publicKey.getEncoded();
arraycopy(publicKeyBytes, 0, rawLink, 1, publicKeyBytes.length); arraycopy(publicKeyBytes, 0, rawLink, 1, publicKeyBytes.length);
String base32 = Base32.encode(rawLink).toLowerCase(); String base32 = Base32.encode(rawLink).toLowerCase();
assertEquals(BASE32_LINK_BYTES, base32.length()); assertEquals(BASE32_LINK_BYTES, base32.length());

View File

@@ -1,6 +1,8 @@
package org.briarproject.bramble.crypto; package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SignaturePrivateKey; import org.briarproject.bramble.api.crypto.SignaturePrivateKey;
import org.briarproject.bramble.api.crypto.SignaturePublicKey; import org.briarproject.bramble.api.crypto.SignaturePublicKey;
import org.junit.Test; import org.junit.Test;
@@ -139,14 +141,14 @@ public class EdSignatureTest extends SignatureTest {
} }
@Override @Override
protected byte[] sign(String label, byte[] toSign, byte[] privateKey) protected byte[] sign(String label, byte[] toSign, PrivateKey privateKey)
throws GeneralSecurityException { throws GeneralSecurityException {
return crypto.sign(label, toSign, privateKey); return crypto.sign(label, toSign, privateKey);
} }
@Override @Override
protected boolean verify(byte[] signature, String label, byte[] signed, protected boolean verify(byte[] signature, String label, byte[] signed,
byte[] publicKey) throws GeneralSecurityException { PublicKey publicKey) throws GeneralSecurityException {
return crypto.verifySignature(signature, label, signed, publicKey); return crypto.verifySignature(signature, label, signed, publicKey);
} }

View File

@@ -65,7 +65,7 @@ public class KeyAgreementTest extends BrambleTestCase {
} }
@Test @Test
public void testRfc7748TestVector() throws Exception { public void testRfc7748TestVector() {
// Private keys need to be clamped because curve25519-java does the // Private keys need to be clamped because curve25519-java does the
// clamping at key generation time, not multiplication time // clamping at key generation time, not multiplication time
byte[] aPriv = Curve25519KeyParser.clamp(fromHexString(ALICE_PRIVATE)); byte[] aPriv = Curve25519KeyParser.clamp(fromHexString(ALICE_PRIVATE));

View File

@@ -23,7 +23,7 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
new CryptoComponentImpl(new TestSecureRandomProvider(), null); new CryptoComponentImpl(new TestSecureRandomProvider(), null);
@Test @Test
public void testAgreementPublicKeyLength() throws Exception { public void testAgreementPublicKeyLength() {
// Generate 10 agreement key pairs // Generate 10 agreement key pairs
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
KeyPair keyPair = crypto.generateAgreementKeyPair(); KeyPair keyPair = crypto.generateAgreementKeyPair();
@@ -70,7 +70,7 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
} }
@Test @Test
public void testAgreementKeyParserByFuzzing() throws Exception { public void testAgreementKeyParserByFuzzing() {
KeyParser parser = crypto.getAgreementKeyParser(); KeyParser parser = crypto.getAgreementKeyParser();
// Generate a key pair to get the proper public key length // Generate a key pair to get the proper public key length
KeyPair p = crypto.generateAgreementKeyPair(); KeyPair p = crypto.generateAgreementKeyPair();
@@ -92,7 +92,7 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
} }
@Test @Test
public void testSignaturePublicKeyLength() throws Exception { public void testSignaturePublicKeyLength() {
// Generate 10 signature key pairs // Generate 10 signature key pairs
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
KeyPair keyPair = crypto.generateSignatureKeyPair(); KeyPair keyPair = crypto.generateSignatureKeyPair();
@@ -107,10 +107,10 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
// Generate 10 signature key pairs // Generate 10 signature key pairs
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
KeyPair keyPair = crypto.generateSignatureKeyPair(); KeyPair keyPair = crypto.generateSignatureKeyPair();
byte[] key = keyPair.getPrivate().getEncoded(); PrivateKey privateKey = keyPair.getPrivate();
// Sign some random data and check the length of the signature // Sign some random data and check the length of the signature
byte[] toBeSigned = getRandomBytes(1234); byte[] toBeSigned = getRandomBytes(1234);
byte[] signature = crypto.sign("label", toBeSigned, key); byte[] signature = crypto.sign("label", toBeSigned, privateKey);
assertTrue(signature.length <= MAX_SIGNATURE_BYTES); assertTrue(signature.length <= MAX_SIGNATURE_BYTES);
} }
} }
@@ -123,16 +123,15 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
PublicKey publicKey = keyPair.getPublic(); PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate(); PrivateKey privateKey = keyPair.getPrivate();
byte[] message = getRandomBytes(123); byte[] message = getRandomBytes(123);
byte[] signature = crypto.sign("test", message, byte[] signature = crypto.sign("test", message, privateKey);
privateKey.getEncoded());
// Verify the signature // Verify the signature
assertTrue(crypto.verifySignature(signature, "test", message, assertTrue(crypto.verifySignature(signature, "test", message,
publicKey.getEncoded())); publicKey));
// Encode and parse the public key - no exceptions should be thrown // Encode and parse the public key - no exceptions should be thrown
publicKey = parser.parsePublicKey(publicKey.getEncoded()); publicKey = parser.parsePublicKey(publicKey.getEncoded());
// Verify the signature again // Verify the signature again
assertTrue(crypto.verifySignature(signature, "test", message, assertTrue(crypto.verifySignature(signature, "test", message,
publicKey.getEncoded())); publicKey));
} }
@Test @Test
@@ -143,23 +142,21 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
PublicKey publicKey = keyPair.getPublic(); PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate(); PrivateKey privateKey = keyPair.getPrivate();
byte[] message = getRandomBytes(123); byte[] message = getRandomBytes(123);
byte[] signature = crypto.sign("test", message, byte[] signature = crypto.sign("test", message, privateKey);
privateKey.getEncoded());
// Verify the signature // Verify the signature
assertTrue(crypto.verifySignature(signature, "test", message, assertTrue(crypto.verifySignature(signature, "test", message,
publicKey.getEncoded())); publicKey));
// Encode and parse the private key - no exceptions should be thrown // Encode and parse the private key - no exceptions should be thrown
privateKey = parser.parsePrivateKey(privateKey.getEncoded()); privateKey = parser.parsePrivateKey(privateKey.getEncoded());
// Sign the data again - the signatures should be the same // Sign the data again - the signatures should be the same
byte[] signature1 = crypto.sign("test", message, byte[] signature1 = crypto.sign("test", message, privateKey);
privateKey.getEncoded());
assertTrue(crypto.verifySignature(signature1, "test", message, assertTrue(crypto.verifySignature(signature1, "test", message,
publicKey.getEncoded())); publicKey));
assertArrayEquals(signature, signature1); assertArrayEquals(signature, signature1);
} }
@Test @Test
public void testSignatureKeyParserByFuzzing() throws Exception { public void testSignatureKeyParserByFuzzing() {
KeyParser parser = crypto.getSignatureKeyParser(); KeyParser parser = crypto.getSignatureKeyParser();
// Generate a key pair to get the proper public key length // Generate a key pair to get the proper public key length
KeyPair p = crypto.generateSignatureKeyPair(); KeyPair p = crypto.generateSignatureKeyPair();

View File

@@ -2,6 +2,8 @@ package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.test.TestSecureRandomProvider; import org.briarproject.bramble.test.TestSecureRandomProvider;
import org.briarproject.bramble.test.TestUtils; import org.briarproject.bramble.test.TestUtils;
@@ -19,23 +21,24 @@ public abstract class SignatureTest extends BrambleTestCase {
protected final CryptoComponent crypto; protected final CryptoComponent crypto;
private final byte[] publicKey, privateKey; private final PublicKey publicKey;
private final PrivateKey privateKey;
private final String label = StringUtils.getRandomString(42); private final String label = StringUtils.getRandomString(42);
private final byte[] inputBytes = TestUtils.getRandomBytes(123); private final byte[] inputBytes = TestUtils.getRandomBytes(123);
protected abstract KeyPair generateKeyPair(); protected abstract KeyPair generateKeyPair();
protected abstract byte[] sign(String label, byte[] toSign, protected abstract byte[] sign(String label, byte[] toSign,
byte[] privateKey) throws GeneralSecurityException; PrivateKey privateKey) throws GeneralSecurityException;
protected abstract boolean verify(byte[] signature, String label, protected abstract boolean verify(byte[] signature, String label,
byte[] signed, byte[] publicKey) throws GeneralSecurityException; byte[] signed, PublicKey publicKey) throws GeneralSecurityException;
SignatureTest() { SignatureTest() {
crypto = new CryptoComponentImpl(new TestSecureRandomProvider(), null); crypto = new CryptoComponentImpl(new TestSecureRandomProvider(), null);
KeyPair k = generateKeyPair(); KeyPair k = generateKeyPair();
publicKey = k.getPublic().getEncoded(); publicKey = k.getPublic();
privateKey = k.getPrivate().getEncoded(); privateKey = k.getPrivate();
} }
@Test @Test
@@ -51,7 +54,7 @@ public abstract class SignatureTest extends BrambleTestCase {
public void testDifferentKeysProduceDifferentSignatures() throws Exception { public void testDifferentKeysProduceDifferentSignatures() throws Exception {
// Generate second private key // Generate second private key
KeyPair k2 = generateKeyPair(); KeyPair k2 = generateKeyPair();
byte[] privateKey2 = k2.getPrivate().getEncoded(); PrivateKey privateKey2 = k2.getPrivate();
// Calculate the signature with each key // Calculate the signature with each key
byte[] sig1 = sign(label, inputBytes, privateKey); byte[] sig1 = sign(label, inputBytes, privateKey);
byte[] sig2 = sign(label, inputBytes, privateKey2); byte[] sig2 = sign(label, inputBytes, privateKey2);
@@ -92,7 +95,7 @@ public abstract class SignatureTest extends BrambleTestCase {
public void testDifferentKeyFailsVerification() throws Exception { public void testDifferentKeyFailsVerification() throws Exception {
// Generate second private key // Generate second private key
KeyPair k2 = generateKeyPair(); KeyPair k2 = generateKeyPair();
byte[] privateKey2 = k2.getPrivate().getEncoded(); PrivateKey privateKey2 = k2.getPrivate();
// calculate the signature with different key, should fail to verify // calculate the signature with different key, should fail to verify
byte[] sig = sign(label, inputBytes, privateKey2); byte[] sig = sign(label, inputBytes, privateKey2);
assertFalse(verify(sig, label, inputBytes, publicKey)); assertFalse(verify(sig, label, inputBytes, publicKey));

View File

@@ -5,6 +5,8 @@ import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent; import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.ContactExistsException; import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
@@ -66,7 +68,6 @@ import java.util.concurrent.atomic.AtomicReference;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@@ -75,13 +76,14 @@ import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERE
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN; import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN;
import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE; import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES; import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
import static org.briarproject.bramble.test.TestUtils.getAgreementPrivateKey;
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getClientId;
import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getContact;
import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.briarproject.bramble.test.TestUtils.getIdentity;
import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTransportId; import static org.briarproject.bramble.test.TestUtils.getTransportId;
@@ -476,8 +478,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
} }
try { try {
byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); PublicKey publicKey = getAgreementPublicKey();
byte[] privateKey = getRandomBytes(123); PrivateKey privateKey = getAgreementPrivateKey();
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.setHandshakeKeyPair(transaction, localAuthor.getId(), db.setHandshakeKeyPair(transaction, localAuthor.getId(),
publicKey, privateKey)); publicKey, privateKey));

View File

@@ -3,6 +3,8 @@ package org.briarproject.bramble.db;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -58,7 +60,6 @@ import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED; import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
import static org.briarproject.bramble.api.db.Metadata.REMOVE; import static org.briarproject.bramble.api.db.Metadata.REMOVE;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
@@ -72,13 +73,14 @@ import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPAC
import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY; import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS; import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getAgreementPrivateKey;
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getClientId;
import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.briarproject.bramble.test.TestUtils.getIdentity;
import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getMessage;
import static org.briarproject.bramble.test.TestUtils.getPendingContact; import static org.briarproject.bramble.test.TestUtils.getPendingContact;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory; import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
@@ -2250,8 +2252,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Identity withoutKeys = Identity withoutKeys =
new Identity(localAuthor, null, null, identity.getTimeCreated()); new Identity(localAuthor, null, null, identity.getTimeCreated());
assertFalse(withoutKeys.hasHandshakeKeyPair()); assertFalse(withoutKeys.hasHandshakeKeyPair());
byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); PublicKey publicKey = getAgreementPublicKey();
byte[] privateKey = getRandomBytes(123); PrivateKey privateKey = getAgreementPrivateKey();
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
@@ -2262,8 +2264,12 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.setHandshakeKeyPair(txn, localAuthor.getId(), publicKey, privateKey); db.setHandshakeKeyPair(txn, localAuthor.getId(), publicKey, privateKey);
retrieved = db.getIdentity(txn, localAuthor.getId()); retrieved = db.getIdentity(txn, localAuthor.getId());
assertTrue(retrieved.hasHandshakeKeyPair()); assertTrue(retrieved.hasHandshakeKeyPair());
assertArrayEquals(publicKey, retrieved.getHandshakePublicKey()); PublicKey handshakePub = retrieved.getHandshakePublicKey();
assertArrayEquals(privateKey, retrieved.getHandshakePrivateKey()); assertNotNull(handshakePub);
assertArrayEquals(publicKey.getEncoded(), handshakePub.getEncoded());
PrivateKey handshakePriv = retrieved.getHandshakePrivateKey();
assertNotNull(handshakePriv);
assertArrayEquals(privateKey.getEncoded(), handshakePriv.getEncoded());
db.commitTransaction(txn); db.commitTransaction(txn);
db.close(); db.close();

View File

@@ -18,6 +18,8 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.briarproject.bramble.test.TestUtils.getAgreementPrivateKey;
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.briarproject.bramble.test.TestUtils.getIdentity;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -28,21 +30,16 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
private final AuthorFactory authorFactory = private final AuthorFactory authorFactory =
context.mock(AuthorFactory.class); context.mock(AuthorFactory.class);
private final Clock clock = context.mock(Clock.class); private final Clock clock = context.mock(Clock.class);
private final PublicKey handshakePublicKey = context.mock(PublicKey.class);
private final PrivateKey handshakePrivateKey =
context.mock(PrivateKey.class);
private final Transaction txn = new Transaction(null, false); private final Transaction txn = new Transaction(null, false);
private final Identity identityWithKeys = getIdentity(); private final Identity identityWithKeys = getIdentity();
private final LocalAuthor localAuthor = identityWithKeys.getLocalAuthor(); private final LocalAuthor localAuthor = identityWithKeys.getLocalAuthor();
private final Identity identityWithoutKeys = new Identity(localAuthor, private final Identity identityWithoutKeys = new Identity(localAuthor,
null, null, identityWithKeys.getTimeCreated()); null, null, identityWithKeys.getTimeCreated());
private final PublicKey handshakePublicKey = getAgreementPublicKey();
private final PrivateKey handshakePrivateKey = getAgreementPrivateKey();
private final KeyPair handshakeKeyPair = private final KeyPair handshakeKeyPair =
new KeyPair(handshakePublicKey, handshakePrivateKey); new KeyPair(handshakePublicKey, handshakePrivateKey);
private final byte[] handshakePublicKeyBytes =
identityWithKeys.getHandshakePublicKey();
private final byte[] handshakePrivateKeyBytes =
identityWithKeys.getHandshakePrivateKey();
private IdentityManagerImpl identityManager; private IdentityManagerImpl identityManager;
@@ -69,12 +66,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
will(returnValue(singletonList(identityWithoutKeys))); will(returnValue(singletonList(identityWithoutKeys)));
oneOf(crypto).generateAgreementKeyPair(); oneOf(crypto).generateAgreementKeyPair();
will(returnValue(handshakeKeyPair)); will(returnValue(handshakeKeyPair));
oneOf(handshakePublicKey).getEncoded();
will(returnValue(handshakePublicKeyBytes));
oneOf(handshakePrivateKey).getEncoded();
will(returnValue(handshakePrivateKeyBytes));
oneOf(db).setHandshakeKeyPair(txn, localAuthor.getId(), oneOf(db).setHandshakeKeyPair(txn, localAuthor.getId(),
handshakePublicKeyBytes, handshakePrivateKeyBytes); handshakePublicKey, handshakePrivateKey);
}}); }});
identityManager.onDatabaseOpened(txn); identityManager.onDatabaseOpened(txn);
@@ -104,10 +97,6 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
will(returnValue(singletonList(identityWithoutKeys))); will(returnValue(singletonList(identityWithoutKeys)));
oneOf(crypto).generateAgreementKeyPair(); oneOf(crypto).generateAgreementKeyPair();
will(returnValue(handshakeKeyPair)); will(returnValue(handshakeKeyPair));
oneOf(handshakePublicKey).getEncoded();
will(returnValue(handshakePublicKeyBytes));
oneOf(handshakePrivateKey).getEncoded();
will(returnValue(handshakePrivateKeyBytes));
}}); }});
assertEquals(localAuthor, identityManager.getLocalAuthor()); assertEquals(localAuthor, identityManager.getLocalAuthor());

View File

@@ -16,10 +16,13 @@ import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import static java.util.Collections.emptyList;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.MASTER_KEY_LABEL; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.MASTER_KEY_LABEL;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL;
import static org.briarproject.bramble.test.TestUtils.getAgreementPrivateKey;
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@@ -34,21 +37,17 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
setImposteriser(ClassImposteriser.INSTANCE); setImposteriser(ClassImposteriser.INSTANCE);
}}; }};
private final PublicKey alicePubKey = private final PublicKey alicePubKey = getAgreementPublicKey();
context.mock(PublicKey.class, "alice");
private final byte[] alicePubKeyBytes = getRandomBytes(32);
private final byte[] aliceCommit = getRandomBytes(COMMIT_LENGTH); private final byte[] aliceCommit = getRandomBytes(COMMIT_LENGTH);
private final byte[] alicePayload = getRandomBytes(COMMIT_LENGTH + 8); private final byte[] alicePayload = getRandomBytes(COMMIT_LENGTH + 8);
private final byte[] aliceConfirm = getRandomBytes(SecretKey.LENGTH); private final byte[] aliceConfirm = getRandomBytes(SecretKey.LENGTH);
private final PublicKey bobPubKey = context.mock(PublicKey.class, "bob"); private final PublicKey bobPubKey = getAgreementPublicKey();
private final byte[] bobPubKeyBytes = getRandomBytes(32);
private final byte[] bobCommit = getRandomBytes(COMMIT_LENGTH); private final byte[] bobCommit = getRandomBytes(COMMIT_LENGTH);
private final byte[] bobPayload = getRandomBytes(COMMIT_LENGTH + 19); private final byte[] bobPayload = getRandomBytes(COMMIT_LENGTH + 19);
private final byte[] bobConfirm = getRandomBytes(SecretKey.LENGTH); private final byte[] bobConfirm = getRandomBytes(SecretKey.LENGTH);
private final PublicKey badPubKey = context.mock(PublicKey.class, "bad"); private final PublicKey badPubKey = getAgreementPublicKey();
private final byte[] badPubKeyBytes = getRandomBytes(32);
private final byte[] badCommit = getRandomBytes(COMMIT_LENGTH); private final byte[] badCommit = getRandomBytes(COMMIT_LENGTH);
private final byte[] badConfirm = getRandomBytes(SecretKey.LENGTH); private final byte[] badConfirm = getRandomBytes(SecretKey.LENGTH);
@@ -64,15 +63,13 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
PayloadEncoder payloadEncoder; PayloadEncoder payloadEncoder;
@Mock @Mock
KeyAgreementTransport transport; KeyAgreementTransport transport;
@Mock
PublicKey ourPubKey;
@Test @Test
public void testAliceProtocol() throws Exception { public void testAliceProtocol() throws Exception {
// set up // set up
Payload theirPayload = new Payload(bobCommit, null); Payload theirPayload = new Payload(bobCommit, emptyList());
Payload ourPayload = new Payload(aliceCommit, null); Payload ourPayload = new Payload(aliceCommit, emptyList());
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(alicePubKey, getAgreementPrivateKey());
SecretKey sharedSecret = getSecretKey(); SecretKey sharedSecret = getSecretKey();
SecretKey masterKey = getSecretKey(); SecretKey masterKey = getSecretKey();
@@ -87,24 +84,18 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
will(returnValue(alicePayload)); will(returnValue(alicePayload));
allowing(payloadEncoder).encode(theirPayload); allowing(payloadEncoder).encode(theirPayload);
will(returnValue(bobPayload)); will(returnValue(bobPayload));
allowing(ourPubKey).getEncoded();
will(returnValue(alicePubKeyBytes));
allowing(crypto).getAgreementKeyParser(); allowing(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
allowing(alicePubKey).getEncoded();
will(returnValue(alicePubKeyBytes));
allowing(bobPubKey).getEncoded();
will(returnValue(bobPubKeyBytes));
// Alice sends her public key // Alice sends her public key
oneOf(transport).sendKey(alicePubKeyBytes); oneOf(transport).sendKey(alicePubKey.getEncoded());
// Alice receives Bob's public key // Alice receives Bob's public key
oneOf(callbacks).connectionWaiting(); oneOf(callbacks).connectionWaiting();
oneOf(transport).receiveKey(); oneOf(transport).receiveKey();
will(returnValue(bobPubKeyBytes)); will(returnValue(bobPubKey.getEncoded()));
oneOf(callbacks).initialRecordReceived(); oneOf(callbacks).initialRecordReceived();
oneOf(keyParser).parsePublicKey(bobPubKeyBytes); oneOf(keyParser).parsePublicKey(bobPubKey.getEncoded());
will(returnValue(bobPubKey)); will(returnValue(bobPubKey));
// Alice verifies Bob's public key // Alice verifies Bob's public key
@@ -114,7 +105,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
// Alice computes shared secret // Alice computes shared secret
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, bobPubKey, oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, bobPubKey,
ourKeyPair, new byte[] {PROTOCOL_VERSION}, ourKeyPair, new byte[] {PROTOCOL_VERSION},
alicePubKeyBytes, bobPubKeyBytes); alicePubKey.getEncoded(), bobPubKey.getEncoded());
will(returnValue(sharedSecret)); will(returnValue(sharedSecret));
// Alice sends her confirmation record // Alice sends her confirmation record
@@ -146,9 +137,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
@Test @Test
public void testBobProtocol() throws Exception { public void testBobProtocol() throws Exception {
// set up // set up
Payload theirPayload = new Payload(aliceCommit, null); Payload theirPayload = new Payload(aliceCommit, emptyList());
Payload ourPayload = new Payload(bobCommit, null); Payload ourPayload = new Payload(bobCommit, emptyList());
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(bobPubKey, getAgreementPrivateKey());
SecretKey sharedSecret = getSecretKey(); SecretKey sharedSecret = getSecretKey();
SecretKey masterKey = getSecretKey(); SecretKey masterKey = getSecretKey();
@@ -163,20 +154,14 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
will(returnValue(bobPayload)); will(returnValue(bobPayload));
allowing(payloadEncoder).encode(theirPayload); allowing(payloadEncoder).encode(theirPayload);
will(returnValue(alicePayload)); will(returnValue(alicePayload));
allowing(ourPubKey).getEncoded();
will(returnValue(bobPubKeyBytes));
allowing(crypto).getAgreementKeyParser(); allowing(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
allowing(alicePubKey).getEncoded();
will(returnValue(alicePubKeyBytes));
allowing(bobPubKey).getEncoded();
will(returnValue(bobPubKeyBytes));
// Bob receives Alice's public key // Bob receives Alice's public key
oneOf(transport).receiveKey(); oneOf(transport).receiveKey();
will(returnValue(alicePubKeyBytes)); will(returnValue(alicePubKey.getEncoded()));
oneOf(callbacks).initialRecordReceived(); oneOf(callbacks).initialRecordReceived();
oneOf(keyParser).parsePublicKey(alicePubKeyBytes); oneOf(keyParser).parsePublicKey(alicePubKey.getEncoded());
will(returnValue(alicePubKey)); will(returnValue(alicePubKey));
// Bob verifies Alice's public key // Bob verifies Alice's public key
@@ -184,12 +169,12 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
will(returnValue(aliceCommit)); will(returnValue(aliceCommit));
// Bob sends his public key // Bob sends his public key
oneOf(transport).sendKey(bobPubKeyBytes); oneOf(transport).sendKey(bobPubKey.getEncoded());
// Bob computes shared secret // Bob computes shared secret
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, alicePubKey, oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, alicePubKey,
ourKeyPair, new byte[] {PROTOCOL_VERSION}, ourKeyPair, new byte[] {PROTOCOL_VERSION},
alicePubKeyBytes, bobPubKeyBytes); alicePubKey.getEncoded(), bobPubKey.getEncoded());
will(returnValue(sharedSecret)); will(returnValue(sharedSecret));
// Bob receives Alices's confirmation record // Bob receives Alices's confirmation record
@@ -221,9 +206,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
@Test(expected = AbortException.class) @Test(expected = AbortException.class)
public void testAliceProtocolAbortOnBadKey() throws Exception { public void testAliceProtocolAbortOnBadKey() throws Exception {
// set up // set up
Payload theirPayload = new Payload(bobCommit, null); Payload theirPayload = new Payload(bobCommit, emptyList());
Payload ourPayload = new Payload(aliceCommit, null); Payload ourPayload = new Payload(aliceCommit, emptyList());
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(alicePubKey, getAgreementPrivateKey());
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks, KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
crypto, keyAgreementCrypto, payloadEncoder, transport, crypto, keyAgreementCrypto, payloadEncoder, transport,
@@ -232,20 +217,18 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
// expectations // expectations
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Helpers // Helpers
allowing(ourPubKey).getEncoded();
will(returnValue(alicePubKeyBytes));
allowing(crypto).getAgreementKeyParser(); allowing(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
// Alice sends her public key // Alice sends her public key
oneOf(transport).sendKey(alicePubKeyBytes); oneOf(transport).sendKey(alicePubKey.getEncoded());
// Alice receives a bad public key // Alice receives a bad public key
oneOf(callbacks).connectionWaiting(); oneOf(callbacks).connectionWaiting();
oneOf(transport).receiveKey(); oneOf(transport).receiveKey();
will(returnValue(badPubKeyBytes)); will(returnValue(badPubKey.getEncoded()));
oneOf(callbacks).initialRecordReceived(); oneOf(callbacks).initialRecordReceived();
oneOf(keyParser).parsePublicKey(badPubKeyBytes); oneOf(keyParser).parsePublicKey(badPubKey.getEncoded());
will(returnValue(badPubKey)); will(returnValue(badPubKey));
// Alice verifies Bob's public key // Alice verifies Bob's public key
@@ -258,7 +241,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
// Alice never computes shared secret // Alice never computes shared secret
never(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, badPubKey, never(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, badPubKey,
ourKeyPair, new byte[] {PROTOCOL_VERSION}, ourKeyPair, new byte[] {PROTOCOL_VERSION},
alicePubKeyBytes, bobPubKeyBytes); alicePubKey.getEncoded(), bobPubKey.getEncoded());
}}); }});
// execute // execute
@@ -268,9 +251,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
@Test(expected = AbortException.class) @Test(expected = AbortException.class)
public void testBobProtocolAbortOnBadKey() throws Exception { public void testBobProtocolAbortOnBadKey() throws Exception {
// set up // set up
Payload theirPayload = new Payload(aliceCommit, null); Payload theirPayload = new Payload(aliceCommit, emptyList());
Payload ourPayload = new Payload(bobCommit, null); Payload ourPayload = new Payload(bobCommit, emptyList());
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(bobPubKey, getAgreementPrivateKey());
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks, KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
crypto, keyAgreementCrypto, payloadEncoder, transport, crypto, keyAgreementCrypto, payloadEncoder, transport,
@@ -279,16 +262,14 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
// expectations // expectations
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Helpers // Helpers
allowing(ourPubKey).getEncoded();
will(returnValue(bobPubKeyBytes));
allowing(crypto).getAgreementKeyParser(); allowing(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
// Bob receives a bad public key // Bob receives a bad public key
oneOf(transport).receiveKey(); oneOf(transport).receiveKey();
will(returnValue(badPubKeyBytes)); will(returnValue(badPubKey.getEncoded()));
oneOf(callbacks).initialRecordReceived(); oneOf(callbacks).initialRecordReceived();
oneOf(keyParser).parsePublicKey(badPubKeyBytes); oneOf(keyParser).parsePublicKey(badPubKey.getEncoded());
will(returnValue(badPubKey)); will(returnValue(badPubKey));
// Bob verifies Alice's public key // Bob verifies Alice's public key
@@ -299,7 +280,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
oneOf(transport).sendAbort(false); oneOf(transport).sendAbort(false);
// Bob never sends his public key // Bob never sends his public key
never(transport).sendKey(bobPubKeyBytes); never(transport).sendKey(bobPubKey.getEncoded());
}}); }});
// execute // execute
@@ -309,9 +290,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
@Test(expected = AbortException.class) @Test(expected = AbortException.class)
public void testAliceProtocolAbortOnBadConfirm() throws Exception { public void testAliceProtocolAbortOnBadConfirm() throws Exception {
// set up // set up
Payload theirPayload = new Payload(bobCommit, null); Payload theirPayload = new Payload(bobCommit, emptyList());
Payload ourPayload = new Payload(aliceCommit, null); Payload ourPayload = new Payload(aliceCommit, emptyList());
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(alicePubKey, getAgreementPrivateKey());
SecretKey sharedSecret = getSecretKey(); SecretKey sharedSecret = getSecretKey();
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks, KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
@@ -325,22 +306,18 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
will(returnValue(alicePayload)); will(returnValue(alicePayload));
allowing(payloadEncoder).encode(theirPayload); allowing(payloadEncoder).encode(theirPayload);
will(returnValue(bobPayload)); will(returnValue(bobPayload));
allowing(ourPubKey).getEncoded();
will(returnValue(alicePubKeyBytes));
allowing(crypto).getAgreementKeyParser(); allowing(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
allowing(bobPubKey).getEncoded();
will(returnValue(bobPubKeyBytes));
// Alice sends her public key // Alice sends her public key
oneOf(transport).sendKey(alicePubKeyBytes); oneOf(transport).sendKey(alicePubKey.getEncoded());
// Alice receives Bob's public key // Alice receives Bob's public key
oneOf(callbacks).connectionWaiting(); oneOf(callbacks).connectionWaiting();
oneOf(transport).receiveKey(); oneOf(transport).receiveKey();
will(returnValue(bobPubKeyBytes)); will(returnValue(bobPubKey.getEncoded()));
oneOf(callbacks).initialRecordReceived(); oneOf(callbacks).initialRecordReceived();
oneOf(keyParser).parsePublicKey(bobPubKeyBytes); oneOf(keyParser).parsePublicKey(bobPubKey.getEncoded());
will(returnValue(bobPubKey)); will(returnValue(bobPubKey));
// Alice verifies Bob's public key // Alice verifies Bob's public key
@@ -350,7 +327,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
// Alice computes shared secret // Alice computes shared secret
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, bobPubKey, oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, bobPubKey,
ourKeyPair, new byte[] {PROTOCOL_VERSION}, ourKeyPair, new byte[] {PROTOCOL_VERSION},
alicePubKeyBytes, bobPubKeyBytes); alicePubKey.getEncoded(), bobPubKey.getEncoded());
will(returnValue(sharedSecret)); will(returnValue(sharedSecret));
// Alice sends her confirmation record // Alice sends her confirmation record
@@ -384,9 +361,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
@Test(expected = AbortException.class) @Test(expected = AbortException.class)
public void testBobProtocolAbortOnBadConfirm() throws Exception { public void testBobProtocolAbortOnBadConfirm() throws Exception {
// set up // set up
Payload theirPayload = new Payload(aliceCommit, null); Payload theirPayload = new Payload(aliceCommit, emptyList());
Payload ourPayload = new Payload(bobCommit, null); Payload ourPayload = new Payload(bobCommit, emptyList());
KeyPair ourKeyPair = new KeyPair(ourPubKey, null); KeyPair ourKeyPair = new KeyPair(bobPubKey, getAgreementPrivateKey());
SecretKey sharedSecret = getSecretKey(); SecretKey sharedSecret = getSecretKey();
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks, KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
@@ -400,18 +377,14 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
will(returnValue(bobPayload)); will(returnValue(bobPayload));
allowing(payloadEncoder).encode(theirPayload); allowing(payloadEncoder).encode(theirPayload);
will(returnValue(alicePayload)); will(returnValue(alicePayload));
allowing(ourPubKey).getEncoded();
will(returnValue(bobPubKeyBytes));
allowing(crypto).getAgreementKeyParser(); allowing(crypto).getAgreementKeyParser();
will(returnValue(keyParser)); will(returnValue(keyParser));
allowing(alicePubKey).getEncoded();
will(returnValue(alicePubKeyBytes));
// Bob receives Alice's public key // Bob receives Alice's public key
oneOf(transport).receiveKey(); oneOf(transport).receiveKey();
will(returnValue(alicePubKeyBytes)); will(returnValue(alicePubKey.getEncoded()));
oneOf(callbacks).initialRecordReceived(); oneOf(callbacks).initialRecordReceived();
oneOf(keyParser).parsePublicKey(alicePubKeyBytes); oneOf(keyParser).parsePublicKey(alicePubKey.getEncoded());
will(returnValue(alicePubKey)); will(returnValue(alicePubKey));
// Bob verifies Alice's public key // Bob verifies Alice's public key
@@ -419,12 +392,12 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
will(returnValue(aliceCommit)); will(returnValue(aliceCommit));
// Bob sends his public key // Bob sends his public key
oneOf(transport).sendKey(bobPubKeyBytes); oneOf(transport).sendKey(bobPubKey.getEncoded());
// Bob computes shared secret // Bob computes shared secret
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, alicePubKey, oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, alicePubKey,
ourKeyPair, new byte[] {PROTOCOL_VERSION}, ourKeyPair, new byte[] {PROTOCOL_VERSION},
alicePubKeyBytes, bobPubKeyBytes); alicePubKey.getEncoded(), bobPubKey.getEncoded());
will(returnValue(sharedSecret)); will(returnValue(sharedSecret));
// Bob receives a bad confirmation record // Bob receives a bad confirmation record

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.api.privategroup.invitation;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.crypto.CryptoExecutor; import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -21,7 +22,7 @@ public interface GroupInvitationFactory {
*/ */
@CryptoExecutor @CryptoExecutor
byte[] signInvitation(Contact c, GroupId privateGroupId, long timestamp, byte[] signInvitation(Contact c, GroupId privateGroupId, long timestamp,
byte[] privateKey); PrivateKey privateKey);
/** /**
* Returns a token to be signed by the creator when inviting a member to * Returns a token to be signed by the creator when inviting a member to

View File

@@ -4,6 +4,8 @@ import com.rometools.rome.feed.synd.SyndFeed;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.SignaturePrivateKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
@@ -70,7 +72,8 @@ class FeedFactoryImpl implements FeedFactory {
String url = d.getString(KEY_FEED_URL); String url = d.getString(KEY_FEED_URL);
BdfList authorList = d.getList(KEY_FEED_AUTHOR); BdfList authorList = d.getList(KEY_FEED_AUTHOR);
byte[] privateKey = d.getRaw(KEY_FEED_PRIVATE_KEY); PrivateKey privateKey =
new SignaturePrivateKey(d.getRaw(KEY_FEED_PRIVATE_KEY));
Author author = clientHelper.parseAndValidateAuthor(authorList); Author author = clientHelper.parseAndValidateAuthor(authorList);
LocalAuthor localAuthor = new LocalAuthor(author.getId(), LocalAuthor localAuthor = new LocalAuthor(author.getId(),
author.getFormatVersion(), author.getName(), author.getFormatVersion(), author.getName(),

View File

@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.client.ContactGroupFactory; import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
@@ -83,7 +84,7 @@ abstract class AbstractProtocolEngine<S extends Session>
} }
Message sendAcceptMessage(Transaction txn, PeerSession s, long timestamp, Message sendAcceptMessage(Transaction txn, PeerSession s, long timestamp,
byte[] ephemeralPublicKey, long acceptTimestamp, PublicKey ephemeralPublicKey, long acceptTimestamp,
Map<TransportId, TransportProperties> transportProperties, Map<TransportId, TransportProperties> transportProperties,
boolean visible) throws DbException { boolean visible) throws DbException {
Message m = messageEncoder Message m = messageEncoder

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar.introduction; package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
@@ -17,14 +18,13 @@ import javax.annotation.concurrent.Immutable;
class AcceptMessage extends AbstractIntroductionMessage { class AcceptMessage extends AbstractIntroductionMessage {
private final SessionId sessionId; private final SessionId sessionId;
private final byte[] ephemeralPublicKey; private final PublicKey ephemeralPublicKey;
private final long acceptTimestamp; private final long acceptTimestamp;
private final Map<TransportId, TransportProperties> transportProperties; private final Map<TransportId, TransportProperties> transportProperties;
protected AcceptMessage(MessageId messageId, GroupId groupId, protected AcceptMessage(MessageId messageId, GroupId groupId,
long timestamp, @Nullable MessageId previousMessageId, long timestamp, @Nullable MessageId previousMessageId,
SessionId sessionId, SessionId sessionId, PublicKey ephemeralPublicKey,
byte[] ephemeralPublicKey,
long acceptTimestamp, long acceptTimestamp,
Map<TransportId, TransportProperties> transportProperties) { Map<TransportId, TransportProperties> transportProperties) {
super(messageId, groupId, timestamp, previousMessageId); super(messageId, groupId, timestamp, previousMessageId);
@@ -38,7 +38,7 @@ class AcceptMessage extends AbstractIntroductionMessage {
return sessionId; return sessionId;
} }
public byte[] getEphemeralPublicKey() { public PublicKey getEphemeralPublicKey() {
return ephemeralPublicKey; return ephemeralPublicKey;
} }

View File

@@ -6,6 +6,8 @@ import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.db.ContactExistsException; import org.briarproject.bramble.api.db.ContactExistsException;
@@ -272,9 +274,9 @@ class IntroduceeProtocolEngine
markRequestsUnavailableToAnswer(txn, s); markRequestsUnavailableToAnswer(txn, s);
// Create ephemeral key pair and get local transport properties // Create ephemeral key pair and get local transport properties
KeyPair keyPair = crypto.generateKeyPair(); KeyPair keyPair = crypto.generateAgreementKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded(); PublicKey publicKey = keyPair.getPublic();
byte[] privateKey = keyPair.getPrivate().getEncoded(); PrivateKey privateKey = keyPair.getPrivate();
Map<TransportId, TransportProperties> transportProperties = Map<TransportId, TransportProperties> transportProperties =
transportPropertyManager.getLocalProperties(txn); transportPropertyManager.getLocalProperties(txn);

View File

@@ -1,5 +1,7 @@
package org.briarproject.briar.introduction; package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -70,7 +72,7 @@ class IntroduceeSession extends Session<IntroduceeState>
static IntroduceeSession addLocalAccept(IntroduceeSession s, static IntroduceeSession addLocalAccept(IntroduceeSession s,
IntroduceeState state, Message acceptMessage, IntroduceeState state, Message acceptMessage,
byte[] ephemeralPublicKey, byte[] ephemeralPrivateKey, PublicKey ephemeralPublicKey, PrivateKey ephemeralPrivateKey,
long acceptTimestamp, long acceptTimestamp,
Map<TransportId, TransportProperties> transportProperties) { Map<TransportId, TransportProperties> transportProperties) {
Local local = new Local(s.local.alice, acceptMessage.getId(), Local local = new Local(s.local.alice, acceptMessage.getId(),
@@ -190,7 +192,7 @@ class IntroduceeSession extends Session<IntroduceeState>
@Nullable @Nullable
final MessageId lastMessageId; final MessageId lastMessageId;
@Nullable @Nullable
final byte[] ephemeralPublicKey; final PublicKey ephemeralPublicKey;
@Nullable @Nullable
final Map<TransportId, TransportProperties> transportProperties; final Map<TransportId, TransportProperties> transportProperties;
final long acceptTimestamp; final long acceptTimestamp;
@@ -198,7 +200,7 @@ class IntroduceeSession extends Session<IntroduceeState>
final byte[] macKey; final byte[] macKey;
private Common(boolean alice, @Nullable MessageId lastMessageId, private Common(boolean alice, @Nullable MessageId lastMessageId,
@Nullable byte[] ephemeralPublicKey, @Nullable @Nullable PublicKey ephemeralPublicKey, @Nullable
Map<TransportId, TransportProperties> transportProperties, Map<TransportId, TransportProperties> transportProperties,
long acceptTimestamp, @Nullable byte[] macKey) { long acceptTimestamp, @Nullable byte[] macKey) {
this.alice = alice; this.alice = alice;
@@ -213,11 +215,12 @@ class IntroduceeSession extends Session<IntroduceeState>
static class Local extends Common { static class Local extends Common {
final long lastMessageTimestamp; final long lastMessageTimestamp;
@Nullable @Nullable
final byte[] ephemeralPrivateKey; final PrivateKey ephemeralPrivateKey;
Local(boolean alice, @Nullable MessageId lastMessageId, Local(boolean alice, @Nullable MessageId lastMessageId,
long lastMessageTimestamp, @Nullable byte[] ephemeralPublicKey, long lastMessageTimestamp,
@Nullable byte[] ephemeralPrivateKey, @Nullable @Nullable PublicKey ephemeralPublicKey,
@Nullable PrivateKey ephemeralPrivateKey, @Nullable
Map<TransportId, TransportProperties> transportProperties, Map<TransportId, TransportProperties> transportProperties,
long acceptTimestamp, @Nullable byte[] macKey) { long acceptTimestamp, @Nullable byte[] macKey) {
super(alice, lastMessageId, ephemeralPublicKey, transportProperties, super(alice, lastMessageId, ephemeralPublicKey, transportProperties,
@@ -239,7 +242,7 @@ class IntroduceeSession extends Session<IntroduceeState>
Remote(boolean alice, Author author, Remote(boolean alice, Author author,
@Nullable MessageId lastMessageId, @Nullable MessageId lastMessageId,
@Nullable byte[] ephemeralPublicKey, @Nullable @Nullable PublicKey ephemeralPublicKey, @Nullable
Map<TransportId, TransportProperties> transportProperties, Map<TransportId, TransportProperties> transportProperties,
long acceptTimestamp, @Nullable byte[] macKey) { long acceptTimestamp, @Nullable byte[] macKey) {
super(alice, lastMessageId, ephemeralPublicKey, transportProperties, super(alice, lastMessageId, ephemeralPublicKey, transportProperties,

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.introduction; package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
@@ -28,7 +29,7 @@ interface IntroductionCrypto {
/** /**
* Generates an agreement key pair. * Generates an agreement key pair.
*/ */
KeyPair generateKeyPair(); KeyPair generateAgreementKeyPair();
/** /**
* Derives a session master key for Alice or Bob. * Derives a session master key for Alice or Bob.
@@ -74,7 +75,7 @@ interface IntroductionCrypto {
* (from {@link LocalAuthor#getPrivateKey()}) * (from {@link LocalAuthor#getPrivateKey()})
* @return The signature as a byte array * @return The signature as a byte array
*/ */
byte[] sign(SecretKey macKey, byte[] privateKey) byte[] sign(SecretKey macKey, PrivateKey privateKey)
throws GeneralSecurityException; throws GeneralSecurityException;
/** /**

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.KeyParser;
import org.briarproject.bramble.api.crypto.PrivateKey; import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
@@ -61,7 +60,7 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
} }
@Override @Override
public KeyPair generateKeyPair() { public KeyPair generateAgreementKeyPair() {
return crypto.generateAgreementKeyPair(); return crypto.generateAgreementKeyPair();
} }
@@ -82,21 +81,17 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
); );
} }
SecretKey deriveMasterKey(byte[] publicKey, byte[] privateKey, SecretKey deriveMasterKey(PublicKey publicKey, PrivateKey privateKey,
byte[] remotePublicKey, boolean alice) PublicKey remotePublicKey, boolean alice)
throws GeneralSecurityException { throws GeneralSecurityException {
KeyParser kp = crypto.getAgreementKeyParser(); KeyPair keyPair = new KeyPair(publicKey, privateKey);
PublicKey remoteEphemeralPublicKey = kp.parsePublicKey(remotePublicKey);
PublicKey ephemeralPublicKey = kp.parsePublicKey(publicKey);
PrivateKey ephemeralPrivateKey = kp.parsePrivateKey(privateKey);
KeyPair keyPair = new KeyPair(ephemeralPublicKey, ephemeralPrivateKey);
return crypto.deriveSharedSecret( return crypto.deriveSharedSecret(
LABEL_MASTER_KEY, LABEL_MASTER_KEY,
remoteEphemeralPublicKey, remotePublicKey,
keyPair, keyPair,
new byte[] {MAJOR_VERSION}, new byte[] {MAJOR_VERSION},
alice ? publicKey : remotePublicKey, alice ? publicKey.getEncoded() : remotePublicKey.getEncoded(),
alice ? remotePublicKey : publicKey alice ? remotePublicKey.getEncoded() : publicKey.getEncoded()
); );
} }
@@ -177,13 +172,9 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
} }
@Override @Override
public byte[] sign(SecretKey macKey, byte[] privateKey) public byte[] sign(SecretKey macKey, PrivateKey privateKey)
throws GeneralSecurityException { throws GeneralSecurityException {
return crypto.sign( return crypto.sign(LABEL_AUTH_SIGN, getNonce(macKey), privateKey);
LABEL_AUTH_SIGN,
getNonce(macKey),
privateKey
);
} }
@Override @Override
@@ -194,7 +185,7 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
verifySignature(macKey, s.getRemote().author.getPublicKey(), signature); verifySignature(macKey, s.getRemote().author.getPublicKey(), signature);
} }
void verifySignature(SecretKey macKey, byte[] publicKey, void verifySignature(SecretKey macKey, PublicKey publicKey,
byte[] signature) throws GeneralSecurityException { byte[] signature) throws GeneralSecurityException {
byte[] nonce = getNonce(macKey); byte[] nonce = getNonce(macKey);
if (!crypto.verifySignature(signature, LABEL_AUTH_SIGN, nonce, if (!crypto.verifySignature(signature, LABEL_AUTH_SIGN, nonce,

View File

@@ -15,10 +15,9 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.client.SessionId;
import java.util.Collections;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
@@ -84,8 +83,7 @@ class IntroductionValidator extends BdfMessageValidator {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
MessageId dependency = new MessageId(previousMessageId); MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, return new BdfMessageContext(meta, singletonList(dependency));
Collections.singletonList(dependency));
} }
} }
@@ -101,6 +99,7 @@ class IntroductionValidator extends BdfMessageValidator {
byte[] ephemeralPublicKey = body.getRaw(3); byte[] ephemeralPublicKey = body.getRaw(3);
checkLength(ephemeralPublicKey, 0, MAX_PUBLIC_KEY_LENGTH); checkLength(ephemeralPublicKey, 0, MAX_PUBLIC_KEY_LENGTH);
clientHelper.parseAndValidateAgreementPublicKey(ephemeralPublicKey);
long timestamp = body.getLong(4); long timestamp = body.getLong(4);
if (timestamp < 0) throw new FormatException(); if (timestamp < 0) throw new FormatException();
@@ -111,15 +110,13 @@ class IntroductionValidator extends BdfMessageValidator {
.parseAndValidateTransportPropertiesMap(transportProperties); .parseAndValidateTransportPropertiesMap(transportProperties);
SessionId sessionId = new SessionId(sessionIdBytes); SessionId sessionId = new SessionId(sessionIdBytes);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder.encodeMetadata(ACCEPT, sessionId,
.encodeMetadata(ACCEPT, sessionId, m.getTimestamp(), false, m.getTimestamp(), false, false, false);
false, false);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
MessageId dependency = new MessageId(previousMessageId); MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, return new BdfMessageContext(meta, singletonList(dependency));
Collections.singletonList(dependency));
} }
} }
@@ -140,12 +137,10 @@ class IntroductionValidator extends BdfMessageValidator {
checkLength(signature, 1, MAX_SIGNATURE_BYTES); checkLength(signature, 1, MAX_SIGNATURE_BYTES);
SessionId sessionId = new SessionId(sessionIdBytes); SessionId sessionId = new SessionId(sessionIdBytes);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder.encodeMetadata(AUTH, sessionId,
.encodeMetadata(AUTH, sessionId, m.getTimestamp(), false, false, m.getTimestamp(), false, false, false);
false);
MessageId dependency = new MessageId(previousMessageId); MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, return new BdfMessageContext(meta, singletonList(dependency));
Collections.singletonList(dependency));
} }
private BdfMessageContext validateActivateMessage(Message m, BdfList body) private BdfMessageContext validateActivateMessage(Message m, BdfList body)
@@ -162,15 +157,13 @@ class IntroductionValidator extends BdfMessageValidator {
checkLength(mac, MAC_BYTES); checkLength(mac, MAC_BYTES);
SessionId sessionId = new SessionId(sessionIdBytes); SessionId sessionId = new SessionId(sessionIdBytes);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder.encodeMetadata(ACTIVATE, sessionId,
.encodeMetadata(ACTIVATE, sessionId, m.getTimestamp(), false, m.getTimestamp(), false, false, false);
false, false);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
MessageId dependency = new MessageId(previousMessageId); MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, return new BdfMessageContext(meta, singletonList(dependency));
Collections.singletonList(dependency));
} }
} }
@@ -185,15 +178,13 @@ class IntroductionValidator extends BdfMessageValidator {
checkLength(previousMessageId, UniqueId.LENGTH); checkLength(previousMessageId, UniqueId.LENGTH);
SessionId sessionId = new SessionId(sessionIdBytes); SessionId sessionId = new SessionId(sessionIdBytes);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder.encodeMetadata(type, sessionId,
.encodeMetadata(type, sessionId, m.getTimestamp(), false, false, m.getTimestamp(), false, false, false);
false);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
MessageId dependency = new MessageId(previousMessageId); MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, return new BdfMessageContext(meta, singletonList(dependency));
Collections.singletonList(dependency));
} }
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar.introduction; package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -35,7 +36,7 @@ interface MessageEncoder {
Message encodeAcceptMessage(GroupId contactGroupId, long timestamp, Message encodeAcceptMessage(GroupId contactGroupId, long timestamp,
@Nullable MessageId previousMessageId, SessionId sessionId, @Nullable MessageId previousMessageId, SessionId sessionId,
byte[] ephemeralPublicKey, long acceptTimestamp, PublicKey ephemeralPublicKey, long acceptTimestamp,
Map<TransportId, TransportProperties> transportProperties); Map<TransportId, TransportProperties> transportProperties);
Message encodeDeclineMessage(GroupId contactGroupId, long timestamp, Message encodeDeclineMessage(GroupId contactGroupId, long timestamp,

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -105,13 +106,13 @@ class MessageEncoderImpl implements MessageEncoder {
@Override @Override
public Message encodeAcceptMessage(GroupId contactGroupId, long timestamp, public Message encodeAcceptMessage(GroupId contactGroupId, long timestamp,
@Nullable MessageId previousMessageId, SessionId sessionId, @Nullable MessageId previousMessageId, SessionId sessionId,
byte[] ephemeralPublicKey, long acceptTimestamp, PublicKey ephemeralPublicKey, long acceptTimestamp,
Map<TransportId, TransportProperties> transportProperties) { Map<TransportId, TransportProperties> transportProperties) {
BdfList body = BdfList.of( BdfList body = BdfList.of(
ACCEPT.getValue(), ACCEPT.getValue(),
sessionId, sessionId,
previousMessageId, previousMessageId,
ephemeralPublicKey, ephemeralPublicKey.getEncoded(),
acceptTimestamp, acceptTimestamp,
clientHelper.toDictionary(transportProperties) clientHelper.toDictionary(transportProperties)
); );

View File

@@ -2,6 +2,8 @@ package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
@@ -86,7 +88,7 @@ class MessageParserImpl implements MessageParser {
byte[] previousMsgBytes = body.getOptionalRaw(2); byte[] previousMsgBytes = body.getOptionalRaw(2);
MessageId previousMessageId = (previousMsgBytes == null ? null : MessageId previousMessageId = (previousMsgBytes == null ? null :
new MessageId(previousMsgBytes)); new MessageId(previousMsgBytes));
byte[] ephemeralPublicKey = body.getRaw(3); PublicKey ephemeralPublicKey = new AgreementPublicKey(body.getRaw(3));
long acceptTimestamp = body.getLong(4); long acceptTimestamp = body.getLong(4);
Map<TransportId, TransportProperties> transportProperties = clientHelper Map<TransportId, TransportProperties> transportProperties = clientHelper
.parseAndValidateTransportPropertiesMap(body.getDictionary(5)); .parseAndValidateTransportPropertiesMap(body.getDictionary(5));

View File

@@ -2,6 +2,10 @@ package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -122,12 +126,12 @@ class SessionParserImpl implements SessionParser {
MessageId lastLocalMessageId = MessageId lastLocalMessageId =
getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID); getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID);
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP); long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
byte[] ephemeralPublicKey = PublicKey ephemeralPublicKey =
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PUBLIC_KEY); getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
BdfDictionary tpDict = BdfDictionary tpDict =
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES); d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
byte[] ephemeralPrivateKey = PrivateKey ephemeralPrivateKey =
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PRIVATE_KEY); getEphemeralPrivateKey(d, SESSION_KEY_EPHEMERAL_PRIVATE_KEY);
Map<TransportId, TransportProperties> transportProperties = Map<TransportId, TransportProperties> transportProperties =
tpDict == null ? null : clientHelper tpDict == null ? null : clientHelper
.parseAndValidateTransportPropertiesMap(tpDict); .parseAndValidateTransportPropertiesMap(tpDict);
@@ -143,8 +147,8 @@ class SessionParserImpl implements SessionParser {
Author remoteAuthor = getAuthor(d, SESSION_KEY_REMOTE_AUTHOR); Author remoteAuthor = getAuthor(d, SESSION_KEY_REMOTE_AUTHOR);
MessageId lastRemoteMessageId = MessageId lastRemoteMessageId =
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID); getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
byte[] ephemeralPublicKey = PublicKey ephemeralPublicKey =
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PUBLIC_KEY); getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
BdfDictionary tpDict = BdfDictionary tpDict =
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES); d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
Map<TransportId, TransportProperties> transportProperties = Map<TransportId, TransportProperties> transportProperties =
@@ -195,4 +199,17 @@ class SessionParserImpl implements SessionParser {
return map; return map;
} }
@Nullable
private PublicKey getEphemeralPublicKey(BdfDictionary d, String key)
throws FormatException {
byte[] keyBytes = d.getOptionalRaw(key);
return keyBytes == null ? null : new AgreementPublicKey(keyBytes);
}
@Nullable
private PrivateKey getEphemeralPrivateKey(BdfDictionary d, String key)
throws FormatException {
byte[] keyBytes = d.getOptionalRaw(key);
return keyBytes == null ? null : new AgreementPrivateKey(keyBytes);
}
} }

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.client.ContactGroupFactory; import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -35,7 +36,7 @@ class GroupInvitationFactoryImpl implements GroupInvitationFactory {
@Override @Override
public byte[] signInvitation(Contact c, GroupId privateGroupId, public byte[] signInvitation(Contact c, GroupId privateGroupId,
long timestamp, byte[] privateKey) { long timestamp, PrivateKey privateKey) {
AuthorId creatorId = c.getLocalAuthorId(); AuthorId creatorId = c.getLocalAuthorId();
AuthorId memberId = c.getAuthor().getId(); AuthorId memberId = c.getAuthor().getId();
BdfList token = createInviteToken(creatorId, memberId, privateGroupId, BdfList token = createInviteToken(creatorId, memberId, privateGroupId,

View File

@@ -19,7 +19,6 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ; import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_AVAILABLE_TO_ANSWER; import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_INVITATION_ACCEPTED; import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_INVITATION_ACCEPTED;
@@ -105,14 +104,7 @@ class MessageParserImpl implements MessageParser {
String text = body.getOptionalString(4); String text = body.getOptionalString(4);
byte[] signature = body.getRaw(5); byte[] signature = body.getRaw(5);
// Format version, name, public key Author creator = clientHelper.parseAndValidateAuthor(creatorList);
int formatVersion = creatorList.getLong(0).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String creatorName = creatorList.getString(1);
byte[] creatorPublicKey = creatorList.getRaw(2);
Author creator = authorFactory.createAuthor(formatVersion, creatorName,
creatorPublicKey);
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup( PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
groupName, creator, salt); groupName, creator, salt);
return new InviteMessage(m.getId(), m.getGroupId(), return new InviteMessage(m.getId(), m.getGroupId(),

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogFactory; import org.briarproject.briar.api.blog.BlogFactory;
@@ -12,21 +11,16 @@ import org.briarproject.briar.api.blog.BlogFactory;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
class BlogMessageParserImpl extends MessageParserImpl<Blog> { class BlogMessageParserImpl extends MessageParserImpl<Blog> {
private final BlogFactory blogFactory; private final BlogFactory blogFactory;
private final AuthorFactory authorFactory;
@Inject @Inject
BlogMessageParserImpl(ClientHelper clientHelper, BlogFactory blogFactory, BlogMessageParserImpl(ClientHelper clientHelper, BlogFactory blogFactory) {
AuthorFactory authorFactory) {
super(clientHelper); super(clientHelper);
this.blogFactory = blogFactory; this.blogFactory = blogFactory;
this.authorFactory = authorFactory;
} }
@Override @Override
@@ -35,14 +29,7 @@ class BlogMessageParserImpl extends MessageParserImpl<Blog> {
BdfList authorList = descriptor.getList(0); BdfList authorList = descriptor.getList(0);
boolean rssFeed = descriptor.getBoolean(1); boolean rssFeed = descriptor.getBoolean(1);
// Format version, name, public key Author author = clientHelper.parseAndValidateAuthor(authorList);
int formatVersion = authorList.getLong(0).intValue();
if (formatVersion != FORMAT_VERSION) throw new FormatException();
String name = authorList.getString(1);
byte[] publicKey = authorList.getRaw(2);
Author author = authorFactory.createAuthor(formatVersion, name,
publicKey);
if (rssFeed) return blogFactory.createFeedBlog(author); if (rssFeed) return blogFactory.createFeedBlog(author);
else return blogFactory.createBlog(author); else return blogFactory.createBlog(author);
} }

View File

@@ -30,7 +30,7 @@ import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_VISIBLE_IN
abstract class MessageParserImpl<S extends Shareable> abstract class MessageParserImpl<S extends Shareable>
implements MessageParser<S> { implements MessageParser<S> {
private final ClientHelper clientHelper; protected final ClientHelper clientHelper;
MessageParserImpl(ClientHelper clientHelper) { MessageParserImpl(ClientHelper clientHelper) {
this.clientHelper = clientHelper; this.clientHelper = clientHelper;

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.forum;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.UniqueId; import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.client.BdfMessageContext; import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -37,9 +38,9 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH); private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
private final Author author = getAuthor(); private final Author author = getAuthor();
private final String authorName = author.getName(); private final String authorName = author.getName();
private final byte[] authorPublicKey = author.getPublicKey(); private final PublicKey authorPublicKey = author.getPublicKey();
private final BdfList authorList = BdfList.of(author.getFormatVersion(), private final BdfList authorList = BdfList.of(author.getFormatVersion(),
authorName, authorPublicKey); authorName, authorPublicKey.getEncoded());
private final BdfList signedWithParent = BdfList.of(groupId, timestamp, private final BdfList signedWithParent = BdfList.of(groupId, timestamp,
parentId.getBytes(), authorList, text); parentId.getBytes(), authorList, text);
private final BdfList signedWithoutParent = BdfList.of(groupId, timestamp, private final BdfList signedWithoutParent = BdfList.of(groupId, timestamp,

View File

@@ -64,8 +64,8 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
crypto.isAlice(introducee1.getId(), introducee2.getId()); crypto.isAlice(introducee1.getId(), introducee2.getId());
alice = isAlice ? introducee1 : introducee2; alice = isAlice ? introducee1 : introducee2;
bob = isAlice ? introducee2 : introducee1; bob = isAlice ? introducee2 : introducee1;
aliceEphemeral = crypto.generateKeyPair(); aliceEphemeral = crypto.generateAgreementKeyPair();
bobEphemeral = crypto.generateKeyPair(); bobEphemeral = crypto.generateAgreementKeyPair();
} }
@Test @Test
@@ -86,30 +86,25 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
@Test @Test
public void testDeriveMasterKey() throws Exception { public void testDeriveMasterKey() throws Exception {
SecretKey aliceMasterKey = SecretKey aliceMasterKey = crypto.deriveMasterKey(
crypto.deriveMasterKey(aliceEphemeral.getPublic().getEncoded(), aliceEphemeral.getPublic(), aliceEphemeral.getPrivate(),
aliceEphemeral.getPrivate().getEncoded(), bobEphemeral.getPublic(), true);
bobEphemeral.getPublic().getEncoded(), true); SecretKey bobMasterKey = crypto.deriveMasterKey(
SecretKey bobMasterKey = bobEphemeral.getPublic(), bobEphemeral.getPrivate(),
crypto.deriveMasterKey(bobEphemeral.getPublic().getEncoded(), aliceEphemeral.getPublic(), false);
bobEphemeral.getPrivate().getEncoded(),
aliceEphemeral.getPublic().getEncoded(), false);
assertArrayEquals(aliceMasterKey.getBytes(), bobMasterKey.getBytes()); assertArrayEquals(aliceMasterKey.getBytes(), bobMasterKey.getBytes());
} }
@Test @Test
public void testAliceAuthMac() throws Exception { public void testAliceAuthMac() throws Exception {
SecretKey aliceMacKey = crypto.deriveMacKey(masterKey, true); SecretKey aliceMacKey = crypto.deriveMacKey(masterKey, true);
Local local = new Local(true, null, -1, Local local = new Local(true, null, -1, aliceEphemeral.getPublic(),
aliceEphemeral.getPublic().getEncoded(), aliceEphemeral.getPrivate(), aliceTransport,
aliceEphemeral.getPrivate().getEncoded(), aliceTransport,
aliceAcceptTimestamp, aliceMacKey.getBytes()); aliceAcceptTimestamp, aliceMacKey.getBytes());
Remote remote = new Remote(false, bob, null, Remote remote = new Remote(false, bob, null, bobEphemeral.getPublic(),
bobEphemeral.getPublic().getEncoded(), bobTransport, bobTransport, bobAcceptTimestamp, null);
bobAcceptTimestamp, null); byte[] aliceMac = crypto.authMac(aliceMacKey, introducer.getId(),
byte[] aliceMac = alice.getId(), local, remote);
crypto.authMac(aliceMacKey, introducer.getId(), alice.getId(),
local, remote);
// verify from Bob's perspective // verify from Bob's perspective
crypto.verifyAuthMac(aliceMac, aliceMacKey, introducer.getId(), crypto.verifyAuthMac(aliceMac, aliceMacKey, introducer.getId(),
@@ -119,16 +114,14 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
@Test @Test
public void testBobAuthMac() throws Exception { public void testBobAuthMac() throws Exception {
SecretKey bobMacKey = crypto.deriveMacKey(masterKey, false); SecretKey bobMacKey = crypto.deriveMacKey(masterKey, false);
Local local = new Local(false, null, -1, Local local = new Local(false, null, -1, bobEphemeral.getPublic(),
bobEphemeral.getPublic().getEncoded(), bobEphemeral.getPrivate(), bobTransport,
bobEphemeral.getPrivate().getEncoded(), bobTransport,
bobAcceptTimestamp, bobMacKey.getBytes()); bobAcceptTimestamp, bobMacKey.getBytes());
Remote remote = new Remote(true, alice, null, Remote remote = new Remote(true, alice, null,
aliceEphemeral.getPublic().getEncoded(), aliceTransport, aliceEphemeral.getPublic(), aliceTransport,
aliceAcceptTimestamp, null); aliceAcceptTimestamp, null);
byte[] bobMac = byte[] bobMac = crypto.authMac(bobMacKey, introducer.getId(),
crypto.authMac(bobMacKey, introducer.getId(), bob.getId(), bob.getId(), local, remote);
local, remote);
// verify from Alice's perspective // verify from Alice's perspective
crypto.verifyAuthMac(bobMac, bobMacKey, introducer.getId(), crypto.verifyAuthMac(bobMac, bobMacKey, introducer.getId(),

View File

@@ -42,9 +42,8 @@ import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID; import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTransportProperties; import static org.briarproject.bramble.test.TestUtils.getTransportProperties;
import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap; import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap;
@@ -1149,8 +1148,7 @@ public class IntroductionIntegrationTest
testModifiedResponse( testModifiedResponse(
m -> new AcceptMessage(m.getMessageId(), m.getGroupId(), m -> new AcceptMessage(m.getMessageId(), m.getGroupId(),
m.getTimestamp(), m.getPreviousMessageId(), m.getTimestamp(), m.getPreviousMessageId(),
m.getSessionId(), m.getSessionId(), getAgreementPublicKey(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
m.getAcceptTimestamp(), m.getTransportProperties()) m.getAcceptTimestamp(), m.getTransportProperties())
); );
} }
@@ -1216,8 +1214,8 @@ public class IntroductionIntegrationTest
@ParametersNotNullByDefault @ParametersNotNullByDefault
private abstract class IntroductionListener implements EventListener { private abstract class IntroductionListener implements EventListener {
protected volatile boolean aborted = false; volatile boolean aborted = false;
protected volatile Event latestEvent; volatile Event latestEvent;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
IntroductionResponse getResponse() { IntroductionResponse getResponse() {

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.BdfMessageContext; import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
@@ -14,8 +15,9 @@ import org.junit.Test;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -40,6 +42,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
private final MessageId previousMsgId = new MessageId(getRandomId()); private final MessageId previousMsgId = new MessageId(getRandomId());
private final String text = getRandomString(MAX_INTRODUCTION_TEXT_LENGTH); private final String text = getRandomString(MAX_INTRODUCTION_TEXT_LENGTH);
private final BdfDictionary meta = new BdfDictionary(); private final BdfDictionary meta = new BdfDictionary();
private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
private final long acceptTimestamp = 42; private final long acceptTimestamp = 42;
private final BdfDictionary transportProperties = BdfDictionary.of( private final BdfDictionary transportProperties = BdfDictionary.of(
new BdfEntry("transportId", new BdfDictionary()) new BdfEntry("transportId", new BdfDictionary())
@@ -123,8 +126,9 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
@Test @Test
public void testAcceptsAccept() throws Exception { public void testAcceptsAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH), previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
acceptTimestamp, transportProperties); acceptTimestamp, transportProperties);
expectParsePublicKey();
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateTransportPropertiesMap( oneOf(clientHelper).parseAndValidateTransportPropertiesMap(
transportProperties); transportProperties);
@@ -139,32 +143,31 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsTooShortBodyForAccept() throws Exception { public void testRejectsTooShortBodyForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp); acceptTimestamp);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsTooLongBodyForAccept() throws Exception { public void testRejectsTooLongBodyForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH), previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
acceptTimestamp, transportProperties, null); acceptTimestamp, transportProperties, null);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsInvalidSessionIdForAccept() throws Exception { public void testRejectsInvalidSessionIdForAccept() throws Exception {
BdfList body = BdfList body = BdfList.of(ACCEPT.getValue(), null,
BdfList.of(ACCEPT.getValue(), null, previousMsgId.getBytes(), previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp, acceptTimestamp, transportProperties);
transportProperties);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsInvalidPreviousMsgIdForAccept() throws Exception { public void testRejectsInvalidPreviousMsgIdForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), 1, BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), 1,
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp, ephemeralPublicKey.getEncoded(), acceptTimestamp,
transportProperties); transportProperties);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@@ -173,16 +176,17 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
public void testRejectsTooLongPublicKeyForAccept() throws Exception { public void testRejectsTooLongPublicKeyForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), previousMsgId.getBytes(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), acceptTimestamp, getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES + 1),
transportProperties); acceptTimestamp, transportProperties);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsNegativeTimestampForAccept() throws Exception { public void testRejectsNegativeTimestampForAccept() throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH), previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
-1, transportProperties); -1, transportProperties);
expectParsePublicKey();
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@@ -190,9 +194,9 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
public void testRejectsEmptyTransportPropertiesForAccept() public void testRejectsEmptyTransportPropertiesForAccept()
throws Exception { throws Exception {
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), acceptTimestamp, acceptTimestamp, new BdfDictionary());
new BdfDictionary()); expectParsePublicKey();
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@@ -271,8 +275,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsInvalidPreviousMsgIdForAuth() throws Exception { public void testRejectsInvalidPreviousMsgIdForAuth() throws Exception {
BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(),
1, getRandomBytes(MAC_BYTES), 1, getRandomBytes(MAC_BYTES), signature);
signature);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@@ -294,8 +297,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsTooLongMacForAuth() throws Exception { public void testRejectsTooLongMacForAuth() throws Exception {
BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(), BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(),
previousMsgId.getBytes(), previousMsgId.getBytes(), getRandomBytes(MAC_BYTES + 1),
getRandomBytes(MAC_BYTES + 1), signature); signature);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@@ -360,9 +363,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsInvalidSessionIdForActivate() throws Exception { public void testRejectsInvalidSessionIdForActivate() throws Exception {
BdfList body = BdfList body = BdfList.of(ACTIVATE.getValue(), null,
BdfList.of(ACTIVATE.getValue(), null, previousMsgId.getBytes(), previousMsgId.getBytes(), mac);
mac);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@@ -375,9 +377,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsPreviousMsgIdNullForActivate() throws Exception { public void testRejectsPreviousMsgIdNullForActivate() throws Exception {
BdfList body = BdfList body = BdfList.of(ACTIVATE.getValue(), sessionId.getBytes(),
BdfList.of(ACTIVATE.getValue(), sessionId.getBytes(), null, null, mac);
mac);
validator.validateMessage(message, group, body); validator.validateMessage(message, group, body);
} }
@@ -434,6 +435,13 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
// Introduction Helper Methods // Introduction Helper Methods
// //
private void expectParsePublicKey() throws Exception {
context.checking(new Expectations() {{
oneOf(clientHelper).parseAndValidateAgreementPublicKey(
ephemeralPublicKey.getEncoded());
will(returnValue(ephemeralPublicKey));
}});
}
private void expectEncodeRequestMetadata() { private void expectEncodeRequestMetadata() {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(messageEncoder).encodeRequestMetadata(message.getTimestamp()); oneOf(messageEncoder).encodeRequestMetadata(message.getTimestamp());
@@ -443,9 +451,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
private void expectEncodeMetadata(MessageType type) { private void expectEncodeMetadata(MessageType type) {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(messageEncoder) oneOf(messageEncoder).encodeMetadata(type, sessionId,
.encodeMetadata(type, sessionId, message.getTimestamp(), message.getTimestamp(), false, false, false);
false, false, false);
will(returnValue(meta)); will(returnValue(meta));
}}); }});
} }

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.MetadataEncoder; import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -24,7 +25,7 @@ import javax.inject.Inject;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAC_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES; import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_BYTES;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
@@ -66,8 +67,7 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
private final MessageId previousMsgId = new MessageId(getRandomId()); private final MessageId previousMsgId = new MessageId(getRandomId());
private final Author author; private final Author author;
private final String text = getRandomString(MAX_INTRODUCTION_TEXT_LENGTH); private final String text = getRandomString(MAX_INTRODUCTION_TEXT_LENGTH);
private final byte[] ephemeralPublicKey = private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final byte[] mac = getRandomBytes(MAC_BYTES); private final byte[] mac = getRandomBytes(MAC_BYTES);
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES); private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES);
@@ -173,7 +173,8 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
assertEquals(m.getTimestamp(), am.getTimestamp()); assertEquals(m.getTimestamp(), am.getTimestamp());
assertEquals(previousMsgId, am.getPreviousMessageId()); assertEquals(previousMsgId, am.getPreviousMessageId());
assertEquals(sessionId, am.getSessionId()); assertEquals(sessionId, am.getSessionId());
assertArrayEquals(ephemeralPublicKey, am.getEphemeralPublicKey()); assertArrayEquals(ephemeralPublicKey.getEncoded(),
am.getEphemeralPublicKey().getEncoded());
assertEquals(acceptTimestamp, am.getAcceptTimestamp()); assertEquals(acceptTimestamp, am.getAcceptTimestamp());
assertEquals(transportProperties, am.getTransportProperties()); assertEquals(transportProperties, am.getTransportProperties());
} }

View File

@@ -2,6 +2,8 @@ package org.briarproject.briar.introduction;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -21,7 +23,8 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.test.TestUtils.getAgreementPrivateKey;
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getTransportId; import static org.briarproject.bramble.test.TestUtils.getTransportId;
@@ -37,6 +40,7 @@ import static org.briarproject.briar.test.BriarTestUtils.getRealAuthor;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@@ -64,13 +68,10 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
private final MessageId lastRemoteMessageId2 = new MessageId(getRandomId()); private final MessageId lastRemoteMessageId2 = new MessageId(getRandomId());
private final Author author1; private final Author author1;
private final Author author2; private final Author author2;
private final byte[] ephemeralPublicKey = private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
getRandomBytes(MAX_PUBLIC_KEY_LENGTH); private final PrivateKey ephemeralPrivateKey = getAgreementPrivateKey();
private final byte[] ephemeralPrivateKey =
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final byte[] masterKey = getRandomBytes(SecretKey.LENGTH); private final byte[] masterKey = getRandomBytes(SecretKey.LENGTH);
private final byte[] remoteEphemeralPublicKey = private final PublicKey remoteEphemeralPublicKey = getAgreementPublicKey();
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
private final Map<TransportId, TransportProperties> transportProperties = private final Map<TransportId, TransportProperties> transportProperties =
getTransportPropertiesMap(3); getTransportPropertiesMap(3);
private final Map<TransportId, TransportProperties> private final Map<TransportId, TransportProperties>
@@ -193,13 +194,22 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
assertEquals(localTimestamp, s1.getLocal().lastMessageTimestamp); assertEquals(localTimestamp, s1.getLocal().lastMessageTimestamp);
assertEquals(s1.getLocal().lastMessageTimestamp, assertEquals(s1.getLocal().lastMessageTimestamp,
s2.getLocal().lastMessageTimestamp); s2.getLocal().lastMessageTimestamp);
assertArrayEquals(ephemeralPublicKey, s1.getLocal().ephemeralPublicKey); PublicKey s1LocalEphemeralPub = s1.getLocal().ephemeralPublicKey;
assertArrayEquals(s1.getLocal().ephemeralPublicKey, PublicKey s2LocalEphemeralPub = s2.getLocal().ephemeralPublicKey;
s2.getLocal().ephemeralPublicKey); assertNotNull(s1LocalEphemeralPub);
assertArrayEquals(ephemeralPrivateKey, assertNotNull(s2LocalEphemeralPub);
s1.getLocal().ephemeralPrivateKey); assertArrayEquals(ephemeralPublicKey.getEncoded(),
assertArrayEquals(s1.getLocal().ephemeralPrivateKey, s1LocalEphemeralPub.getEncoded());
s2.getLocal().ephemeralPrivateKey); assertArrayEquals(s1LocalEphemeralPub.getEncoded(),
s2LocalEphemeralPub.getEncoded());
PrivateKey s1LocalEphemeralPriv = s1.getLocal().ephemeralPrivateKey;
PrivateKey s2LocalEphemeralPriv = s2.getLocal().ephemeralPrivateKey;
assertNotNull(s1LocalEphemeralPriv);
assertNotNull(s2LocalEphemeralPriv);
assertArrayEquals(ephemeralPrivateKey.getEncoded(),
s1LocalEphemeralPriv.getEncoded());
assertArrayEquals(s1LocalEphemeralPriv.getEncoded(),
s2LocalEphemeralPriv.getEncoded());
assertEquals(transportProperties, s1.getLocal().transportProperties); assertEquals(transportProperties, s1.getLocal().transportProperties);
assertEquals(s1.getLocal().transportProperties, assertEquals(s1.getLocal().transportProperties,
s2.getLocal().transportProperties); s2.getLocal().transportProperties);
@@ -217,10 +227,14 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
assertEquals(lastRemoteMessageId, s1.getRemote().lastMessageId); assertEquals(lastRemoteMessageId, s1.getRemote().lastMessageId);
assertEquals(s1.getRemote().lastMessageId, assertEquals(s1.getRemote().lastMessageId,
s2.getRemote().lastMessageId); s2.getRemote().lastMessageId);
assertArrayEquals(remoteEphemeralPublicKey, PublicKey s1RemoteEphemeralPub = s1.getRemote().ephemeralPublicKey;
s1.getRemote().ephemeralPublicKey); PublicKey s2RemoteEphemeralPub = s2.getRemote().ephemeralPublicKey;
assertArrayEquals(s1.getRemote().ephemeralPublicKey, assertNotNull(s1RemoteEphemeralPub);
s2.getRemote().ephemeralPublicKey); assertNotNull(s2RemoteEphemeralPub);
assertArrayEquals(remoteEphemeralPublicKey.getEncoded(),
s1RemoteEphemeralPub.getEncoded());
assertArrayEquals(s1RemoteEphemeralPub.getEncoded(),
s2RemoteEphemeralPub.getEncoded());
assertEquals(remoteTransportProperties, assertEquals(remoteTransportProperties,
s1.getRemote().transportProperties); s1.getRemote().transportProperties);
assertEquals(s1.getRemote().transportProperties, assertEquals(s1.getRemote().transportProperties,
@@ -311,7 +325,7 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
ephemeralPublicKey, ephemeralPrivateKey, transportProperties, ephemeralPublicKey, ephemeralPrivateKey, transportProperties,
acceptTimestamp, localMacKey); acceptTimestamp, localMacKey);
Remote remote = new Remote(false, author2, lastRemoteMessageId, Remote remote = new Remote(false, author2, lastRemoteMessageId,
remoteEphemeralPublicKey, remoteTransportProperties, remoteEphemeralPublicKey, remoteTransportProperties,
remoteAcceptTimestamp, remoteMacKey); remoteAcceptTimestamp, remoteMacKey);
return new IntroduceeSession(sessionId, LOCAL_ACCEPTED, return new IntroduceeSession(sessionId, LOCAL_ACCEPTED,
requestTimestamp, groupId1, author1, local, remote, requestTimestamp, groupId1, author1, local, remote,

View File

@@ -29,6 +29,7 @@ import static org.briarproject.briar.api.privategroup.Visibility.INVISIBLE;
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_CONTACT; import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_CONTACT;
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_US; import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_US;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
/** /**
@@ -164,7 +165,7 @@ public class PrivateGroupIntegrationTest
getGroupMember(groupManager2, author1.getId()).getVisibility()); getGroupMember(groupManager2, author1.getId()).getVisibility());
// 1 reveals the contact relationship to 2 // 1 reveals the contact relationship to 2
assertTrue(contactId2From1 != null); assertNotNull(contactId2From1);
groupInvitationManager1.revealRelationship(contactId2From1, groupId0); groupInvitationManager1.revealRelationship(contactId2From1, groupId0);
sync1To2(1, true); sync1To2(1, true);
sync2To1(1, true); sync2To1(1, true);

View File

@@ -458,8 +458,8 @@ public class GroupInvitationIntegrationTest
sync1To0(1, true); sync1To0(1, true);
} }
private void sendInvitation(long timestamp, @Nullable String text) throws private void sendInvitation(long timestamp, @Nullable String text)
DbException { throws DbException {
byte[] signature = groupInvitationFactory.signInvitation(contact1From0, byte[] signature = groupInvitationFactory.signInvitation(contact1From0,
privateGroup0.getId(), timestamp, author0.getPrivateKey()); privateGroup0.getId(), timestamp, author0.getPrivateKey());
groupInvitationManager0 groupInvitationManager0