mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Merge branch 'key-pair-refactoring' into 'master'
Key pair refactoring See merge request briar/briar!1083
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package org.briarproject.bramble.api.client;
|
||||
|
||||
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.BdfList;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
@@ -96,14 +98,18 @@ public interface ClientHelper {
|
||||
|
||||
BdfList toList(Author a);
|
||||
|
||||
byte[] sign(String label, BdfList toSign, byte[] privateKey)
|
||||
byte[] sign(String label, BdfList toSign, PrivateKey privateKey)
|
||||
throws FormatException, GeneralSecurityException;
|
||||
|
||||
void verifySignature(byte[] signature, String label, BdfList signed,
|
||||
byte[] publicKey) throws FormatException, GeneralSecurityException;
|
||||
PublicKey publicKey)
|
||||
throws FormatException, GeneralSecurityException;
|
||||
|
||||
Author parseAndValidateAuthor(BdfList author) throws FormatException;
|
||||
|
||||
PublicKey parseAndValidateAgreementPublicKey(byte[] publicKeyBytes)
|
||||
throws FormatException;
|
||||
|
||||
TransportProperties parseAndValidateTransportProperties(
|
||||
BdfDictionary properties) throws FormatException;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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.AuthorId;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -8,7 +9,6 @@ import javax.annotation.Nullable;
|
||||
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_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
||||
|
||||
@Immutable
|
||||
@@ -21,21 +21,17 @@ public class Contact {
|
||||
@Nullable
|
||||
private final String alias;
|
||||
@Nullable
|
||||
private final byte[] handshakePublicKey;
|
||||
private final PublicKey handshakePublicKey;
|
||||
private final boolean verified;
|
||||
|
||||
public Contact(ContactId id, Author author, AuthorId localAuthorId,
|
||||
@Nullable String alias, @Nullable byte[] handshakePublicKey,
|
||||
@Nullable String alias, @Nullable PublicKey handshakePublicKey,
|
||||
boolean verified) {
|
||||
if (alias != null) {
|
||||
int aliasLength = toUtf8(alias).length;
|
||||
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (handshakePublicKey != null && (handshakePublicKey.length == 0 ||
|
||||
handshakePublicKey.length > MAX_PUBLIC_KEY_LENGTH)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.localAuthorId = localAuthorId;
|
||||
@@ -62,7 +58,7 @@ public class Contact {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getHandshakePublicKey() {
|
||||
public PublicKey getHandshakePublicKey() {
|
||||
return handshakePublicKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.api.contact;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
@@ -9,12 +10,12 @@ import javax.annotation.concurrent.Immutable;
|
||||
public class PendingContact {
|
||||
|
||||
private final PendingContactId id;
|
||||
private final byte[] publicKey;
|
||||
private final PublicKey publicKey;
|
||||
private final String alias;
|
||||
private final PendingContactState state;
|
||||
private final long timestamp;
|
||||
|
||||
public PendingContact(PendingContactId id, byte[] publicKey,
|
||||
public PendingContact(PendingContactId id, PublicKey publicKey,
|
||||
String alias, PendingContactState state, long timestamp) {
|
||||
this.id = id;
|
||||
this.publicKey = publicKey;
|
||||
@@ -27,7 +28,7 @@ public class PendingContact {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getPublicKey() {
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.briarproject.bramble.api.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a private key used for key agreement.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class AgreementPrivateKey extends Bytes implements PrivateKey {
|
||||
|
||||
public AgreementPrivateKey(byte[] encoded) {
|
||||
super(encoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyType() {
|
||||
return KEY_TYPE_AGREEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.briarproject.bramble.api.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a public key used for key agreement.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class AgreementPublicKey extends Bytes implements PublicKey {
|
||||
|
||||
public AgreementPublicKey(byte[] encoded) {
|
||||
super(encoded);
|
||||
if (encoded.length == 0 ||
|
||||
encoded.length > MAX_AGREEMENT_PUBLIC_KEY_BYTES) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyType() {
|
||||
return KEY_TYPE_AGREEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public interface CryptoComponent {
|
||||
* signature, to prevent it from being repurposed or colliding with a
|
||||
* signature created for another purpose
|
||||
*/
|
||||
byte[] sign(String label, byte[] toSign, byte[] privateKey)
|
||||
byte[] sign(String label, byte[] toSign, PrivateKey privateKey)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ public interface CryptoComponent {
|
||||
* @return true if the signature was valid, false otherwise.
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -7,11 +7,21 @@ public interface CryptoConstants {
|
||||
*/
|
||||
int MAX_AGREEMENT_PUBLIC_KEY_BYTES = 32;
|
||||
|
||||
/**
|
||||
* The key type for agreement key pairs.
|
||||
*/
|
||||
String KEY_TYPE_AGREEMENT = "Curve25519";
|
||||
|
||||
/**
|
||||
* The maximum length of a signature public key in bytes.
|
||||
*/
|
||||
int MAX_SIGNATURE_PUBLIC_KEY_BYTES = 32;
|
||||
|
||||
/**
|
||||
* The key type for signature key pairs.
|
||||
*/
|
||||
String KEY_TYPE_SIGNATURE = "Ed25519";
|
||||
|
||||
/**
|
||||
* The maximum length of a signature in bytes.
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,8 @@ public class KeyPair {
|
||||
private final PrivateKey privateKey;
|
||||
|
||||
public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
|
||||
if (!publicKey.getKeyType().equals(privateKey.getKeyType()))
|
||||
throw new IllegalArgumentException();
|
||||
this.publicKey = publicKey;
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@NotNullByDefault
|
||||
public interface PrivateKey {
|
||||
|
||||
/**
|
||||
* Returns the type of this key pair.
|
||||
*/
|
||||
String getKeyType();
|
||||
|
||||
/**
|
||||
* Returns the encoded representation of this key.
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@NotNullByDefault
|
||||
public interface PublicKey {
|
||||
|
||||
/**
|
||||
* Returns the type of this key pair.
|
||||
*/
|
||||
String getKeyType();
|
||||
|
||||
/**
|
||||
* Returns the encoded representation of this key.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.briarproject.bramble.api.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a public key used for signing.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class SignaturePrivateKey extends Bytes implements PrivateKey {
|
||||
|
||||
public SignaturePrivateKey(byte[] bytes) {
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyType() {
|
||||
return KEY_TYPE_SIGNATURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.briarproject.bramble.api.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_SIGNATURE_PUBLIC_KEY_BYTES;
|
||||
|
||||
/**
|
||||
* Type-safe wrapper for a public key used for verifying signatures.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class SignaturePublicKey extends Bytes implements PublicKey {
|
||||
|
||||
public SignaturePublicKey(byte[] encoded) {
|
||||
super(encoded);
|
||||
if (encoded.length == 0 ||
|
||||
encoded.length > MAX_SIGNATURE_PUBLIC_KEY_BYTES) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyType() {
|
||||
return KEY_TYPE_SIGNATURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
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.identity.Author;
|
||||
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.
|
||||
*/
|
||||
void setHandshakeKeyPair(Transaction txn, AuthorId local, byte[] publicKey,
|
||||
byte[] privateKey) throws DbException;
|
||||
void setHandshakeKeyPair(Transaction txn, AuthorId local,
|
||||
PublicKey publicKey, PrivateKey privateKey) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the reordering window for the given transport key set in the given
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package org.briarproject.bramble.api.identity;
|
||||
|
||||
import org.briarproject.bramble.api.Nameable;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
|
||||
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_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
||||
|
||||
/**
|
||||
* A pseudonym for a user.
|
||||
@@ -24,14 +25,14 @@ public class Author implements Nameable {
|
||||
private final AuthorId id;
|
||||
private final int formatVersion;
|
||||
private final String name;
|
||||
private final byte[] publicKey;
|
||||
private final PublicKey publicKey;
|
||||
|
||||
public Author(AuthorId id, int formatVersion, String name,
|
||||
byte[] publicKey) {
|
||||
int nameLength = StringUtils.toUtf8(name).length;
|
||||
PublicKey publicKey) {
|
||||
int nameLength = toUtf8(name).length;
|
||||
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)
|
||||
if (!publicKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
|
||||
throw new IllegalArgumentException();
|
||||
this.id = id;
|
||||
this.formatVersion = formatVersion;
|
||||
@@ -63,7 +64,7 @@ public class Author implements Nameable {
|
||||
/**
|
||||
* Returns the public key used to verify the pseudonym's signatures.
|
||||
*/
|
||||
public byte[] getPublicKey() {
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.api.identity;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
@@ -9,12 +10,12 @@ public interface AuthorFactory {
|
||||
* Creates an author with the current format version and the given name and
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
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 java.util.Arrays;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
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
|
||||
@NotNullByDefault
|
||||
@@ -15,15 +15,24 @@ public class Identity {
|
||||
|
||||
private final LocalAuthor localAuthor;
|
||||
@Nullable
|
||||
private final byte[] handshakePublicKey, handshakePrivateKey;
|
||||
private final PublicKey handshakePublicKey;
|
||||
@Nullable
|
||||
private final PrivateKey handshakePrivateKey;
|
||||
private final long created;
|
||||
|
||||
public Identity(LocalAuthor localAuthor,
|
||||
@Nullable byte[] handshakePublicKey,
|
||||
@Nullable byte[] handshakePrivateKey, long created) {
|
||||
@Nullable PublicKey handshakePublicKey,
|
||||
@Nullable PrivateKey handshakePrivateKey, long created) {
|
||||
if (handshakePublicKey != null) {
|
||||
int keyLength = handshakePublicKey.length;
|
||||
if (keyLength == 0 || keyLength > MAX_AGREEMENT_PUBLIC_KEY_BYTES)
|
||||
if (handshakePrivateKey == null)
|
||||
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();
|
||||
}
|
||||
this.localAuthor = localAuthor;
|
||||
@@ -57,7 +66,7 @@ public class Identity {
|
||||
* Returns the public key used for handshaking, or null if no key exists.
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] getHandshakePublicKey() {
|
||||
public PublicKey getHandshakePublicKey() {
|
||||
return handshakePublicKey;
|
||||
}
|
||||
|
||||
@@ -65,7 +74,7 @@ public class Identity {
|
||||
* Returns the private key used for handshaking, or null if no key exists.
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] getHandshakePrivateKey() {
|
||||
public PrivateKey getHandshakePrivateKey() {
|
||||
return handshakePrivateKey;
|
||||
}
|
||||
|
||||
@@ -76,21 +85,4 @@ public class Identity {
|
||||
public long getTimeCreated() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.api.identity;
|
||||
|
||||
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.db.DbException;
|
||||
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.
|
||||
* <p/>
|
||||
* 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;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
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 javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
|
||||
|
||||
/**
|
||||
* A pseudonym for the local user.
|
||||
*/
|
||||
@@ -11,18 +15,20 @@ import javax.annotation.concurrent.Immutable;
|
||||
@NotNullByDefault
|
||||
public class LocalAuthor extends Author {
|
||||
|
||||
private final byte[] privateKey;
|
||||
private final PrivateKey privateKey;
|
||||
|
||||
public LocalAuthor(AuthorId id, int formatVersion, String name,
|
||||
byte[] publicKey, byte[] privateKey) {
|
||||
PublicKey publicKey, PrivateKey privateKey) {
|
||||
super(id, formatVersion, name, publicKey);
|
||||
if (!privateKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
|
||||
throw new IllegalArgumentException();
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the private key used to generate the pseudonym's signatures.
|
||||
*/
|
||||
public byte[] getPrivateKey() {
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,13 @@ import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
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.SignaturePrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
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 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_SIGNATURE_PUBLIC_KEY_BYTES;
|
||||
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_PUBLIC_KEY_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.sync.ClientId.MAX_CLIENT_ID_LENGTH;
|
||||
@@ -101,10 +107,28 @@ public class TestUtils {
|
||||
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() {
|
||||
LocalAuthor localAuthor = getLocalAuthor();
|
||||
byte[] handshakePub = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||
byte[] handshakePriv = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||
PublicKey handshakePub = getAgreementPublicKey();
|
||||
PrivateKey handshakePriv = getAgreementPrivateKey();
|
||||
return new Identity(localAuthor, handshakePub, handshakePriv,
|
||||
timestamp);
|
||||
}
|
||||
@@ -113,8 +137,8 @@ public class TestUtils {
|
||||
AuthorId id = new AuthorId(getRandomId());
|
||||
int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH);
|
||||
String name = getRandomString(nameLength);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
PublicKey publicKey = getSignaturePublicKey();
|
||||
PrivateKey privateKey = getSignaturePrivateKey();
|
||||
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey);
|
||||
}
|
||||
|
||||
@@ -122,7 +146,7 @@ public class TestUtils {
|
||||
AuthorId id = new AuthorId(getRandomId());
|
||||
int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH);
|
||||
String name = getRandomString(nameLength);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
PublicKey publicKey = getSignaturePublicKey();
|
||||
return new Author(id, FORMAT_VERSION, name, publicKey);
|
||||
}
|
||||
|
||||
@@ -155,7 +179,7 @@ public class TestUtils {
|
||||
|
||||
public static PendingContact getPendingContact(int nameLength) {
|
||||
PendingContactId id = new PendingContactId(getRandomId());
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
PublicKey publicKey = getAgreementPublicKey();
|
||||
String alias = getRandomString(nameLength);
|
||||
return new PendingContact(id, publicKey, alias, WAITING_FOR_CONNECTION,
|
||||
timestamp);
|
||||
@@ -179,7 +203,7 @@ public class TestUtils {
|
||||
boolean verified) {
|
||||
return new Contact(c, remote, local,
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), verified);
|
||||
getAgreementPublicKey(), verified);
|
||||
}
|
||||
|
||||
public static double getMedian(Collection<? extends Number> samples) {
|
||||
|
||||
@@ -3,6 +3,9 @@ package org.briarproject.bramble.client;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
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.BdfList;
|
||||
import org.briarproject.bramble.api.data.BdfReader;
|
||||
@@ -305,14 +308,15 @@ class ClientHelperImpl implements ClientHelper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign(String label, BdfList toSign, byte[] privateKey)
|
||||
public byte[] sign(String label, BdfList toSign, PrivateKey privateKey)
|
||||
throws FormatException, GeneralSecurityException {
|
||||
return crypto.sign(label, toByteArray(toSign), privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
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),
|
||||
publicKey)) {
|
||||
throw new GeneralSecurityException("Invalid signature");
|
||||
@@ -327,11 +331,29 @@ class ClientHelperImpl implements ClientHelper {
|
||||
if (formatVersion != FORMAT_VERSION) throw new FormatException();
|
||||
String name = author.getString(1);
|
||||
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = author.getRaw(2);
|
||||
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] publicKeyBytes = author.getRaw(2);
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey parseAndValidateAgreementPublicKey(byte[] publicKeyBytes)
|
||||
throws FormatException {
|
||||
KeyParser parser = crypto.getAgreementKeyParser();
|
||||
try {
|
||||
return parser.parsePublicKey(publicKeyBytes);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportProperties parseAndValidateTransportProperties(
|
||||
BdfDictionary properties) throws FormatException {
|
||||
|
||||
@@ -39,8 +39,8 @@ class PendingContactFactoryImpl implements PendingContactFactory {
|
||||
PublicKey publicKey = parseHandshakeLink(link);
|
||||
PendingContactId id = getPendingContactId(publicKey);
|
||||
long timestamp = clock.currentTimeMillis();
|
||||
return new PendingContact(id, publicKey.getEncoded(), alias,
|
||||
WAITING_FOR_CONNECTION, timestamp);
|
||||
return new PendingContact(id, publicKey, alias, WAITING_FOR_CONNECTION,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
private PublicKey parseHandshakeLink(String link) throws FormatException {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||
import org.briarproject.bramble.api.crypto.KeyParser;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
@@ -7,21 +9,24 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class Curve25519KeyParser implements KeyParser {
|
||||
class AgreementKeyParser implements KeyParser {
|
||||
|
||||
@Override
|
||||
public PublicKey parsePublicKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException {
|
||||
if (encodedKey.length != 32) throw new GeneralSecurityException();
|
||||
return new Curve25519PublicKey(encodedKey);
|
||||
return new AgreementPublicKey(encodedKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey parsePrivateKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException {
|
||||
if (encodedKey.length != 32) throw new GeneralSecurityException();
|
||||
return new Curve25519PrivateKey(clamp(encodedKey));
|
||||
return new AgreementPrivateKey(clamp(encodedKey));
|
||||
}
|
||||
|
||||
static byte[] clamp(byte[] b) {
|
||||
@@ -4,12 +4,16 @@ import net.i2p.crypto.eddsa.EdDSAPrivateKey;
|
||||
import net.i2p.crypto.eddsa.EdDSAPublicKey;
|
||||
import net.i2p.crypto.eddsa.KeyPairGenerator;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
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.PublicKey;
|
||||
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.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
||||
import org.briarproject.bramble.util.ByteUtils;
|
||||
@@ -31,6 +35,8 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
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_SIGNATURE;
|
||||
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.now;
|
||||
@@ -80,8 +86,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
signatureKeyPairGenerator = new KeyPairGenerator();
|
||||
signatureKeyPairGenerator.initialize(SIGNATURE_KEY_PAIR_BITS,
|
||||
secureRandom);
|
||||
agreementKeyParser = new Curve25519KeyParser();
|
||||
signatureKeyParser = new EdKeyParser();
|
||||
agreementKeyParser = new AgreementKeyParser();
|
||||
signatureKeyParser = new SignatureKeyParser();
|
||||
messageEncrypter = new MessageEncrypter(secureRandom);
|
||||
}
|
||||
|
||||
@@ -125,9 +131,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
// Package access for testing
|
||||
byte[] performRawKeyAgreement(PrivateKey priv, PublicKey pub)
|
||||
throws GeneralSecurityException {
|
||||
if (!(priv instanceof Curve25519PrivateKey))
|
||||
if (!priv.getKeyType().equals(KEY_TYPE_AGREEMENT))
|
||||
throw new IllegalArgumentException();
|
||||
if (!(pub instanceof Curve25519PublicKey))
|
||||
if (!pub.getKeyType().equals(KEY_TYPE_AGREEMENT))
|
||||
throw new IllegalArgumentException();
|
||||
long start = now();
|
||||
byte[] secret = curve25519.calculateAgreement(pub.getEncoded(),
|
||||
@@ -143,8 +149,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
@Override
|
||||
public KeyPair generateAgreementKeyPair() {
|
||||
Curve25519KeyPair keyPair = curve25519.generateKeyPair();
|
||||
PublicKey pub = new Curve25519PublicKey(keyPair.getPublicKey());
|
||||
PrivateKey priv = new Curve25519PrivateKey(keyPair.getPrivateKey());
|
||||
PublicKey pub = new AgreementPublicKey(keyPair.getPublicKey());
|
||||
PrivateKey priv = new AgreementPrivateKey(keyPair.getPrivateKey());
|
||||
return new KeyPair(pub, priv);
|
||||
}
|
||||
|
||||
@@ -158,9 +164,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
java.security.KeyPair keyPair =
|
||||
signatureKeyPairGenerator.generateKeyPair();
|
||||
EdDSAPublicKey edPublicKey = (EdDSAPublicKey) keyPair.getPublic();
|
||||
PublicKey publicKey = new EdPublicKey(edPublicKey.getAbyte());
|
||||
PublicKey publicKey = new SignaturePublicKey(edPublicKey.getAbyte());
|
||||
EdDSAPrivateKey edPrivateKey = (EdDSAPrivateKey) keyPair.getPrivate();
|
||||
PrivateKey privateKey = new EdPrivateKey(edPrivateKey.getSeed());
|
||||
PrivateKey privateKey = new SignaturePrivateKey(edPrivateKey.getSeed());
|
||||
return new KeyPair(publicKey, privateKey);
|
||||
}
|
||||
|
||||
@@ -195,21 +201,22 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign(String label, byte[] toSign, byte[] privateKey)
|
||||
public byte[] sign(String label, byte[] toSign, PrivateKey privateKey)
|
||||
throws GeneralSecurityException {
|
||||
PrivateKey key = signatureKeyParser.parsePrivateKey(privateKey);
|
||||
Signature sig = new EdSignature();
|
||||
sig.initSign(key);
|
||||
sig.initSign(privateKey);
|
||||
updateSignature(sig, label, toSign);
|
||||
return sig.sign();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifySignature(byte[] signature, String label,
|
||||
byte[] signed, byte[] publicKey) throws GeneralSecurityException {
|
||||
PublicKey key = signatureKeyParser.parsePublicKey(publicKey);
|
||||
byte[] signed, PublicKey publicKey)
|
||||
throws GeneralSecurityException {
|
||||
if (!publicKey.getKeyType().equals(KEY_TYPE_SIGNATURE))
|
||||
throw new IllegalArgumentException();
|
||||
Signature sig = new EdSignature();
|
||||
sig.initVerify(key);
|
||||
sig.initVerify(publicKey);
|
||||
updateSignature(sig, label, signed);
|
||||
return sig.verify(signature);
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
class Curve25519PrivateKey extends Bytes implements PrivateKey {
|
||||
|
||||
Curve25519PrivateKey(byte[] bytes) {
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
class Curve25519PublicKey extends Bytes implements PublicKey {
|
||||
|
||||
Curve25519PublicKey(byte[] bytes) {
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
class EdPrivateKey extends Bytes implements PrivateKey {
|
||||
|
||||
EdPrivateKey(byte[] bytes) {
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
class EdPublicKey extends Bytes implements PublicKey {
|
||||
|
||||
EdPublicKey(byte[] bytes) {
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
|
||||
import static net.i2p.crypto.eddsa.EdDSAEngine.SIGNATURE_ALGORITHM;
|
||||
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_SIGNATURE;
|
||||
|
||||
@NotNullByDefault
|
||||
class EdSignature implements Signature {
|
||||
@@ -39,7 +40,7 @@ class EdSignature implements Signature {
|
||||
|
||||
@Override
|
||||
public void initSign(PrivateKey k) throws GeneralSecurityException {
|
||||
if (!(k instanceof EdPrivateKey))
|
||||
if (!k.getKeyType().equals(KEY_TYPE_SIGNATURE))
|
||||
throw new IllegalArgumentException();
|
||||
EdDSAPrivateKey privateKey = new EdDSAPrivateKey(
|
||||
new EdDSAPrivateKeySpec(k.getEncoded(), CURVE_SPEC));
|
||||
@@ -48,7 +49,7 @@ class EdSignature implements Signature {
|
||||
|
||||
@Override
|
||||
public void initVerify(PublicKey k) throws GeneralSecurityException {
|
||||
if (!(k instanceof EdPublicKey))
|
||||
if (!k.getKeyType().equals(KEY_TYPE_SIGNATURE))
|
||||
throw new IllegalArgumentException();
|
||||
EdDSAPublicKey publicKey = new EdDSAPublicKey(
|
||||
new EdDSAPublicKeySpec(k.getEncoded(), CURVE_SPEC));
|
||||
|
||||
@@ -49,6 +49,7 @@ import javax.annotation.concurrent.Immutable;
|
||||
@NotNullByDefault
|
||||
public class MessageEncrypter {
|
||||
|
||||
private static final String KEY_TYPE = "SEC1_brainpoolp512r1";
|
||||
private static final ECDomainParameters PARAMETERS;
|
||||
private static final int MESSAGE_KEY_BITS = 512;
|
||||
private static final int MAC_KEY_BITS = 256;
|
||||
@@ -69,7 +70,7 @@ public class MessageEncrypter {
|
||||
MessageEncrypter(SecureRandom random) {
|
||||
generator = new ECKeyPairGenerator();
|
||||
generator.init(new ECKeyGenerationParameters(PARAMETERS, random));
|
||||
parser = new Sec1KeyParser(PARAMETERS, MESSAGE_KEY_BITS);
|
||||
parser = new Sec1KeyParser(KEY_TYPE, PARAMETERS, MESSAGE_KEY_BITS);
|
||||
KeyEncoder encoder = new PublicKeyEncoder();
|
||||
ephemeralGenerator = new EphemeralKeyPairGenerator(generator, encoder);
|
||||
ephemeralParser = new PublicKeyParser(PARAMETERS);
|
||||
@@ -80,11 +81,11 @@ public class MessageEncrypter {
|
||||
// Return a wrapper that uses the SEC 1 encoding
|
||||
ECPublicKeyParameters ecPublicKey =
|
||||
(ECPublicKeyParameters) keyPair.getPublic();
|
||||
PublicKey publicKey = new Sec1PublicKey(ecPublicKey);
|
||||
PublicKey publicKey = new Sec1PublicKey(KEY_TYPE, ecPublicKey);
|
||||
ECPrivateKeyParameters ecPrivateKey =
|
||||
(ECPrivateKeyParameters) keyPair.getPrivate();
|
||||
PrivateKey privateKey =
|
||||
new Sec1PrivateKey(ecPrivateKey, MESSAGE_KEY_BITS);
|
||||
new Sec1PrivateKey(KEY_TYPE, ecPrivateKey, MESSAGE_KEY_BITS);
|
||||
return new KeyPair(publicKey, privateKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,13 @@ class Sec1KeyParser implements KeyParser {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(Sec1KeyParser.class.getName());
|
||||
|
||||
private final String keyType;
|
||||
private final ECDomainParameters params;
|
||||
private final BigInteger modulus;
|
||||
private final int keyBits, bytesPerInt, publicKeyBytes, privateKeyBytes;
|
||||
|
||||
Sec1KeyParser(ECDomainParameters params, int keyBits) {
|
||||
Sec1KeyParser(String keyType, ECDomainParameters params, int keyBits) {
|
||||
this.keyType = keyType;
|
||||
this.params = params;
|
||||
this.keyBits = keyBits;
|
||||
modulus = ((ECCurve.Fp) params.getCurve()).getQ();
|
||||
@@ -80,7 +82,7 @@ class Sec1KeyParser implements KeyParser {
|
||||
throw new GeneralSecurityException();
|
||||
// Construct a public key from the point (x, y) and the params
|
||||
ECPublicKeyParameters k = new ECPublicKeyParameters(pub, params);
|
||||
PublicKey p = new Sec1PublicKey(k);
|
||||
PublicKey p = new Sec1PublicKey(keyType, k);
|
||||
logDuration(LOG, "Parsing public key", start);
|
||||
return p;
|
||||
}
|
||||
@@ -97,7 +99,7 @@ class Sec1KeyParser implements KeyParser {
|
||||
throw new GeneralSecurityException();
|
||||
// Construct a private key from the private value and the params
|
||||
ECPrivateKeyParameters k = new ECPrivateKeyParameters(d, params);
|
||||
PrivateKey p = new Sec1PrivateKey(k, keyBits);
|
||||
PrivateKey p = new Sec1PrivateKey(keyType, k, keyBits);
|
||||
logDuration(LOG, "Parsing private key", start);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -10,14 +10,21 @@ import javax.annotation.concurrent.Immutable;
|
||||
@NotNullByDefault
|
||||
class Sec1PrivateKey implements PrivateKey {
|
||||
|
||||
private final String keyType;
|
||||
private final ECPrivateKeyParameters key;
|
||||
private final int bytesPerInt;
|
||||
|
||||
Sec1PrivateKey(ECPrivateKeyParameters key, int keyBits) {
|
||||
Sec1PrivateKey(String keyType, ECPrivateKeyParameters key, int keyBits) {
|
||||
this.keyType = keyType;
|
||||
this.key = key;
|
||||
bytesPerInt = (keyBits + 7) / 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
byte[] encodedKey = new byte[bytesPerInt];
|
||||
|
||||
@@ -15,12 +15,19 @@ import javax.annotation.concurrent.Immutable;
|
||||
@NotNullByDefault
|
||||
class Sec1PublicKey implements PublicKey {
|
||||
|
||||
private final String keyType;
|
||||
private final ECPublicKeyParameters key;
|
||||
|
||||
Sec1PublicKey(ECPublicKeyParameters key) {
|
||||
Sec1PublicKey(String keyType, ECPublicKeyParameters key) {
|
||||
this.keyType = keyType;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return key.getQ().getEncoded(false);
|
||||
|
||||
@@ -3,24 +3,29 @@ package org.briarproject.bramble.crypto;
|
||||
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.crypto.SignaturePrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class EdKeyParser implements KeyParser {
|
||||
class SignatureKeyParser implements KeyParser {
|
||||
|
||||
@Override
|
||||
public PublicKey parsePublicKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException {
|
||||
if (encodedKey.length != 32) throw new GeneralSecurityException();
|
||||
return new EdPublicKey(encodedKey);
|
||||
return new SignaturePublicKey(encodedKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey parsePrivateKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException {
|
||||
if (encodedKey.length != 32) throw new GeneralSecurityException();
|
||||
return new EdPrivateKey(encodedKey);
|
||||
return new SignaturePrivateKey(encodedKey);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
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.db.DataTooNewException;
|
||||
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.
|
||||
*/
|
||||
void setHandshakeKeyPair(T txn, AuthorId local, byte[] publicKey,
|
||||
byte[] privateKey) throws DbException;
|
||||
void setHandshakeKeyPair(T txn, AuthorId local, PublicKey publicKey,
|
||||
PrivateKey privateKey) throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given message as shared.
|
||||
|
||||
@@ -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.ContactRemovedEvent;
|
||||
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.db.CommitAction;
|
||||
import org.briarproject.bramble.api.db.CommitAction.Visitor;
|
||||
@@ -1037,7 +1039,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
|
||||
@Override
|
||||
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();
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsIdentity(txn, local))
|
||||
|
||||
@@ -5,7 +5,13 @@ import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
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.SignaturePrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
|
||||
import org.briarproject.bramble.api.db.DataTooNewException;
|
||||
import org.briarproject.bramble.api.db.DataTooOldException;
|
||||
import org.briarproject.bramble.api.db.DbClosedException;
|
||||
@@ -677,7 +683,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setBytes(1, remote.getId().getBytes());
|
||||
ps.setInt(2, remote.getFormatVersion());
|
||||
ps.setString(3, remote.getName());
|
||||
ps.setBytes(4, remote.getPublicKey());
|
||||
ps.setBytes(4, remote.getPublicKey().getEncoded());
|
||||
ps.setBytes(5, local.getBytes());
|
||||
ps.setBoolean(6, verified);
|
||||
int affected = ps.executeUpdate();
|
||||
@@ -887,12 +893,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setBytes(1, local.getId().getBytes());
|
||||
ps.setInt(2, local.getFormatVersion());
|
||||
ps.setString(3, local.getName());
|
||||
ps.setBytes(4, local.getPublicKey());
|
||||
ps.setBytes(5, local.getPrivateKey());
|
||||
ps.setBytes(4, local.getPublicKey().getEncoded());
|
||||
ps.setBytes(5, local.getPrivateKey().getEncoded());
|
||||
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);
|
||||
else ps.setBytes(7, i.getHandshakePrivateKey());
|
||||
else ps.setBytes(7, i.getHandshakePrivateKey().getEncoded());
|
||||
ps.setLong(8, i.getTimeCreated());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected != 1) throw new DbStateException();
|
||||
@@ -1068,7 +1074,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " VALUES (?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, p.getId().getBytes());
|
||||
ps.setBytes(2, p.getPublicKey());
|
||||
ps.setBytes(2, p.getPublicKey().getEncoded());
|
||||
ps.setString(3, p.getAlias());
|
||||
ps.setInt(4, p.getState().getValue());
|
||||
ps.setLong(5, p.getTimestamp());
|
||||
@@ -1444,14 +1450,16 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
int formatVersion = rs.getInt(2);
|
||||
String name = rs.getString(3);
|
||||
String alias = rs.getString(4);
|
||||
byte[] publicKey = rs.getBytes(5);
|
||||
byte[] handshakePublicKey = rs.getBytes(6);
|
||||
PublicKey publicKey = new SignaturePublicKey(rs.getBytes(5));
|
||||
byte[] handshakePub = rs.getBytes(6);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(7));
|
||||
boolean verified = rs.getBoolean(8);
|
||||
rs.close();
|
||||
ps.close();
|
||||
Author author =
|
||||
new Author(authorId, formatVersion, name, publicKey);
|
||||
PublicKey handshakePublicKey = handshakePub == null ?
|
||||
null : new AgreementPublicKey(handshakePub);
|
||||
return new Contact(c, author, localAuthorId, alias,
|
||||
handshakePublicKey, verified);
|
||||
} catch (SQLException e) {
|
||||
@@ -1479,12 +1487,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
int formatVersion = rs.getInt(3);
|
||||
String name = rs.getString(4);
|
||||
String alias = rs.getString(5);
|
||||
byte[] publicKey = rs.getBytes(6);
|
||||
byte[] handshakePublicKey = rs.getBytes(7);
|
||||
PublicKey publicKey = new SignaturePublicKey(rs.getBytes(6));
|
||||
byte[] handshakePub = rs.getBytes(7);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(8));
|
||||
boolean verified = rs.getBoolean(9);
|
||||
Author author =
|
||||
new Author(authorId, formatVersion, name, publicKey);
|
||||
PublicKey handshakePublicKey = handshakePub == null ?
|
||||
null : new AgreementPublicKey(handshakePub);
|
||||
contacts.add(new Contact(contactId, author, localAuthorId,
|
||||
alias, handshakePublicKey, verified));
|
||||
}
|
||||
@@ -1540,12 +1550,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
int formatVersion = rs.getInt(2);
|
||||
String name = rs.getString(3);
|
||||
String alias = rs.getString(4);
|
||||
byte[] publicKey = rs.getBytes(5);
|
||||
byte[] handshakePublicKey = rs.getBytes(6);
|
||||
PublicKey publicKey = new SignaturePublicKey(rs.getBytes(5));
|
||||
byte[] handshakePub = rs.getBytes(6);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(7));
|
||||
boolean verified = rs.getBoolean(8);
|
||||
Author author =
|
||||
new Author(remote, formatVersion, name, publicKey);
|
||||
PublicKey handshakePublicKey = handshakePub == null ?
|
||||
null : new AgreementPublicKey(handshakePub);
|
||||
contacts.add(new Contact(contactId, author, localAuthorId,
|
||||
alias, handshakePublicKey, verified));
|
||||
}
|
||||
@@ -1756,16 +1768,20 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
if (!rs.next()) throw new DbStateException();
|
||||
int formatVersion = rs.getInt(1);
|
||||
String name = rs.getString(2);
|
||||
byte[] publicKey = rs.getBytes(3);
|
||||
byte[] privateKey = rs.getBytes(4);
|
||||
byte[] handshakePublicKey = rs.getBytes(5);
|
||||
byte[] handshakePrivateKey = rs.getBytes(6);
|
||||
PublicKey publicKey = new SignaturePublicKey(rs.getBytes(3));
|
||||
PrivateKey privateKey = new SignaturePrivateKey(rs.getBytes(4));
|
||||
byte[] handshakePub = rs.getBytes(5);
|
||||
byte[] handshakePriv = rs.getBytes(6);
|
||||
long created = rs.getLong(7);
|
||||
if (rs.next()) throw new DbStateException();
|
||||
rs.close();
|
||||
ps.close();
|
||||
LocalAuthor local = new LocalAuthor(a, formatVersion, name,
|
||||
publicKey, privateKey);
|
||||
PublicKey handshakePublicKey = handshakePub == null ?
|
||||
null : new AgreementPublicKey(handshakePub);
|
||||
PrivateKey handshakePrivateKey = handshakePriv == null ?
|
||||
null : new AgreementPrivateKey(handshakePriv);
|
||||
return new Identity(local, handshakePublicKey, handshakePrivateKey,
|
||||
created);
|
||||
} catch (SQLException e) {
|
||||
@@ -1792,13 +1808,17 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
AuthorId authorId = new AuthorId(rs.getBytes(1));
|
||||
int formatVersion = rs.getInt(2);
|
||||
String name = rs.getString(3);
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
byte[] privateKey = rs.getBytes(5);
|
||||
byte[] handshakePublicKey = rs.getBytes(6);
|
||||
byte[] handshakePrivateKey = rs.getBytes(7);
|
||||
PublicKey publicKey = new SignaturePublicKey(rs.getBytes(4));
|
||||
PrivateKey privateKey = new SignaturePrivateKey(rs.getBytes(5));
|
||||
byte[] handshakePub = rs.getBytes(6);
|
||||
byte[] handshakePriv = rs.getBytes(7);
|
||||
long created = rs.getLong(8);
|
||||
LocalAuthor local = new LocalAuthor(authorId, formatVersion,
|
||||
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,
|
||||
handshakePrivateKey, created));
|
||||
}
|
||||
@@ -2395,7 +2415,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
List<PendingContact> pendingContacts = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
PendingContactId id = new PendingContactId(rs.getBytes(1));
|
||||
byte[] publicKey = rs.getBytes(2);
|
||||
PublicKey publicKey = new AgreementPublicKey(rs.getBytes(2));
|
||||
String alias = rs.getString(3);
|
||||
PendingContactState state =
|
||||
PendingContactState.fromValue(rs.getInt(4));
|
||||
@@ -3182,15 +3202,15 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
@Override
|
||||
public void setHandshakeKeyPair(Connection txn, AuthorId local,
|
||||
byte[] publicKey, byte[] privateKey) throws DbException {
|
||||
PublicKey publicKey, PrivateKey privateKey) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "UPDATE localAuthors"
|
||||
+ " SET handshakePublicKey = ?, handshakePrivateKey = ?"
|
||||
+ " WHERE authorId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, publicKey);
|
||||
ps.setBytes(2, privateKey);
|
||||
ps.setBytes(1, publicKey.getEncoded());
|
||||
ps.setBytes(2, privateKey.getEncoded());
|
||||
ps.setBytes(3, local.getBytes());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||
|
||||
@@ -2,13 +2,13 @@ package org.briarproject.bramble.identity;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
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.AuthorFactory;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
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.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.AuthorId.LABEL;
|
||||
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
|
||||
@NotNullByDefault
|
||||
@@ -29,13 +31,13 @@ class AuthorFactoryImpl implements AuthorFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Author createAuthor(String name, byte[] publicKey) {
|
||||
public Author createAuthor(String name, PublicKey publicKey) {
|
||||
return createAuthor(FORMAT_VERSION, name, publicKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Author createAuthor(int formatVersion, String name,
|
||||
byte[] publicKey) {
|
||||
PublicKey publicKey) {
|
||||
AuthorId id = getId(formatVersion, name, publicKey);
|
||||
return new Author(id, formatVersion, name, publicKey);
|
||||
}
|
||||
@@ -43,16 +45,17 @@ class AuthorFactoryImpl implements AuthorFactory {
|
||||
@Override
|
||||
public LocalAuthor createLocalAuthor(String name) {
|
||||
KeyPair signatureKeyPair = crypto.generateSignatureKeyPair();
|
||||
byte[] publicKey = signatureKeyPair.getPublic().getEncoded();
|
||||
byte[] privateKey = signatureKeyPair.getPrivate().getEncoded();
|
||||
PublicKey publicKey = signatureKeyPair.getPublic();
|
||||
PrivateKey privateKey = signatureKeyPair.getPrivate();
|
||||
AuthorId id = getId(FORMAT_VERSION, name, publicKey);
|
||||
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];
|
||||
ByteUtils.writeUint32(formatVersion, formatVersionBytes, 0);
|
||||
writeUint32(formatVersion, formatVersionBytes, 0);
|
||||
return new AuthorId(crypto.hash(LABEL, formatVersionBytes,
|
||||
StringUtils.toUtf8(name), publicKey));
|
||||
toUtf8(name), publicKey.getEncoded()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.briarproject.bramble.identity;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
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.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
@@ -73,8 +75,8 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
|
||||
long start = now();
|
||||
LocalAuthor localAuthor = authorFactory.createLocalAuthor(name);
|
||||
KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair();
|
||||
byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded();
|
||||
byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded();
|
||||
PublicKey handshakePub = handshakeKeyPair.getPublic();
|
||||
PrivateKey handshakePriv = handshakeKeyPair.getPrivate();
|
||||
logDuration(LOG, "Creating identity", start);
|
||||
return new Identity(localAuthor, handshakePub, handshakePriv,
|
||||
clock.currentTimeMillis());
|
||||
@@ -98,9 +100,9 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
|
||||
} else if (shouldStoreKeys) {
|
||||
// Handshake keys were generated when loading the identity -
|
||||
// store them
|
||||
byte[] handshakePub =
|
||||
PublicKey handshakePub =
|
||||
requireNonNull(cached.getHandshakePublicKey());
|
||||
byte[] handshakePriv =
|
||||
PrivateKey handshakePriv =
|
||||
requireNonNull(cached.getHandshakePrivateKey());
|
||||
db.setHandshakeKeyPair(txn, cached.getId(), handshakePub,
|
||||
handshakePriv);
|
||||
@@ -122,12 +124,12 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[][] getHandshakeKeys(Transaction txn) throws DbException {
|
||||
public KeyPair getHandshakeKeys(Transaction txn) throws DbException {
|
||||
Identity cached = getCachedIdentity(txn);
|
||||
return new byte[][] {
|
||||
cached.getHandshakePublicKey(),
|
||||
cached.getHandshakePrivateKey()
|
||||
};
|
||||
PublicKey handshakePub = requireNonNull(cached.getHandshakePublicKey());
|
||||
PrivateKey handshakePriv =
|
||||
requireNonNull(cached.getHandshakePrivateKey());
|
||||
return new KeyPair(handshakePub, handshakePriv);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,8 +161,8 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
|
||||
LOG.info("Identity loaded");
|
||||
if (i.hasHandshakeKeyPair()) return i;
|
||||
KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair();
|
||||
byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded();
|
||||
byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded();
|
||||
PublicKey handshakePub = handshakeKeyPair.getPublic();
|
||||
PrivateKey handshakePriv = handshakeKeyPair.getPrivate();
|
||||
LOG.info("Handshake key pair generated");
|
||||
shouldStoreKeys = true;
|
||||
return new Identity(i.getLocalAuthor(), handshakePub, handshakePriv,
|
||||
|
||||
@@ -3,6 +3,9 @@ package org.briarproject.bramble.client;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
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.BdfEntry;
|
||||
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.getRandomBytes;
|
||||
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.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -66,6 +71,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
context.mock(CryptoComponent.class);
|
||||
private final AuthorFactory authorFactory =
|
||||
context.mock(AuthorFactory.class);
|
||||
private final KeyParser keyParser = context.mock(KeyParser.class);
|
||||
|
||||
private final GroupId groupId = new GroupId(getRandomId());
|
||||
private final BdfDictionary dictionary = new BdfDictionary();
|
||||
@@ -262,24 +268,25 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testSign() throws Exception {
|
||||
byte[] privateKey = getRandomBytes(42);
|
||||
byte[] signed = getRandomBytes(42);
|
||||
PrivateKey privateKey = getSignaturePrivateKey();
|
||||
byte[] signature = getRandomBytes(42);
|
||||
|
||||
byte[] bytes = expectToByteArray(list);
|
||||
context.checking(new Expectations() {{
|
||||
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();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifySignature() throws Exception {
|
||||
byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(42);
|
||||
byte[] signed = expectToByteArray(list);
|
||||
PublicKey publicKey = getSignaturePublicKey();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(cryptoComponent).verifySignature(signature, label, signed,
|
||||
@@ -294,8 +301,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testVerifyWrongSignature() throws Exception {
|
||||
byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(42);
|
||||
byte[] signed = expectToByteArray(list);
|
||||
PublicKey publicKey = getSignaturePublicKey();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(cryptoComponent).verifySignature(signature, label, signed,
|
||||
@@ -315,6 +322,10 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testParsesAndEncodesAuthor() throws Exception {
|
||||
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(),
|
||||
author.getName(), author.getPublicKey());
|
||||
will(returnValue(author));
|
||||
@@ -329,10 +340,14 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList authorList = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
author.getPublicKey().getEncoded()
|
||||
);
|
||||
|
||||
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(),
|
||||
author.getName(), author.getPublicKey());
|
||||
will(returnValue(author));
|
||||
@@ -355,7 +370,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
author.getPublicKey(),
|
||||
author.getPublicKey().getEncoded(),
|
||||
"foo"
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
@@ -366,7 +381,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
null,
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
author.getPublicKey().getEncoded()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
@@ -377,7 +392,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
"foo",
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
author.getPublicKey().getEncoded()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
@@ -387,7 +402,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion() + 1,
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
author.getPublicKey().getEncoded()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
@@ -397,7 +412,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
"",
|
||||
author.getPublicKey()
|
||||
author.getPublicKey().getEncoded()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
@@ -407,7 +422,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1),
|
||||
author.getPublicKey()
|
||||
author.getPublicKey().getEncoded()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
@@ -417,7 +432,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
null,
|
||||
author.getPublicKey()
|
||||
author.getPublicKey().getEncoded()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
@@ -472,6 +487,24 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
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 {
|
||||
BdfWriter bdfWriter = context.mock(BdfWriter.class);
|
||||
|
||||
|
||||
@@ -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.PendingContactState.WAITING_FOR_CONNECTION;
|
||||
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.util.StringUtils.getRandomString;
|
||||
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 Clock clock = context.mock(Clock.class);
|
||||
private final KeyParser keyParser = context.mock(KeyParser.class);
|
||||
private final PublicKey publicKey = context.mock(PublicKey.class);
|
||||
|
||||
private final PendingContactFactory pendingContactFactory =
|
||||
new PendingContactFactoryImpl(crypto, clock);
|
||||
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 long timestamp = System.currentTimeMillis();
|
||||
|
||||
@@ -64,7 +63,7 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
oneOf(keyParser).parsePublicKey(with(equal(publicKeyBytes)));
|
||||
oneOf(keyParser).parsePublicKey(publicKey.getEncoded());
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
}});
|
||||
|
||||
@@ -95,11 +94,9 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
oneOf(keyParser).parsePublicKey(with(equal(publicKeyBytes)));
|
||||
oneOf(keyParser).parsePublicKey(publicKey.getEncoded());
|
||||
will(returnValue(publicKey));
|
||||
allowing(publicKey).getEncoded();
|
||||
will(returnValue(publicKeyBytes));
|
||||
oneOf(crypto).hash(ID_LABEL, publicKeyBytes);
|
||||
oneOf(crypto).hash(ID_LABEL, publicKey.getEncoded());
|
||||
will(returnValue(idBytes));
|
||||
oneOf(clock).currentTimeMillis();
|
||||
will(returnValue(timestamp));
|
||||
@@ -108,7 +105,8 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
|
||||
PendingContact p =
|
||||
pendingContactFactory.createPendingContact(link, alias);
|
||||
assertArrayEquals(idBytes, p.getId().getBytes());
|
||||
assertArrayEquals(publicKeyBytes, p.getPublicKey());
|
||||
assertArrayEquals(publicKey.getEncoded(),
|
||||
p.getPublicKey().getEncoded());
|
||||
assertEquals(alias, p.getAlias());
|
||||
assertEquals(WAITING_FOR_CONNECTION, p.getState());
|
||||
assertEquals(timestamp, p.getTimestamp());
|
||||
@@ -121,6 +119,7 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
|
||||
private String encodeLink(int formatVersion) {
|
||||
byte[] rawLink = new byte[RAW_LINK_BYTES];
|
||||
rawLink[0] = (byte) formatVersion;
|
||||
byte[] publicKeyBytes = publicKey.getEncoded();
|
||||
arraycopy(publicKeyBytes, 0, rawLink, 1, publicKeyBytes.length);
|
||||
String base32 = Base32.encode(rawLink).toLowerCase();
|
||||
assertEquals(BASE32_LINK_BYTES, base32.length());
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
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.SignaturePublicKey;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
@@ -137,14 +141,14 @@ public class EdSignatureTest extends SignatureTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] sign(String label, byte[] toSign, byte[] privateKey)
|
||||
protected byte[] sign(String label, byte[] toSign, PrivateKey privateKey)
|
||||
throws GeneralSecurityException {
|
||||
return crypto.sign(label, toSign, privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verify(byte[] signature, String label, byte[] signed,
|
||||
byte[] publicKey) throws GeneralSecurityException {
|
||||
PublicKey publicKey) throws GeneralSecurityException {
|
||||
return crypto.verifySignature(signature, label, signed, publicKey);
|
||||
}
|
||||
|
||||
@@ -157,11 +161,11 @@ public class EdSignatureTest extends SignatureTest {
|
||||
byte[] signatureBytes = fromHexString(vector[3]);
|
||||
|
||||
EdSignature signature = new EdSignature();
|
||||
signature.initSign(new EdPrivateKey(privateKeyBytes));
|
||||
signature.initSign(new SignaturePrivateKey(privateKeyBytes));
|
||||
signature.update(messageBytes);
|
||||
assertArrayEquals(signatureBytes, signature.sign());
|
||||
|
||||
signature.initVerify(new EdPublicKey(publicKeyBytes));
|
||||
signature.initVerify(new SignaturePublicKey(publicKeyBytes));
|
||||
signature.update(messageBytes);
|
||||
assertTrue(signature.verify(signatureBytes));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
@@ -58,18 +59,18 @@ public class KeyAgreementTest extends BrambleTestCase {
|
||||
@Test(expected = GeneralSecurityException.class)
|
||||
public void testRejectsInvalidPublicKey() throws Exception {
|
||||
KeyPair keyPair = crypto.generateAgreementKeyPair();
|
||||
PublicKey invalid = new Curve25519PublicKey(new byte[32]);
|
||||
PublicKey invalid = new AgreementPublicKey(new byte[32]);
|
||||
crypto.deriveSharedSecret(SHARED_SECRET_LABEL, invalid, keyPair,
|
||||
inputs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRfc7748TestVector() throws Exception {
|
||||
public void testRfc7748TestVector() {
|
||||
// Private keys need to be clamped because curve25519-java does the
|
||||
// clamping at key generation time, not multiplication time
|
||||
byte[] aPriv = Curve25519KeyParser.clamp(fromHexString(ALICE_PRIVATE));
|
||||
byte[] aPriv = AgreementKeyParser.clamp(fromHexString(ALICE_PRIVATE));
|
||||
byte[] aPub = fromHexString(ALICE_PUBLIC);
|
||||
byte[] bPriv = Curve25519KeyParser.clamp(fromHexString(BOB_PRIVATE));
|
||||
byte[] bPriv = AgreementKeyParser.clamp(fromHexString(BOB_PRIVATE));
|
||||
byte[] bPub = fromHexString(BOB_PUBLIC);
|
||||
byte[] sharedSecret = fromHexString(SHARED_SECRET);
|
||||
Curve25519 curve25519 = Curve25519.getInstance("java");
|
||||
|
||||
@@ -23,7 +23,7 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
|
||||
new CryptoComponentImpl(new TestSecureRandomProvider(), null);
|
||||
|
||||
@Test
|
||||
public void testAgreementPublicKeyLength() throws Exception {
|
||||
public void testAgreementPublicKeyLength() {
|
||||
// Generate 10 agreement key pairs
|
||||
for (int i = 0; i < 10; i++) {
|
||||
KeyPair keyPair = crypto.generateAgreementKeyPair();
|
||||
@@ -70,7 +70,7 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAgreementKeyParserByFuzzing() throws Exception {
|
||||
public void testAgreementKeyParserByFuzzing() {
|
||||
KeyParser parser = crypto.getAgreementKeyParser();
|
||||
// Generate a key pair to get the proper public key length
|
||||
KeyPair p = crypto.generateAgreementKeyPair();
|
||||
@@ -92,7 +92,7 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignaturePublicKeyLength() throws Exception {
|
||||
public void testSignaturePublicKeyLength() {
|
||||
// Generate 10 signature key pairs
|
||||
for (int i = 0; i < 10; i++) {
|
||||
KeyPair keyPair = crypto.generateSignatureKeyPair();
|
||||
@@ -107,10 +107,10 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
|
||||
// Generate 10 signature key pairs
|
||||
for (int i = 0; i < 10; i++) {
|
||||
KeyPair keyPair = crypto.generateSignatureKeyPair();
|
||||
byte[] key = keyPair.getPrivate().getEncoded();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
// Sign some random data and check the length of the signature
|
||||
byte[] toBeSigned = getRandomBytes(1234);
|
||||
byte[] signature = crypto.sign("label", toBeSigned, key);
|
||||
byte[] signature = crypto.sign("label", toBeSigned, privateKey);
|
||||
assertTrue(signature.length <= MAX_SIGNATURE_BYTES);
|
||||
}
|
||||
}
|
||||
@@ -123,16 +123,15 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
byte[] message = getRandomBytes(123);
|
||||
byte[] signature = crypto.sign("test", message,
|
||||
privateKey.getEncoded());
|
||||
byte[] signature = crypto.sign("test", message, privateKey);
|
||||
// Verify the signature
|
||||
assertTrue(crypto.verifySignature(signature, "test", message,
|
||||
publicKey.getEncoded()));
|
||||
publicKey));
|
||||
// Encode and parse the public key - no exceptions should be thrown
|
||||
publicKey = parser.parsePublicKey(publicKey.getEncoded());
|
||||
// Verify the signature again
|
||||
assertTrue(crypto.verifySignature(signature, "test", message,
|
||||
publicKey.getEncoded()));
|
||||
publicKey));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,23 +142,21 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
byte[] message = getRandomBytes(123);
|
||||
byte[] signature = crypto.sign("test", message,
|
||||
privateKey.getEncoded());
|
||||
byte[] signature = crypto.sign("test", message, privateKey);
|
||||
// Verify the signature
|
||||
assertTrue(crypto.verifySignature(signature, "test", message,
|
||||
publicKey.getEncoded()));
|
||||
publicKey));
|
||||
// Encode and parse the private key - no exceptions should be thrown
|
||||
privateKey = parser.parsePrivateKey(privateKey.getEncoded());
|
||||
// Sign the data again - the signatures should be the same
|
||||
byte[] signature1 = crypto.sign("test", message,
|
||||
privateKey.getEncoded());
|
||||
byte[] signature1 = crypto.sign("test", message, privateKey);
|
||||
assertTrue(crypto.verifySignature(signature1, "test", message,
|
||||
publicKey.getEncoded()));
|
||||
publicKey));
|
||||
assertArrayEquals(signature, signature1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignatureKeyParserByFuzzing() throws Exception {
|
||||
public void testSignatureKeyParserByFuzzing() {
|
||||
KeyParser parser = crypto.getSignatureKeyParser();
|
||||
// Generate a key pair to get the proper public key length
|
||||
KeyPair p = crypto.generateSignatureKeyPair();
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
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.TestSecureRandomProvider;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
@@ -19,23 +21,24 @@ public abstract class SignatureTest extends BrambleTestCase {
|
||||
|
||||
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 byte[] inputBytes = TestUtils.getRandomBytes(123);
|
||||
|
||||
protected abstract KeyPair generateKeyPair();
|
||||
|
||||
protected abstract byte[] sign(String label, byte[] toSign,
|
||||
byte[] privateKey) throws GeneralSecurityException;
|
||||
PrivateKey privateKey) throws GeneralSecurityException;
|
||||
|
||||
protected abstract boolean verify(byte[] signature, String label,
|
||||
byte[] signed, byte[] publicKey) throws GeneralSecurityException;
|
||||
byte[] signed, PublicKey publicKey) throws GeneralSecurityException;
|
||||
|
||||
SignatureTest() {
|
||||
crypto = new CryptoComponentImpl(new TestSecureRandomProvider(), null);
|
||||
KeyPair k = generateKeyPair();
|
||||
publicKey = k.getPublic().getEncoded();
|
||||
privateKey = k.getPrivate().getEncoded();
|
||||
publicKey = k.getPublic();
|
||||
privateKey = k.getPrivate();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -51,7 +54,7 @@ public abstract class SignatureTest extends BrambleTestCase {
|
||||
public void testDifferentKeysProduceDifferentSignatures() throws Exception {
|
||||
// Generate second private key
|
||||
KeyPair k2 = generateKeyPair();
|
||||
byte[] privateKey2 = k2.getPrivate().getEncoded();
|
||||
PrivateKey privateKey2 = k2.getPrivate();
|
||||
// Calculate the signature with each key
|
||||
byte[] sig1 = sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = sign(label, inputBytes, privateKey2);
|
||||
@@ -92,7 +95,7 @@ public abstract class SignatureTest extends BrambleTestCase {
|
||||
public void testDifferentKeyFailsVerification() throws Exception {
|
||||
// Generate second private key
|
||||
KeyPair k2 = generateKeyPair();
|
||||
byte[] privateKey2 = k2.getPrivate().getEncoded();
|
||||
PrivateKey privateKey2 = k2.getPrivate();
|
||||
// calculate the signature with different key, should fail to verify
|
||||
byte[] sig = sign(label, inputBytes, privateKey2);
|
||||
assertFalse(verify(sig, label, inputBytes, publicKey));
|
||||
|
||||
@@ -5,6 +5,8 @@ import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
||||
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.db.ContactExistsException;
|
||||
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.Collections.emptyMap;
|
||||
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.SHARED;
|
||||
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.transport.TransportConstants.REORDERING_WINDOW_SIZE;
|
||||
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.getClientId;
|
||||
import static org.briarproject.bramble.test.TestUtils.getContact;
|
||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||
import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||
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.getSecretKey;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTransportId;
|
||||
@@ -476,8 +478,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||
byte[] privateKey = getRandomBytes(123);
|
||||
PublicKey publicKey = getAgreementPublicKey();
|
||||
PrivateKey privateKey = getAgreementPrivateKey();
|
||||
db.transaction(false, transaction ->
|
||||
db.setHandshakeKeyPair(transaction, localAuthor.getId(),
|
||||
publicKey, privateKey));
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.briarproject.bramble.db;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
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.db.DatabaseConfig;
|
||||
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.concurrent.TimeUnit.SECONDS;
|
||||
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.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
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.MAX_COMPACTION_INTERVAL_MS;
|
||||
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.getClientId;
|
||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||
import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
||||
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.getSecretKey;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||
@@ -2250,8 +2252,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
Identity withoutKeys =
|
||||
new Identity(localAuthor, null, null, identity.getTimeCreated());
|
||||
assertFalse(withoutKeys.hasHandshakeKeyPair());
|
||||
byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||
byte[] privateKey = getRandomBytes(123);
|
||||
PublicKey publicKey = getAgreementPublicKey();
|
||||
PrivateKey privateKey = getAgreementPrivateKey();
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
@@ -2262,8 +2264,12 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
db.setHandshakeKeyPair(txn, localAuthor.getId(), publicKey, privateKey);
|
||||
retrieved = db.getIdentity(txn, localAuthor.getId());
|
||||
assertTrue(retrieved.hasHandshakeKeyPair());
|
||||
assertArrayEquals(publicKey, retrieved.getHandshakePublicKey());
|
||||
assertArrayEquals(privateKey, retrieved.getHandshakePrivateKey());
|
||||
PublicKey handshakePub = retrieved.getHandshakePublicKey();
|
||||
assertNotNull(handshakePub);
|
||||
assertArrayEquals(publicKey.getEncoded(), handshakePub.getEncoded());
|
||||
PrivateKey handshakePriv = retrieved.getHandshakePrivateKey();
|
||||
assertNotNull(handshakePriv);
|
||||
assertArrayEquals(privateKey.getEncoded(), handshakePriv.getEncoded());
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
|
||||
@@ -18,6 +18,8 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
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.junit.Assert.assertEquals;
|
||||
|
||||
@@ -28,21 +30,16 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
private final AuthorFactory authorFactory =
|
||||
context.mock(AuthorFactory.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 Identity identityWithKeys = getIdentity();
|
||||
private final LocalAuthor localAuthor = identityWithKeys.getLocalAuthor();
|
||||
private final Identity identityWithoutKeys = new Identity(localAuthor,
|
||||
null, null, identityWithKeys.getTimeCreated());
|
||||
private final PublicKey handshakePublicKey = getAgreementPublicKey();
|
||||
private final PrivateKey handshakePrivateKey = getAgreementPrivateKey();
|
||||
private final KeyPair handshakeKeyPair =
|
||||
new KeyPair(handshakePublicKey, handshakePrivateKey);
|
||||
private final byte[] handshakePublicKeyBytes =
|
||||
identityWithKeys.getHandshakePublicKey();
|
||||
private final byte[] handshakePrivateKeyBytes =
|
||||
identityWithKeys.getHandshakePrivateKey();
|
||||
|
||||
private IdentityManagerImpl identityManager;
|
||||
|
||||
@@ -69,12 +66,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(singletonList(identityWithoutKeys)));
|
||||
oneOf(crypto).generateAgreementKeyPair();
|
||||
will(returnValue(handshakeKeyPair));
|
||||
oneOf(handshakePublicKey).getEncoded();
|
||||
will(returnValue(handshakePublicKeyBytes));
|
||||
oneOf(handshakePrivateKey).getEncoded();
|
||||
will(returnValue(handshakePrivateKeyBytes));
|
||||
oneOf(db).setHandshakeKeyPair(txn, localAuthor.getId(),
|
||||
handshakePublicKeyBytes, handshakePrivateKeyBytes);
|
||||
handshakePublicKey, handshakePrivateKey);
|
||||
}});
|
||||
|
||||
identityManager.onDatabaseOpened(txn);
|
||||
@@ -104,10 +97,6 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(singletonList(identityWithoutKeys)));
|
||||
oneOf(crypto).generateAgreementKeyPair();
|
||||
will(returnValue(handshakeKeyPair));
|
||||
oneOf(handshakePublicKey).getEncoded();
|
||||
will(returnValue(handshakePublicKeyBytes));
|
||||
oneOf(handshakePrivateKey).getEncoded();
|
||||
will(returnValue(handshakePrivateKeyBytes));
|
||||
}});
|
||||
|
||||
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
||||
|
||||
@@ -16,10 +16,13 @@ import org.jmock.lib.legacy.ClassImposteriser;
|
||||
import org.junit.Rule;
|
||||
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.MASTER_KEY_LABEL;
|
||||
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.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.getSecretKey;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@@ -34,21 +37,17 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
setImposteriser(ClassImposteriser.INSTANCE);
|
||||
}};
|
||||
|
||||
private final PublicKey alicePubKey =
|
||||
context.mock(PublicKey.class, "alice");
|
||||
private final byte[] alicePubKeyBytes = getRandomBytes(32);
|
||||
private final PublicKey alicePubKey = getAgreementPublicKey();
|
||||
private final byte[] aliceCommit = getRandomBytes(COMMIT_LENGTH);
|
||||
private final byte[] alicePayload = getRandomBytes(COMMIT_LENGTH + 8);
|
||||
private final byte[] aliceConfirm = getRandomBytes(SecretKey.LENGTH);
|
||||
|
||||
private final PublicKey bobPubKey = context.mock(PublicKey.class, "bob");
|
||||
private final byte[] bobPubKeyBytes = getRandomBytes(32);
|
||||
private final PublicKey bobPubKey = getAgreementPublicKey();
|
||||
private final byte[] bobCommit = getRandomBytes(COMMIT_LENGTH);
|
||||
private final byte[] bobPayload = getRandomBytes(COMMIT_LENGTH + 19);
|
||||
private final byte[] bobConfirm = getRandomBytes(SecretKey.LENGTH);
|
||||
|
||||
private final PublicKey badPubKey = context.mock(PublicKey.class, "bad");
|
||||
private final byte[] badPubKeyBytes = getRandomBytes(32);
|
||||
private final PublicKey badPubKey = getAgreementPublicKey();
|
||||
private final byte[] badCommit = getRandomBytes(COMMIT_LENGTH);
|
||||
private final byte[] badConfirm = getRandomBytes(SecretKey.LENGTH);
|
||||
|
||||
@@ -64,15 +63,13 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
PayloadEncoder payloadEncoder;
|
||||
@Mock
|
||||
KeyAgreementTransport transport;
|
||||
@Mock
|
||||
PublicKey ourPubKey;
|
||||
|
||||
@Test
|
||||
public void testAliceProtocol() throws Exception {
|
||||
// set up
|
||||
Payload theirPayload = new Payload(bobCommit, null);
|
||||
Payload ourPayload = new Payload(aliceCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(bobCommit, emptyList());
|
||||
Payload ourPayload = new Payload(aliceCommit, emptyList());
|
||||
KeyPair ourKeyPair = new KeyPair(alicePubKey, getAgreementPrivateKey());
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
SecretKey masterKey = getSecretKey();
|
||||
|
||||
@@ -87,24 +84,18 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(alicePayload));
|
||||
allowing(payloadEncoder).encode(theirPayload);
|
||||
will(returnValue(bobPayload));
|
||||
allowing(ourPubKey).getEncoded();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
allowing(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
allowing(alicePubKey).getEncoded();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
allowing(bobPubKey).getEncoded();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
|
||||
// Alice sends her public key
|
||||
oneOf(transport).sendKey(alicePubKeyBytes);
|
||||
oneOf(transport).sendKey(alicePubKey.getEncoded());
|
||||
|
||||
// Alice receives Bob's public key
|
||||
oneOf(callbacks).connectionWaiting();
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
will(returnValue(bobPubKey.getEncoded()));
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
oneOf(keyParser).parsePublicKey(bobPubKeyBytes);
|
||||
oneOf(keyParser).parsePublicKey(bobPubKey.getEncoded());
|
||||
will(returnValue(bobPubKey));
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
@@ -114,7 +105,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// Alice computes shared secret
|
||||
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, bobPubKey,
|
||||
ourKeyPair, new byte[] {PROTOCOL_VERSION},
|
||||
alicePubKeyBytes, bobPubKeyBytes);
|
||||
alicePubKey.getEncoded(), bobPubKey.getEncoded());
|
||||
will(returnValue(sharedSecret));
|
||||
|
||||
// Alice sends her confirmation record
|
||||
@@ -146,9 +137,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testBobProtocol() throws Exception {
|
||||
// set up
|
||||
Payload theirPayload = new Payload(aliceCommit, null);
|
||||
Payload ourPayload = new Payload(bobCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(aliceCommit, emptyList());
|
||||
Payload ourPayload = new Payload(bobCommit, emptyList());
|
||||
KeyPair ourKeyPair = new KeyPair(bobPubKey, getAgreementPrivateKey());
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
SecretKey masterKey = getSecretKey();
|
||||
|
||||
@@ -163,20 +154,14 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(bobPayload));
|
||||
allowing(payloadEncoder).encode(theirPayload);
|
||||
will(returnValue(alicePayload));
|
||||
allowing(ourPubKey).getEncoded();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
allowing(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
allowing(alicePubKey).getEncoded();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
allowing(bobPubKey).getEncoded();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
|
||||
// Bob receives Alice's public key
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
will(returnValue(alicePubKey.getEncoded()));
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
oneOf(keyParser).parsePublicKey(alicePubKeyBytes);
|
||||
oneOf(keyParser).parsePublicKey(alicePubKey.getEncoded());
|
||||
will(returnValue(alicePubKey));
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
@@ -184,12 +169,12 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(aliceCommit));
|
||||
|
||||
// Bob sends his public key
|
||||
oneOf(transport).sendKey(bobPubKeyBytes);
|
||||
oneOf(transport).sendKey(bobPubKey.getEncoded());
|
||||
|
||||
// Bob computes shared secret
|
||||
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, alicePubKey,
|
||||
ourKeyPair, new byte[] {PROTOCOL_VERSION},
|
||||
alicePubKeyBytes, bobPubKeyBytes);
|
||||
alicePubKey.getEncoded(), bobPubKey.getEncoded());
|
||||
will(returnValue(sharedSecret));
|
||||
|
||||
// Bob receives Alices's confirmation record
|
||||
@@ -221,9 +206,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testAliceProtocolAbortOnBadKey() throws Exception {
|
||||
// set up
|
||||
Payload theirPayload = new Payload(bobCommit, null);
|
||||
Payload ourPayload = new Payload(aliceCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(bobCommit, emptyList());
|
||||
Payload ourPayload = new Payload(aliceCommit, emptyList());
|
||||
KeyPair ourKeyPair = new KeyPair(alicePubKey, getAgreementPrivateKey());
|
||||
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
@@ -232,20 +217,18 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
// Helpers
|
||||
allowing(ourPubKey).getEncoded();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
allowing(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
|
||||
// Alice sends her public key
|
||||
oneOf(transport).sendKey(alicePubKeyBytes);
|
||||
oneOf(transport).sendKey(alicePubKey.getEncoded());
|
||||
|
||||
// Alice receives a bad public key
|
||||
oneOf(callbacks).connectionWaiting();
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(badPubKeyBytes));
|
||||
will(returnValue(badPubKey.getEncoded()));
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
oneOf(keyParser).parsePublicKey(badPubKeyBytes);
|
||||
oneOf(keyParser).parsePublicKey(badPubKey.getEncoded());
|
||||
will(returnValue(badPubKey));
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
@@ -258,7 +241,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// Alice never computes shared secret
|
||||
never(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, badPubKey,
|
||||
ourKeyPair, new byte[] {PROTOCOL_VERSION},
|
||||
alicePubKeyBytes, bobPubKeyBytes);
|
||||
alicePubKey.getEncoded(), bobPubKey.getEncoded());
|
||||
}});
|
||||
|
||||
// execute
|
||||
@@ -268,9 +251,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testBobProtocolAbortOnBadKey() throws Exception {
|
||||
// set up
|
||||
Payload theirPayload = new Payload(aliceCommit, null);
|
||||
Payload ourPayload = new Payload(bobCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(aliceCommit, emptyList());
|
||||
Payload ourPayload = new Payload(bobCommit, emptyList());
|
||||
KeyPair ourKeyPair = new KeyPair(bobPubKey, getAgreementPrivateKey());
|
||||
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
@@ -279,16 +262,14 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
// Helpers
|
||||
allowing(ourPubKey).getEncoded();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
allowing(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
|
||||
// Bob receives a bad public key
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(badPubKeyBytes));
|
||||
will(returnValue(badPubKey.getEncoded()));
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
oneOf(keyParser).parsePublicKey(badPubKeyBytes);
|
||||
oneOf(keyParser).parsePublicKey(badPubKey.getEncoded());
|
||||
will(returnValue(badPubKey));
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
@@ -299,7 +280,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
oneOf(transport).sendAbort(false);
|
||||
|
||||
// Bob never sends his public key
|
||||
never(transport).sendKey(bobPubKeyBytes);
|
||||
never(transport).sendKey(bobPubKey.getEncoded());
|
||||
}});
|
||||
|
||||
// execute
|
||||
@@ -309,9 +290,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testAliceProtocolAbortOnBadConfirm() throws Exception {
|
||||
// set up
|
||||
Payload theirPayload = new Payload(bobCommit, null);
|
||||
Payload ourPayload = new Payload(aliceCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(bobCommit, emptyList());
|
||||
Payload ourPayload = new Payload(aliceCommit, emptyList());
|
||||
KeyPair ourKeyPair = new KeyPair(alicePubKey, getAgreementPrivateKey());
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
@@ -325,22 +306,18 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(alicePayload));
|
||||
allowing(payloadEncoder).encode(theirPayload);
|
||||
will(returnValue(bobPayload));
|
||||
allowing(ourPubKey).getEncoded();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
allowing(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
allowing(bobPubKey).getEncoded();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
|
||||
// Alice sends her public key
|
||||
oneOf(transport).sendKey(alicePubKeyBytes);
|
||||
oneOf(transport).sendKey(alicePubKey.getEncoded());
|
||||
|
||||
// Alice receives Bob's public key
|
||||
oneOf(callbacks).connectionWaiting();
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
will(returnValue(bobPubKey.getEncoded()));
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
oneOf(keyParser).parsePublicKey(bobPubKeyBytes);
|
||||
oneOf(keyParser).parsePublicKey(bobPubKey.getEncoded());
|
||||
will(returnValue(bobPubKey));
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
@@ -350,7 +327,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// Alice computes shared secret
|
||||
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, bobPubKey,
|
||||
ourKeyPair, new byte[] {PROTOCOL_VERSION},
|
||||
alicePubKeyBytes, bobPubKeyBytes);
|
||||
alicePubKey.getEncoded(), bobPubKey.getEncoded());
|
||||
will(returnValue(sharedSecret));
|
||||
|
||||
// Alice sends her confirmation record
|
||||
@@ -384,9 +361,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testBobProtocolAbortOnBadConfirm() throws Exception {
|
||||
// set up
|
||||
Payload theirPayload = new Payload(aliceCommit, null);
|
||||
Payload ourPayload = new Payload(bobCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(aliceCommit, emptyList());
|
||||
Payload ourPayload = new Payload(bobCommit, emptyList());
|
||||
KeyPair ourKeyPair = new KeyPair(bobPubKey, getAgreementPrivateKey());
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
@@ -400,18 +377,14 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(bobPayload));
|
||||
allowing(payloadEncoder).encode(theirPayload);
|
||||
will(returnValue(alicePayload));
|
||||
allowing(ourPubKey).getEncoded();
|
||||
will(returnValue(bobPubKeyBytes));
|
||||
allowing(crypto).getAgreementKeyParser();
|
||||
will(returnValue(keyParser));
|
||||
allowing(alicePubKey).getEncoded();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
|
||||
// Bob receives Alice's public key
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(alicePubKeyBytes));
|
||||
will(returnValue(alicePubKey.getEncoded()));
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
oneOf(keyParser).parsePublicKey(alicePubKeyBytes);
|
||||
oneOf(keyParser).parsePublicKey(alicePubKey.getEncoded());
|
||||
will(returnValue(alicePubKey));
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
@@ -419,12 +392,12 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(aliceCommit));
|
||||
|
||||
// Bob sends his public key
|
||||
oneOf(transport).sendKey(bobPubKeyBytes);
|
||||
oneOf(transport).sendKey(bobPubKey.getEncoded());
|
||||
|
||||
// Bob computes shared secret
|
||||
oneOf(crypto).deriveSharedSecret(SHARED_SECRET_LABEL, alicePubKey,
|
||||
ourKeyPair, new byte[] {PROTOCOL_VERSION},
|
||||
alicePubKeyBytes, bobPubKeyBytes);
|
||||
alicePubKey.getEncoded(), bobPubKey.getEncoded());
|
||||
will(returnValue(sharedSecret));
|
||||
|
||||
// Bob receives a bad confirmation record
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.api.privategroup.invitation;
|
||||
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
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.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -21,7 +22,7 @@ public interface GroupInvitationFactory {
|
||||
*/
|
||||
@CryptoExecutor
|
||||
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
|
||||
|
||||
@@ -4,6 +4,8 @@ import com.rometools.rome.feed.synd.SyndFeed;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
@@ -70,7 +72,8 @@ class FeedFactoryImpl implements FeedFactory {
|
||||
String url = d.getString(KEY_FEED_URL);
|
||||
|
||||
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);
|
||||
LocalAuthor localAuthor = new LocalAuthor(author.getId(),
|
||||
author.getFormatVersion(), author.getName(),
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
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.db.DatabaseComponent;
|
||||
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,
|
||||
byte[] ephemeralPublicKey, long acceptTimestamp,
|
||||
PublicKey ephemeralPublicKey, long acceptTimestamp,
|
||||
Map<TransportId, TransportProperties> transportProperties,
|
||||
boolean visible) throws DbException {
|
||||
Message m = messageEncoder
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
@@ -17,14 +18,13 @@ import javax.annotation.concurrent.Immutable;
|
||||
class AcceptMessage extends AbstractIntroductionMessage {
|
||||
|
||||
private final SessionId sessionId;
|
||||
private final byte[] ephemeralPublicKey;
|
||||
private final PublicKey ephemeralPublicKey;
|
||||
private final long acceptTimestamp;
|
||||
private final Map<TransportId, TransportProperties> transportProperties;
|
||||
|
||||
protected AcceptMessage(MessageId messageId, GroupId groupId,
|
||||
long timestamp, @Nullable MessageId previousMessageId,
|
||||
SessionId sessionId,
|
||||
byte[] ephemeralPublicKey,
|
||||
SessionId sessionId, PublicKey ephemeralPublicKey,
|
||||
long acceptTimestamp,
|
||||
Map<TransportId, TransportProperties> transportProperties) {
|
||||
super(messageId, groupId, timestamp, previousMessageId);
|
||||
@@ -38,7 +38,7 @@ class AcceptMessage extends AbstractIntroductionMessage {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public byte[] getEphemeralPublicKey() {
|
||||
public PublicKey getEphemeralPublicKey() {
|
||||
return ephemeralPublicKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
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.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
||||
@@ -272,9 +274,9 @@ class IntroduceeProtocolEngine
|
||||
markRequestsUnavailableToAnswer(txn, s);
|
||||
|
||||
// Create ephemeral key pair and get local transport properties
|
||||
KeyPair keyPair = crypto.generateKeyPair();
|
||||
byte[] publicKey = keyPair.getPublic().getEncoded();
|
||||
byte[] privateKey = keyPair.getPrivate().getEncoded();
|
||||
KeyPair keyPair = crypto.generateAgreementKeyPair();
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
Map<TransportId, TransportProperties> transportProperties =
|
||||
transportPropertyManager.getLocalProperties(txn);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -70,7 +72,7 @@ class IntroduceeSession extends Session<IntroduceeState>
|
||||
|
||||
static IntroduceeSession addLocalAccept(IntroduceeSession s,
|
||||
IntroduceeState state, Message acceptMessage,
|
||||
byte[] ephemeralPublicKey, byte[] ephemeralPrivateKey,
|
||||
PublicKey ephemeralPublicKey, PrivateKey ephemeralPrivateKey,
|
||||
long acceptTimestamp,
|
||||
Map<TransportId, TransportProperties> transportProperties) {
|
||||
Local local = new Local(s.local.alice, acceptMessage.getId(),
|
||||
@@ -190,7 +192,7 @@ class IntroduceeSession extends Session<IntroduceeState>
|
||||
@Nullable
|
||||
final MessageId lastMessageId;
|
||||
@Nullable
|
||||
final byte[] ephemeralPublicKey;
|
||||
final PublicKey ephemeralPublicKey;
|
||||
@Nullable
|
||||
final Map<TransportId, TransportProperties> transportProperties;
|
||||
final long acceptTimestamp;
|
||||
@@ -198,7 +200,7 @@ class IntroduceeSession extends Session<IntroduceeState>
|
||||
final byte[] macKey;
|
||||
|
||||
private Common(boolean alice, @Nullable MessageId lastMessageId,
|
||||
@Nullable byte[] ephemeralPublicKey, @Nullable
|
||||
@Nullable PublicKey ephemeralPublicKey, @Nullable
|
||||
Map<TransportId, TransportProperties> transportProperties,
|
||||
long acceptTimestamp, @Nullable byte[] macKey) {
|
||||
this.alice = alice;
|
||||
@@ -213,11 +215,12 @@ class IntroduceeSession extends Session<IntroduceeState>
|
||||
static class Local extends Common {
|
||||
final long lastMessageTimestamp;
|
||||
@Nullable
|
||||
final byte[] ephemeralPrivateKey;
|
||||
final PrivateKey ephemeralPrivateKey;
|
||||
|
||||
Local(boolean alice, @Nullable MessageId lastMessageId,
|
||||
long lastMessageTimestamp, @Nullable byte[] ephemeralPublicKey,
|
||||
@Nullable byte[] ephemeralPrivateKey, @Nullable
|
||||
long lastMessageTimestamp,
|
||||
@Nullable PublicKey ephemeralPublicKey,
|
||||
@Nullable PrivateKey ephemeralPrivateKey, @Nullable
|
||||
Map<TransportId, TransportProperties> transportProperties,
|
||||
long acceptTimestamp, @Nullable byte[] macKey) {
|
||||
super(alice, lastMessageId, ephemeralPublicKey, transportProperties,
|
||||
@@ -239,7 +242,7 @@ class IntroduceeSession extends Session<IntroduceeState>
|
||||
|
||||
Remote(boolean alice, Author author,
|
||||
@Nullable MessageId lastMessageId,
|
||||
@Nullable byte[] ephemeralPublicKey, @Nullable
|
||||
@Nullable PublicKey ephemeralPublicKey, @Nullable
|
||||
Map<TransportId, TransportProperties> transportProperties,
|
||||
long acceptTimestamp, @Nullable byte[] macKey) {
|
||||
super(alice, lastMessageId, ephemeralPublicKey, transportProperties,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.briar.introduction;
|
||||
|
||||
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.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
@@ -28,7 +29,7 @@ interface IntroductionCrypto {
|
||||
/**
|
||||
* Generates an agreement key pair.
|
||||
*/
|
||||
KeyPair generateKeyPair();
|
||||
KeyPair generateAgreementKeyPair();
|
||||
|
||||
/**
|
||||
* Derives a session master key for Alice or Bob.
|
||||
@@ -74,7 +75,7 @@ interface IntroductionCrypto {
|
||||
* (from {@link LocalAuthor#getPrivateKey()})
|
||||
* @return The signature as a byte array
|
||||
*/
|
||||
byte[] sign(SecretKey macKey, byte[] privateKey)
|
||||
byte[] sign(SecretKey macKey, PrivateKey privateKey)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
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.PublicKey;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
@@ -61,7 +60,7 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPair generateKeyPair() {
|
||||
public KeyPair generateAgreementKeyPair() {
|
||||
return crypto.generateAgreementKeyPair();
|
||||
}
|
||||
|
||||
@@ -82,21 +81,17 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
|
||||
);
|
||||
}
|
||||
|
||||
SecretKey deriveMasterKey(byte[] publicKey, byte[] privateKey,
|
||||
byte[] remotePublicKey, boolean alice)
|
||||
SecretKey deriveMasterKey(PublicKey publicKey, PrivateKey privateKey,
|
||||
PublicKey remotePublicKey, boolean alice)
|
||||
throws GeneralSecurityException {
|
||||
KeyParser kp = crypto.getAgreementKeyParser();
|
||||
PublicKey remoteEphemeralPublicKey = kp.parsePublicKey(remotePublicKey);
|
||||
PublicKey ephemeralPublicKey = kp.parsePublicKey(publicKey);
|
||||
PrivateKey ephemeralPrivateKey = kp.parsePrivateKey(privateKey);
|
||||
KeyPair keyPair = new KeyPair(ephemeralPublicKey, ephemeralPrivateKey);
|
||||
KeyPair keyPair = new KeyPair(publicKey, privateKey);
|
||||
return crypto.deriveSharedSecret(
|
||||
LABEL_MASTER_KEY,
|
||||
remoteEphemeralPublicKey,
|
||||
remotePublicKey,
|
||||
keyPair,
|
||||
new byte[] {MAJOR_VERSION},
|
||||
alice ? publicKey : remotePublicKey,
|
||||
alice ? remotePublicKey : publicKey
|
||||
alice ? publicKey.getEncoded() : remotePublicKey.getEncoded(),
|
||||
alice ? remotePublicKey.getEncoded() : publicKey.getEncoded()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -177,13 +172,9 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign(SecretKey macKey, byte[] privateKey)
|
||||
public byte[] sign(SecretKey macKey, PrivateKey privateKey)
|
||||
throws GeneralSecurityException {
|
||||
return crypto.sign(
|
||||
LABEL_AUTH_SIGN,
|
||||
getNonce(macKey),
|
||||
privateKey
|
||||
);
|
||||
return crypto.sign(LABEL_AUTH_SIGN, getNonce(macKey), privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -194,7 +185,7 @@ class IntroductionCryptoImpl implements IntroductionCrypto {
|
||||
verifySignature(macKey, s.getRemote().author.getPublicKey(), signature);
|
||||
}
|
||||
|
||||
void verifySignature(SecretKey macKey, byte[] publicKey,
|
||||
void verifySignature(SecretKey macKey, PublicKey publicKey,
|
||||
byte[] signature) throws GeneralSecurityException {
|
||||
byte[] nonce = getNonce(macKey);
|
||||
if (!crypto.verifySignature(signature, LABEL_AUTH_SIGN, nonce,
|
||||
|
||||
@@ -15,10 +15,9 @@ import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
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.MAX_SIGNATURE_BYTES;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
@@ -84,8 +83,7 @@ class IntroductionValidator extends BdfMessageValidator {
|
||||
return new BdfMessageContext(meta);
|
||||
} else {
|
||||
MessageId dependency = new MessageId(previousMessageId);
|
||||
return new BdfMessageContext(meta,
|
||||
Collections.singletonList(dependency));
|
||||
return new BdfMessageContext(meta, singletonList(dependency));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +99,7 @@ class IntroductionValidator extends BdfMessageValidator {
|
||||
|
||||
byte[] ephemeralPublicKey = body.getRaw(3);
|
||||
checkLength(ephemeralPublicKey, 0, MAX_PUBLIC_KEY_LENGTH);
|
||||
clientHelper.parseAndValidateAgreementPublicKey(ephemeralPublicKey);
|
||||
|
||||
long timestamp = body.getLong(4);
|
||||
if (timestamp < 0) throw new FormatException();
|
||||
@@ -111,15 +110,13 @@ class IntroductionValidator extends BdfMessageValidator {
|
||||
.parseAndValidateTransportPropertiesMap(transportProperties);
|
||||
|
||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||
BdfDictionary meta = messageEncoder
|
||||
.encodeMetadata(ACCEPT, sessionId, m.getTimestamp(), false,
|
||||
false, false);
|
||||
BdfDictionary meta = messageEncoder.encodeMetadata(ACCEPT, sessionId,
|
||||
m.getTimestamp(), false, false, false);
|
||||
if (previousMessageId == null) {
|
||||
return new BdfMessageContext(meta);
|
||||
} else {
|
||||
MessageId dependency = new MessageId(previousMessageId);
|
||||
return new BdfMessageContext(meta,
|
||||
Collections.singletonList(dependency));
|
||||
return new BdfMessageContext(meta, singletonList(dependency));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,12 +137,10 @@ class IntroductionValidator extends BdfMessageValidator {
|
||||
checkLength(signature, 1, MAX_SIGNATURE_BYTES);
|
||||
|
||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||
BdfDictionary meta = messageEncoder
|
||||
.encodeMetadata(AUTH, sessionId, m.getTimestamp(), false, false,
|
||||
false);
|
||||
BdfDictionary meta = messageEncoder.encodeMetadata(AUTH, sessionId,
|
||||
m.getTimestamp(), false, false, false);
|
||||
MessageId dependency = new MessageId(previousMessageId);
|
||||
return new BdfMessageContext(meta,
|
||||
Collections.singletonList(dependency));
|
||||
return new BdfMessageContext(meta, singletonList(dependency));
|
||||
}
|
||||
|
||||
private BdfMessageContext validateActivateMessage(Message m, BdfList body)
|
||||
@@ -162,15 +157,13 @@ class IntroductionValidator extends BdfMessageValidator {
|
||||
checkLength(mac, MAC_BYTES);
|
||||
|
||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||
BdfDictionary meta = messageEncoder
|
||||
.encodeMetadata(ACTIVATE, sessionId, m.getTimestamp(), false,
|
||||
false, false);
|
||||
BdfDictionary meta = messageEncoder.encodeMetadata(ACTIVATE, sessionId,
|
||||
m.getTimestamp(), false, false, false);
|
||||
if (previousMessageId == null) {
|
||||
return new BdfMessageContext(meta);
|
||||
} else {
|
||||
MessageId dependency = new MessageId(previousMessageId);
|
||||
return new BdfMessageContext(meta,
|
||||
Collections.singletonList(dependency));
|
||||
return new BdfMessageContext(meta, singletonList(dependency));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,15 +178,13 @@ class IntroductionValidator extends BdfMessageValidator {
|
||||
checkLength(previousMessageId, UniqueId.LENGTH);
|
||||
|
||||
SessionId sessionId = new SessionId(sessionIdBytes);
|
||||
BdfDictionary meta = messageEncoder
|
||||
.encodeMetadata(type, sessionId, m.getTimestamp(), false, false,
|
||||
false);
|
||||
BdfDictionary meta = messageEncoder.encodeMetadata(type, sessionId,
|
||||
m.getTimestamp(), false, false, false);
|
||||
if (previousMessageId == null) {
|
||||
return new BdfMessageContext(meta);
|
||||
} else {
|
||||
MessageId dependency = new MessageId(previousMessageId);
|
||||
return new BdfMessageContext(meta,
|
||||
Collections.singletonList(dependency));
|
||||
return new BdfMessageContext(meta, singletonList(dependency));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -35,7 +36,7 @@ interface MessageEncoder {
|
||||
|
||||
Message encodeAcceptMessage(GroupId contactGroupId, long timestamp,
|
||||
@Nullable MessageId previousMessageId, SessionId sessionId,
|
||||
byte[] ephemeralPublicKey, long acceptTimestamp,
|
||||
PublicKey ephemeralPublicKey, long acceptTimestamp,
|
||||
Map<TransportId, TransportProperties> transportProperties);
|
||||
|
||||
Message encodeDeclineMessage(GroupId contactGroupId, long timestamp,
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
@@ -105,13 +106,13 @@ class MessageEncoderImpl implements MessageEncoder {
|
||||
@Override
|
||||
public Message encodeAcceptMessage(GroupId contactGroupId, long timestamp,
|
||||
@Nullable MessageId previousMessageId, SessionId sessionId,
|
||||
byte[] ephemeralPublicKey, long acceptTimestamp,
|
||||
PublicKey ephemeralPublicKey, long acceptTimestamp,
|
||||
Map<TransportId, TransportProperties> transportProperties) {
|
||||
BdfList body = BdfList.of(
|
||||
ACCEPT.getValue(),
|
||||
sessionId,
|
||||
previousMessageId,
|
||||
ephemeralPublicKey,
|
||||
ephemeralPublicKey.getEncoded(),
|
||||
acceptTimestamp,
|
||||
clientHelper.toDictionary(transportProperties)
|
||||
);
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
@@ -86,7 +88,7 @@ class MessageParserImpl implements MessageParser {
|
||||
byte[] previousMsgBytes = body.getOptionalRaw(2);
|
||||
MessageId previousMessageId = (previousMsgBytes == null ? null :
|
||||
new MessageId(previousMsgBytes));
|
||||
byte[] ephemeralPublicKey = body.getRaw(3);
|
||||
PublicKey ephemeralPublicKey = new AgreementPublicKey(body.getRaw(3));
|
||||
long acceptTimestamp = body.getLong(4);
|
||||
Map<TransportId, TransportProperties> transportProperties = clientHelper
|
||||
.parseAndValidateTransportPropertiesMap(body.getDictionary(5));
|
||||
|
||||
@@ -2,6 +2,10 @@ package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.BdfEntry;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
@@ -122,12 +126,12 @@ class SessionParserImpl implements SessionParser {
|
||||
MessageId lastLocalMessageId =
|
||||
getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID);
|
||||
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
||||
byte[] ephemeralPublicKey =
|
||||
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
||||
PublicKey ephemeralPublicKey =
|
||||
getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
||||
BdfDictionary tpDict =
|
||||
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
|
||||
byte[] ephemeralPrivateKey =
|
||||
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PRIVATE_KEY);
|
||||
PrivateKey ephemeralPrivateKey =
|
||||
getEphemeralPrivateKey(d, SESSION_KEY_EPHEMERAL_PRIVATE_KEY);
|
||||
Map<TransportId, TransportProperties> transportProperties =
|
||||
tpDict == null ? null : clientHelper
|
||||
.parseAndValidateTransportPropertiesMap(tpDict);
|
||||
@@ -143,8 +147,8 @@ class SessionParserImpl implements SessionParser {
|
||||
Author remoteAuthor = getAuthor(d, SESSION_KEY_REMOTE_AUTHOR);
|
||||
MessageId lastRemoteMessageId =
|
||||
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
|
||||
byte[] ephemeralPublicKey =
|
||||
d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
||||
PublicKey ephemeralPublicKey =
|
||||
getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
||||
BdfDictionary tpDict =
|
||||
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
|
||||
Map<TransportId, TransportProperties> transportProperties =
|
||||
@@ -195,4 +199,17 @@ class SessionParserImpl implements SessionParser {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||
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.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -35,7 +36,7 @@ class GroupInvitationFactoryImpl implements GroupInvitationFactory {
|
||||
|
||||
@Override
|
||||
public byte[] signInvitation(Contact c, GroupId privateGroupId,
|
||||
long timestamp, byte[] privateKey) {
|
||||
long timestamp, PrivateKey privateKey) {
|
||||
AuthorId creatorId = c.getLocalAuthorId();
|
||||
AuthorId memberId = c.getAuthor().getId();
|
||||
BdfList token = createInviteToken(creatorId, memberId, privateGroupId,
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
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.privategroup.invitation.GroupInvitationConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
|
||||
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);
|
||||
byte[] signature = body.getRaw(5);
|
||||
|
||||
// Format version, name, public key
|
||||
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);
|
||||
Author creator = clientHelper.parseAndValidateAuthor(creatorList);
|
||||
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
|
||||
groupName, creator, salt);
|
||||
return new InviteMessage(m.getId(), m.getGroupId(),
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
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.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class BlogMessageParserImpl extends MessageParserImpl<Blog> {
|
||||
|
||||
private final BlogFactory blogFactory;
|
||||
private final AuthorFactory authorFactory;
|
||||
|
||||
@Inject
|
||||
BlogMessageParserImpl(ClientHelper clientHelper, BlogFactory blogFactory,
|
||||
AuthorFactory authorFactory) {
|
||||
BlogMessageParserImpl(ClientHelper clientHelper, BlogFactory blogFactory) {
|
||||
super(clientHelper);
|
||||
this.blogFactory = blogFactory;
|
||||
this.authorFactory = authorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,14 +29,7 @@ class BlogMessageParserImpl extends MessageParserImpl<Blog> {
|
||||
BdfList authorList = descriptor.getList(0);
|
||||
boolean rssFeed = descriptor.getBoolean(1);
|
||||
|
||||
// Format version, name, public key
|
||||
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);
|
||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||
if (rssFeed) return blogFactory.createFeedBlog(author);
|
||||
else return blogFactory.createBlog(author);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_VISIBLE_IN
|
||||
abstract class MessageParserImpl<S extends Shareable>
|
||||
implements MessageParser<S> {
|
||||
|
||||
private final ClientHelper clientHelper;
|
||||
protected final ClientHelper clientHelper;
|
||||
|
||||
MessageParserImpl(ClientHelper clientHelper) {
|
||||
this.clientHelper = clientHelper;
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.briar.forum;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.UniqueId;
|
||||
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.BdfList;
|
||||
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 Author author = getAuthor();
|
||||
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(),
|
||||
authorName, authorPublicKey);
|
||||
authorName, authorPublicKey.getEncoded());
|
||||
private final BdfList signedWithParent = BdfList.of(groupId, timestamp,
|
||||
parentId.getBytes(), authorList, text);
|
||||
private final BdfList signedWithoutParent = BdfList.of(groupId, timestamp,
|
||||
|
||||
@@ -64,8 +64,8 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
|
||||
crypto.isAlice(introducee1.getId(), introducee2.getId());
|
||||
alice = isAlice ? introducee1 : introducee2;
|
||||
bob = isAlice ? introducee2 : introducee1;
|
||||
aliceEphemeral = crypto.generateKeyPair();
|
||||
bobEphemeral = crypto.generateKeyPair();
|
||||
aliceEphemeral = crypto.generateAgreementKeyPair();
|
||||
bobEphemeral = crypto.generateAgreementKeyPair();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,30 +86,25 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testDeriveMasterKey() throws Exception {
|
||||
SecretKey aliceMasterKey =
|
||||
crypto.deriveMasterKey(aliceEphemeral.getPublic().getEncoded(),
|
||||
aliceEphemeral.getPrivate().getEncoded(),
|
||||
bobEphemeral.getPublic().getEncoded(), true);
|
||||
SecretKey bobMasterKey =
|
||||
crypto.deriveMasterKey(bobEphemeral.getPublic().getEncoded(),
|
||||
bobEphemeral.getPrivate().getEncoded(),
|
||||
aliceEphemeral.getPublic().getEncoded(), false);
|
||||
SecretKey aliceMasterKey = crypto.deriveMasterKey(
|
||||
aliceEphemeral.getPublic(), aliceEphemeral.getPrivate(),
|
||||
bobEphemeral.getPublic(), true);
|
||||
SecretKey bobMasterKey = crypto.deriveMasterKey(
|
||||
bobEphemeral.getPublic(), bobEphemeral.getPrivate(),
|
||||
aliceEphemeral.getPublic(), false);
|
||||
assertArrayEquals(aliceMasterKey.getBytes(), bobMasterKey.getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliceAuthMac() throws Exception {
|
||||
SecretKey aliceMacKey = crypto.deriveMacKey(masterKey, true);
|
||||
Local local = new Local(true, null, -1,
|
||||
aliceEphemeral.getPublic().getEncoded(),
|
||||
aliceEphemeral.getPrivate().getEncoded(), aliceTransport,
|
||||
Local local = new Local(true, null, -1, aliceEphemeral.getPublic(),
|
||||
aliceEphemeral.getPrivate(), aliceTransport,
|
||||
aliceAcceptTimestamp, aliceMacKey.getBytes());
|
||||
Remote remote = new Remote(false, bob, null,
|
||||
bobEphemeral.getPublic().getEncoded(), bobTransport,
|
||||
bobAcceptTimestamp, null);
|
||||
byte[] aliceMac =
|
||||
crypto.authMac(aliceMacKey, introducer.getId(), alice.getId(),
|
||||
local, remote);
|
||||
Remote remote = new Remote(false, bob, null, bobEphemeral.getPublic(),
|
||||
bobTransport, bobAcceptTimestamp, null);
|
||||
byte[] aliceMac = crypto.authMac(aliceMacKey, introducer.getId(),
|
||||
alice.getId(), local, remote);
|
||||
|
||||
// verify from Bob's perspective
|
||||
crypto.verifyAuthMac(aliceMac, aliceMacKey, introducer.getId(),
|
||||
@@ -119,16 +114,14 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testBobAuthMac() throws Exception {
|
||||
SecretKey bobMacKey = crypto.deriveMacKey(masterKey, false);
|
||||
Local local = new Local(false, null, -1,
|
||||
bobEphemeral.getPublic().getEncoded(),
|
||||
bobEphemeral.getPrivate().getEncoded(), bobTransport,
|
||||
Local local = new Local(false, null, -1, bobEphemeral.getPublic(),
|
||||
bobEphemeral.getPrivate(), bobTransport,
|
||||
bobAcceptTimestamp, bobMacKey.getBytes());
|
||||
Remote remote = new Remote(true, alice, null,
|
||||
aliceEphemeral.getPublic().getEncoded(), aliceTransport,
|
||||
aliceEphemeral.getPublic(), aliceTransport,
|
||||
aliceAcceptTimestamp, null);
|
||||
byte[] bobMac =
|
||||
crypto.authMac(bobMacKey, introducer.getId(), bob.getId(),
|
||||
local, remote);
|
||||
byte[] bobMac = crypto.authMac(bobMacKey, introducer.getId(),
|
||||
bob.getId(), local, remote);
|
||||
|
||||
// verify from Alice's perspective
|
||||
crypto.verifyAuthMac(bobMac, bobMacKey, introducer.getId(),
|
||||
|
||||
@@ -42,9 +42,8 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
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.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.getTransportProperties;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTransportPropertiesMap;
|
||||
@@ -1149,8 +1148,7 @@ public class IntroductionIntegrationTest
|
||||
testModifiedResponse(
|
||||
m -> new AcceptMessage(m.getMessageId(), m.getGroupId(),
|
||||
m.getTimestamp(), m.getPreviousMessageId(),
|
||||
m.getSessionId(),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
m.getSessionId(), getAgreementPublicKey(),
|
||||
m.getAcceptTimestamp(), m.getTransportProperties())
|
||||
);
|
||||
}
|
||||
@@ -1216,8 +1214,8 @@ public class IntroductionIntegrationTest
|
||||
@ParametersNotNullByDefault
|
||||
private abstract class IntroductionListener implements EventListener {
|
||||
|
||||
protected volatile boolean aborted = false;
|
||||
protected volatile Event latestEvent;
|
||||
volatile boolean aborted = false;
|
||||
volatile Event latestEvent;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
IntroductionResponse getResponse() {
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
@@ -14,8 +15,9 @@ import org.junit.Test;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
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.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.getRandomId;
|
||||
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 String text = getRandomString(MAX_INTRODUCTION_TEXT_LENGTH);
|
||||
private final BdfDictionary meta = new BdfDictionary();
|
||||
private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
|
||||
private final long acceptTimestamp = 42;
|
||||
private final BdfDictionary transportProperties = BdfDictionary.of(
|
||||
new BdfEntry("transportId", new BdfDictionary())
|
||||
@@ -123,8 +126,9 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
@Test
|
||||
public void testAcceptsAccept() throws Exception {
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||
acceptTimestamp, transportProperties);
|
||||
expectParsePublicKey();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateTransportPropertiesMap(
|
||||
transportProperties);
|
||||
@@ -139,32 +143,31 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBodyForAccept() throws Exception {
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||
previousMsgId.getBytes(),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp);
|
||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||
acceptTimestamp);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBodyForAccept() throws Exception {
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||
acceptTimestamp, transportProperties, null);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInvalidSessionIdForAccept() throws Exception {
|
||||
BdfList body =
|
||||
BdfList.of(ACCEPT.getValue(), null, previousMsgId.getBytes(),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp,
|
||||
transportProperties);
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), null,
|
||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||
acceptTimestamp, transportProperties);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInvalidPreviousMsgIdForAccept() throws Exception {
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(), 1,
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), acceptTimestamp,
|
||||
ephemeralPublicKey.getEncoded(), acceptTimestamp,
|
||||
transportProperties);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
@@ -173,16 +176,17 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
public void testRejectsTooLongPublicKeyForAccept() throws Exception {
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||
previousMsgId.getBytes(),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), acceptTimestamp,
|
||||
transportProperties);
|
||||
getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES + 1),
|
||||
acceptTimestamp, transportProperties);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNegativeTimestampForAccept() throws Exception {
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||
previousMsgId.getBytes(), getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||
-1, transportProperties);
|
||||
expectParsePublicKey();
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@@ -190,9 +194,9 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
public void testRejectsEmptyTransportPropertiesForAccept()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(ACCEPT.getValue(), sessionId.getBytes(),
|
||||
previousMsgId.getBytes(),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), acceptTimestamp,
|
||||
new BdfDictionary());
|
||||
previousMsgId.getBytes(), ephemeralPublicKey.getEncoded(),
|
||||
acceptTimestamp, new BdfDictionary());
|
||||
expectParsePublicKey();
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@@ -271,8 +275,7 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInvalidPreviousMsgIdForAuth() throws Exception {
|
||||
BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(),
|
||||
1, getRandomBytes(MAC_BYTES),
|
||||
signature);
|
||||
1, getRandomBytes(MAC_BYTES), signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@@ -294,8 +297,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongMacForAuth() throws Exception {
|
||||
BdfList body = BdfList.of(AUTH.getValue(), sessionId.getBytes(),
|
||||
previousMsgId.getBytes(),
|
||||
getRandomBytes(MAC_BYTES + 1), signature);
|
||||
previousMsgId.getBytes(), getRandomBytes(MAC_BYTES + 1),
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@@ -360,9 +363,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInvalidSessionIdForActivate() throws Exception {
|
||||
BdfList body =
|
||||
BdfList.of(ACTIVATE.getValue(), null, previousMsgId.getBytes(),
|
||||
mac);
|
||||
BdfList body = BdfList.of(ACTIVATE.getValue(), null,
|
||||
previousMsgId.getBytes(), mac);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@@ -375,9 +377,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPreviousMsgIdNullForActivate() throws Exception {
|
||||
BdfList body =
|
||||
BdfList.of(ACTIVATE.getValue(), sessionId.getBytes(), null,
|
||||
mac);
|
||||
BdfList body = BdfList.of(ACTIVATE.getValue(), sessionId.getBytes(),
|
||||
null, mac);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@@ -434,6 +435,13 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
// Introduction Helper Methods
|
||||
//
|
||||
|
||||
private void expectParsePublicKey() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateAgreementPublicKey(
|
||||
ephemeralPublicKey.getEncoded());
|
||||
will(returnValue(ephemeralPublicKey));
|
||||
}});
|
||||
}
|
||||
private void expectEncodeRequestMetadata() {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageEncoder).encodeRequestMetadata(message.getTimestamp());
|
||||
@@ -443,9 +451,8 @@ public class IntroductionValidatorTest extends ValidatorTestCase {
|
||||
|
||||
private void expectEncodeMetadata(MessageType type) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageEncoder)
|
||||
.encodeMetadata(type, sessionId, message.getTimestamp(),
|
||||
false, false, false);
|
||||
oneOf(messageEncoder).encodeMetadata(type, sessionId,
|
||||
message.getTimestamp(), false, false, false);
|
||||
will(returnValue(meta));
|
||||
}});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.MetadataEncoder;
|
||||
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.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.getRandomBytes;
|
||||
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 Author author;
|
||||
private final String text = getRandomString(MAX_INTRODUCTION_TEXT_LENGTH);
|
||||
private final byte[] ephemeralPublicKey =
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
|
||||
private final byte[] mac = getRandomBytes(MAC_BYTES);
|
||||
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_BYTES);
|
||||
|
||||
@@ -173,7 +173,8 @@ public class MessageEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
assertEquals(m.getTimestamp(), am.getTimestamp());
|
||||
assertEquals(previousMsgId, am.getPreviousMessageId());
|
||||
assertEquals(sessionId, am.getSessionId());
|
||||
assertArrayEquals(ephemeralPublicKey, am.getEphemeralPublicKey());
|
||||
assertArrayEquals(ephemeralPublicKey.getEncoded(),
|
||||
am.getEphemeralPublicKey().getEncoded());
|
||||
assertEquals(acceptTimestamp, am.getAcceptTimestamp());
|
||||
assertEquals(transportProperties, am.getTransportProperties());
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.briarproject.briar.introduction;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
@@ -21,7 +23,8 @@ import java.util.Map;
|
||||
|
||||
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.getRandomId;
|
||||
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.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -64,13 +68,10 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
private final MessageId lastRemoteMessageId2 = new MessageId(getRandomId());
|
||||
private final Author author1;
|
||||
private final Author author2;
|
||||
private final byte[] ephemeralPublicKey =
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final byte[] ephemeralPrivateKey =
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final PublicKey ephemeralPublicKey = getAgreementPublicKey();
|
||||
private final PrivateKey ephemeralPrivateKey = getAgreementPrivateKey();
|
||||
private final byte[] masterKey = getRandomBytes(SecretKey.LENGTH);
|
||||
private final byte[] remoteEphemeralPublicKey =
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final PublicKey remoteEphemeralPublicKey = getAgreementPublicKey();
|
||||
private final Map<TransportId, TransportProperties> transportProperties =
|
||||
getTransportPropertiesMap(3);
|
||||
private final Map<TransportId, TransportProperties>
|
||||
@@ -193,13 +194,22 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
assertEquals(localTimestamp, s1.getLocal().lastMessageTimestamp);
|
||||
assertEquals(s1.getLocal().lastMessageTimestamp,
|
||||
s2.getLocal().lastMessageTimestamp);
|
||||
assertArrayEquals(ephemeralPublicKey, s1.getLocal().ephemeralPublicKey);
|
||||
assertArrayEquals(s1.getLocal().ephemeralPublicKey,
|
||||
s2.getLocal().ephemeralPublicKey);
|
||||
assertArrayEquals(ephemeralPrivateKey,
|
||||
s1.getLocal().ephemeralPrivateKey);
|
||||
assertArrayEquals(s1.getLocal().ephemeralPrivateKey,
|
||||
s2.getLocal().ephemeralPrivateKey);
|
||||
PublicKey s1LocalEphemeralPub = s1.getLocal().ephemeralPublicKey;
|
||||
PublicKey s2LocalEphemeralPub = s2.getLocal().ephemeralPublicKey;
|
||||
assertNotNull(s1LocalEphemeralPub);
|
||||
assertNotNull(s2LocalEphemeralPub);
|
||||
assertArrayEquals(ephemeralPublicKey.getEncoded(),
|
||||
s1LocalEphemeralPub.getEncoded());
|
||||
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(s1.getLocal().transportProperties,
|
||||
s2.getLocal().transportProperties);
|
||||
@@ -217,10 +227,14 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
assertEquals(lastRemoteMessageId, s1.getRemote().lastMessageId);
|
||||
assertEquals(s1.getRemote().lastMessageId,
|
||||
s2.getRemote().lastMessageId);
|
||||
assertArrayEquals(remoteEphemeralPublicKey,
|
||||
s1.getRemote().ephemeralPublicKey);
|
||||
assertArrayEquals(s1.getRemote().ephemeralPublicKey,
|
||||
s2.getRemote().ephemeralPublicKey);
|
||||
PublicKey s1RemoteEphemeralPub = s1.getRemote().ephemeralPublicKey;
|
||||
PublicKey s2RemoteEphemeralPub = s2.getRemote().ephemeralPublicKey;
|
||||
assertNotNull(s1RemoteEphemeralPub);
|
||||
assertNotNull(s2RemoteEphemeralPub);
|
||||
assertArrayEquals(remoteEphemeralPublicKey.getEncoded(),
|
||||
s1RemoteEphemeralPub.getEncoded());
|
||||
assertArrayEquals(s1RemoteEphemeralPub.getEncoded(),
|
||||
s2RemoteEphemeralPub.getEncoded());
|
||||
assertEquals(remoteTransportProperties,
|
||||
s1.getRemote().transportProperties);
|
||||
assertEquals(s1.getRemote().transportProperties,
|
||||
@@ -311,7 +325,7 @@ public class SessionEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
ephemeralPublicKey, ephemeralPrivateKey, transportProperties,
|
||||
acceptTimestamp, localMacKey);
|
||||
Remote remote = new Remote(false, author2, lastRemoteMessageId,
|
||||
remoteEphemeralPublicKey, remoteTransportProperties,
|
||||
remoteEphemeralPublicKey, remoteTransportProperties,
|
||||
remoteAcceptTimestamp, remoteMacKey);
|
||||
return new IntroduceeSession(sessionId, LOCAL_ACCEPTED,
|
||||
requestTimestamp, groupId1, author1, local, remote,
|
||||
|
||||
@@ -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_US;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
@@ -164,7 +165,7 @@ public class PrivateGroupIntegrationTest
|
||||
getGroupMember(groupManager2, author1.getId()).getVisibility());
|
||||
|
||||
// 1 reveals the contact relationship to 2
|
||||
assertTrue(contactId2From1 != null);
|
||||
assertNotNull(contactId2From1);
|
||||
groupInvitationManager1.revealRelationship(contactId2From1, groupId0);
|
||||
sync1To2(1, true);
|
||||
sync2To1(1, true);
|
||||
|
||||
@@ -458,8 +458,8 @@ public class GroupInvitationIntegrationTest
|
||||
sync1To0(1, true);
|
||||
}
|
||||
|
||||
private void sendInvitation(long timestamp, @Nullable String text) throws
|
||||
DbException {
|
||||
private void sendInvitation(long timestamp, @Nullable String text)
|
||||
throws DbException {
|
||||
byte[] signature = groupInvitationFactory.signInvitation(contact1From0,
|
||||
privateGroup0.getId(), timestamp, author0.getPrivateKey());
|
||||
groupInvitationManager0
|
||||
|
||||
Reference in New Issue
Block a user