mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Factor out key agreement crypto from CryptoComponent.
This commit is contained in:
@@ -36,22 +36,14 @@ public interface CryptoComponent {
|
||||
* Derives a nonce from the given secret key that can be used for key
|
||||
* binding.
|
||||
*
|
||||
* TODO: This just calls mac(), remove it
|
||||
*
|
||||
* @param label a namespaced label indicating the purpose of this nonce,
|
||||
* to prevent it from being repurposed or colliding with a nonce derived
|
||||
* for another purpose
|
||||
*/
|
||||
byte[] deriveKeyBindingNonce(String label, SecretKey k);
|
||||
|
||||
/**
|
||||
* Derives a commitment to the provided public key.
|
||||
* <p/>
|
||||
* Used by the key exchange protocol.
|
||||
*
|
||||
* @param publicKey the public key
|
||||
* @return the commitment to the provided public key.
|
||||
*/
|
||||
byte[] deriveKeyCommitment(PublicKey publicKey);
|
||||
|
||||
/**
|
||||
* Derives a common shared secret from two public keys and one of the
|
||||
* corresponding private keys.
|
||||
@@ -67,25 +59,6 @@ public interface CryptoComponent {
|
||||
SecretKey deriveSharedSecret(String label, PublicKey theirPublicKey,
|
||||
KeyPair ourKeyPair, boolean alice) throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Derives the content of a confirmation record.
|
||||
* <p/>
|
||||
* Used by the key exchange protocol.
|
||||
*
|
||||
* @param sharedSecret the common shared secret
|
||||
* @param theirPayload the key exchange payload of the remote party
|
||||
* @param ourPayload the key exchange payload of the local party
|
||||
* @param theirPublicKey the ephemeral public key of the remote party
|
||||
* @param ourKeyPair our ephemeral key pair of the local party
|
||||
* @param alice true if the local party is Alice
|
||||
* @param aliceRecord true if the confirmation record is for use by Alice
|
||||
* @return the confirmation record
|
||||
*/
|
||||
byte[] deriveConfirmationRecord(SecretKey sharedSecret,
|
||||
byte[] theirPayload, byte[] ourPayload,
|
||||
PublicKey theirPublicKey, KeyPair ourKeyPair,
|
||||
boolean alice, boolean aliceRecord);
|
||||
|
||||
/**
|
||||
* Signs the given byte[] with the given ECDSA private key.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.briarproject.bramble.api.crypto;
|
||||
|
||||
public interface KeyAgreementCrypto {
|
||||
|
||||
/**
|
||||
* Hash label for public key commitment.
|
||||
*/
|
||||
String COMMIT_LABEL = "org.briarproject.bramble.keyagreement/COMMIT";
|
||||
|
||||
/**
|
||||
* Key derivation label for confirmation record.
|
||||
*/
|
||||
String CONFIRMATION_KEY_LABEL =
|
||||
"org.briarproject.bramble.keyagreement/CONFIRMATION_KEY";
|
||||
|
||||
/**
|
||||
* MAC label for confirmation record.
|
||||
*/
|
||||
String CONFIRMATION_MAC_LABEL =
|
||||
"org.briarproject.bramble.keyagreement/CONFIRMATION_MAC";
|
||||
|
||||
/**
|
||||
* Derives a commitment to the provided public key.
|
||||
* <p/>
|
||||
* Used by the key exchange protocol.
|
||||
*
|
||||
* @param publicKey the public key
|
||||
* @return the commitment to the provided public key.
|
||||
*/
|
||||
byte[] deriveKeyCommitment(PublicKey publicKey);
|
||||
|
||||
/**
|
||||
* Derives the content of a confirmation record.
|
||||
* <p/>
|
||||
* Used by the key exchange protocol.
|
||||
*
|
||||
* @param sharedSecret the common shared secret
|
||||
* @param theirPayload the key exchange payload of the remote party
|
||||
* @param ourPayload the key exchange payload of the local party
|
||||
* @param theirPublicKey the ephemeral public key of the remote party
|
||||
* @param ourKeyPair our ephemeral key pair of the local party
|
||||
* @param alice true if the local party is Alice
|
||||
* @param aliceRecord true if the confirmation record is for use by Alice
|
||||
* @return the confirmation record
|
||||
*/
|
||||
byte[] deriveConfirmationRecord(SecretKey sharedSecret,
|
||||
byte[] theirPayload, byte[] ourPayload,
|
||||
PublicKey theirPublicKey, KeyPair ourKeyPair,
|
||||
boolean alice, boolean aliceRecord);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package org.briarproject.bramble.api.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
/**
|
||||
* Manages tasks for conducting key agreements with remote peers.
|
||||
*/
|
||||
@NotNullByDefault
|
||||
public interface KeyAgreementTaskFactory {
|
||||
|
||||
/**
|
||||
* Gets the current key agreement task.
|
||||
*/
|
||||
KeyAgreementTask createTask();
|
||||
}
|
||||
@@ -39,7 +39,6 @@ import java.util.logging.Logger;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||
import static org.briarproject.bramble.crypto.EllipticCurveConstants.PARAMETERS;
|
||||
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
||||
|
||||
@@ -56,16 +55,6 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
private static final int PBKDF_TARGET_MILLIS = 500;
|
||||
private static final int PBKDF_SAMPLES = 30;
|
||||
|
||||
// Hash label for BQP public key commitment derivation
|
||||
private static final String COMMIT_LABEL =
|
||||
"org.briarproject.bramble.keyagreement/COMMIT";
|
||||
// KDF label for BQP confirmation key derivation
|
||||
private static final String CONFIRMATION_KEY_LABEL =
|
||||
"org.briarproject.bramble.keyagreement/CONFIRMATION_KEY";
|
||||
// MAC label for BQP confirmation record
|
||||
private static final String CONFIRMATION_MAC_LABEL =
|
||||
"org.briarproject.bramble.keyagreement/CONFIRMATION_MAC";
|
||||
|
||||
private final SecureRandom secureRandom;
|
||||
private final ECKeyPairGenerator agreementKeyPairGenerator;
|
||||
private final ECKeyPairGenerator signatureKeyPairGenerator;
|
||||
@@ -230,23 +219,13 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretKey deriveKey(String label, SecretKey k,
|
||||
byte[]... inputs) {
|
||||
return new SecretKey(macKdf(label, k, inputs));
|
||||
public SecretKey deriveKey(String label, SecretKey k, byte[]... inputs) {
|
||||
return new SecretKey(mac(label, k, inputs));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] deriveKeyBindingNonce(String label, SecretKey k) {
|
||||
return macKdf(label, k);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] deriveKeyCommitment(PublicKey publicKey) {
|
||||
byte[] hash = hash(COMMIT_LABEL, publicKey.getEncoded());
|
||||
// The output is the first COMMIT_LENGTH bytes of the hash
|
||||
byte[] commitment = new byte[COMMIT_LENGTH];
|
||||
System.arraycopy(hash, 0, commitment, 0, COMMIT_LENGTH);
|
||||
return commitment;
|
||||
return mac(label, k);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -265,32 +244,6 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
return new SecretKey(hash(label, raw, alicePub, bobPub));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] deriveConfirmationRecord(SecretKey sharedSecret,
|
||||
byte[] theirPayload, byte[] ourPayload, PublicKey theirPublicKey,
|
||||
KeyPair ourKeyPair, boolean alice, boolean aliceRecord) {
|
||||
SecretKey ck = deriveKey(CONFIRMATION_KEY_LABEL, sharedSecret);
|
||||
byte[] alicePayload, alicePub, bobPayload, bobPub;
|
||||
if (alice) {
|
||||
alicePayload = ourPayload;
|
||||
alicePub = ourKeyPair.getPublic().getEncoded();
|
||||
bobPayload = theirPayload;
|
||||
bobPub = theirPublicKey.getEncoded();
|
||||
} else {
|
||||
alicePayload = theirPayload;
|
||||
alicePub = theirPublicKey.getEncoded();
|
||||
bobPayload = ourPayload;
|
||||
bobPub = ourKeyPair.getPublic().getEncoded();
|
||||
}
|
||||
if (aliceRecord) {
|
||||
return macKdf(CONFIRMATION_MAC_LABEL, ck, alicePayload, alicePub,
|
||||
bobPayload, bobPub);
|
||||
} else {
|
||||
return macKdf(CONFIRMATION_MAC_LABEL, ck, bobPayload, bobPub,
|
||||
alicePayload, alicePub);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign(String label, byte[] toSign, byte[] privateKey)
|
||||
throws GeneralSecurityException {
|
||||
@@ -464,15 +417,6 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
return AsciiArmour.wrap(b, lineLength);
|
||||
}
|
||||
|
||||
// Key derivation function based on a pseudo-random function - see
|
||||
// NIST SP 800-108, section 5.1
|
||||
private byte[] macKdf(String label, SecretKey k, byte[]... inputs) {
|
||||
byte[] mac = mac(label, k, inputs);
|
||||
// The output of the PRF must be usable as a key
|
||||
if (mac.length != SecretKey.LENGTH) throw new IllegalStateException();
|
||||
return mac;
|
||||
}
|
||||
|
||||
// Password-based key derivation function - see PKCS#5 v2.1, section 5.2
|
||||
private byte[] pbkdf2(String password, byte[] salt, int iterations) {
|
||||
byte[] utf8 = StringUtils.toUtf8(password);
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.crypto;
|
||||
import org.briarproject.bramble.TimeLoggingExecutor;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
||||
import org.briarproject.bramble.api.crypto.StreamDecrypterFactory;
|
||||
import org.briarproject.bramble.api.crypto.StreamEncrypterFactory;
|
||||
@@ -95,6 +96,12 @@ public class CryptoModule {
|
||||
cipherProvider);
|
||||
}
|
||||
|
||||
@Provides
|
||||
KeyAgreementCrypto provideKeyAgreementCrypto(
|
||||
KeyAgreementCryptoImpl keyAgreementCrypto) {
|
||||
return keyAgreementCrypto;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@CryptoExecutor
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||
|
||||
class KeyAgreementCryptoImpl implements KeyAgreementCrypto {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
|
||||
@Inject
|
||||
KeyAgreementCryptoImpl(CryptoComponent crypto) {
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] deriveKeyCommitment(PublicKey publicKey) {
|
||||
byte[] hash = crypto.hash(COMMIT_LABEL, publicKey.getEncoded());
|
||||
// The output is the first COMMIT_LENGTH bytes of the hash
|
||||
byte[] commitment = new byte[COMMIT_LENGTH];
|
||||
System.arraycopy(hash, 0, commitment, 0, COMMIT_LENGTH);
|
||||
return commitment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] deriveConfirmationRecord(SecretKey sharedSecret,
|
||||
byte[] theirPayload, byte[] ourPayload, PublicKey theirPublicKey,
|
||||
KeyPair ourKeyPair, boolean alice, boolean aliceRecord) {
|
||||
SecretKey ck = crypto.deriveKey(CONFIRMATION_KEY_LABEL, sharedSecret);
|
||||
byte[] alicePayload, alicePub, bobPayload, bobPub;
|
||||
if (alice) {
|
||||
alicePayload = ourPayload;
|
||||
alicePub = ourKeyPair.getPublic().getEncoded();
|
||||
bobPayload = theirPayload;
|
||||
bobPub = theirPublicKey.getEncoded();
|
||||
} else {
|
||||
alicePayload = theirPayload;
|
||||
alicePub = theirPublicKey.getEncoded();
|
||||
bobPayload = ourPayload;
|
||||
bobPub = ourKeyPair.getPublic().getEncoded();
|
||||
}
|
||||
if (aliceRecord) {
|
||||
return crypto.mac(CONFIRMATION_MAC_LABEL, ck, alicePayload,
|
||||
alicePub, bobPayload, bobPub);
|
||||
} else {
|
||||
return crypto.mac(CONFIRMATION_MAC_LABEL, ck, bobPayload, bobPub,
|
||||
alicePayload, alicePub);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection;
|
||||
@@ -46,7 +46,7 @@ class KeyAgreementConnector {
|
||||
|
||||
private final Callbacks callbacks;
|
||||
private final Clock clock;
|
||||
private final CryptoComponent crypto;
|
||||
private final KeyAgreementCrypto keyAgreementCrypto;
|
||||
private final PluginManager pluginManager;
|
||||
private final CompletionService<KeyAgreementConnection> connect;
|
||||
|
||||
@@ -58,11 +58,11 @@ class KeyAgreementConnector {
|
||||
private volatile boolean alice = false;
|
||||
|
||||
KeyAgreementConnector(Callbacks callbacks, Clock clock,
|
||||
CryptoComponent crypto, PluginManager pluginManager,
|
||||
KeyAgreementCrypto keyAgreementCrypto, PluginManager pluginManager,
|
||||
Executor ioExecutor) {
|
||||
this.callbacks = callbacks;
|
||||
this.clock = clock;
|
||||
this.crypto = crypto;
|
||||
this.keyAgreementCrypto = keyAgreementCrypto;
|
||||
this.pluginManager = pluginManager;
|
||||
connect = new ExecutorCompletionService<>(ioExecutor);
|
||||
}
|
||||
@@ -70,8 +70,8 @@ class KeyAgreementConnector {
|
||||
public Payload listen(KeyPair localKeyPair) {
|
||||
LOG.info("Starting BQP listeners");
|
||||
// Derive commitment
|
||||
byte[] commitment =
|
||||
crypto.deriveKeyCommitment(localKeyPair.getPublic());
|
||||
byte[] commitment = keyAgreementCrypto.deriveKeyCommitment(
|
||||
localKeyPair.getPublic());
|
||||
// Start all listeners and collect their descriptors
|
||||
List<TransportDescriptor> descriptors = new ArrayList<>();
|
||||
for (DuplexPlugin plugin : pluginManager.getKeyAgreementPlugins()) {
|
||||
|
||||
@@ -1,19 +1,10 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTaskFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
@@ -22,13 +13,9 @@ import dagger.Provides;
|
||||
public class KeyAgreementModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
KeyAgreementTaskFactory provideKeyAgreementTaskFactory(Clock clock,
|
||||
CryptoComponent crypto, EventBus eventBus,
|
||||
@IoExecutor Executor ioExecutor, PayloadEncoder payloadEncoder,
|
||||
PluginManager pluginManager) {
|
||||
return new KeyAgreementTaskFactoryImpl(clock, crypto, eventBus,
|
||||
ioExecutor, payloadEncoder, pluginManager);
|
||||
KeyAgreementTask provideKeyAgreementTask(
|
||||
KeyAgreementTaskImpl keyAgreementTask) {
|
||||
return keyAgreementTask;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.crypto.KeyParser;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
@@ -62,6 +63,7 @@ class KeyAgreementProtocol {
|
||||
|
||||
private final Callbacks callbacks;
|
||||
private final CryptoComponent crypto;
|
||||
private final KeyAgreementCrypto keyAgreementCrypto;
|
||||
private final PayloadEncoder payloadEncoder;
|
||||
private final KeyAgreementTransport transport;
|
||||
private final Payload theirPayload, ourPayload;
|
||||
@@ -69,11 +71,13 @@ class KeyAgreementProtocol {
|
||||
private final boolean alice;
|
||||
|
||||
KeyAgreementProtocol(Callbacks callbacks, CryptoComponent crypto,
|
||||
KeyAgreementCrypto keyAgreementCrypto,
|
||||
PayloadEncoder payloadEncoder, KeyAgreementTransport transport,
|
||||
Payload theirPayload, Payload ourPayload, KeyPair ourKeyPair,
|
||||
boolean alice) {
|
||||
this.callbacks = callbacks;
|
||||
this.crypto = crypto;
|
||||
this.keyAgreementCrypto = keyAgreementCrypto;
|
||||
this.payloadEncoder = payloadEncoder;
|
||||
this.transport = transport;
|
||||
this.theirPayload = theirPayload;
|
||||
@@ -126,7 +130,7 @@ class KeyAgreementProtocol {
|
||||
KeyParser keyParser = crypto.getAgreementKeyParser();
|
||||
try {
|
||||
PublicKey publicKey = keyParser.parsePublicKey(publicKeyBytes);
|
||||
byte[] expected = crypto.deriveKeyCommitment(publicKey);
|
||||
byte[] expected = keyAgreementCrypto.deriveKeyCommitment(publicKey);
|
||||
if (!Arrays.equals(expected, theirPayload.getCommitment()))
|
||||
throw new AbortException();
|
||||
return publicKey;
|
||||
@@ -147,7 +151,7 @@ class KeyAgreementProtocol {
|
||||
|
||||
private void sendConfirm(SecretKey s, PublicKey theirPublicKey)
|
||||
throws IOException {
|
||||
byte[] confirm = crypto.deriveConfirmationRecord(s,
|
||||
byte[] confirm = keyAgreementCrypto.deriveConfirmationRecord(s,
|
||||
payloadEncoder.encode(theirPayload),
|
||||
payloadEncoder.encode(ourPayload),
|
||||
theirPublicKey, ourKeyPair,
|
||||
@@ -158,7 +162,7 @@ class KeyAgreementProtocol {
|
||||
private void receiveConfirm(SecretKey s, PublicKey theirPublicKey)
|
||||
throws AbortException {
|
||||
byte[] confirm = transport.receiveConfirm();
|
||||
byte[] expected = crypto.deriveConfirmationRecord(s,
|
||||
byte[] expected = keyAgreementCrypto.deriveConfirmationRecord(s,
|
||||
payloadEncoder.encode(theirPayload),
|
||||
payloadEncoder.encode(ourPayload),
|
||||
theirPublicKey, ourKeyPair,
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTaskFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class KeyAgreementTaskFactoryImpl implements KeyAgreementTaskFactory {
|
||||
|
||||
private final Clock clock;
|
||||
private final CryptoComponent crypto;
|
||||
private final EventBus eventBus;
|
||||
private final Executor ioExecutor;
|
||||
private final PayloadEncoder payloadEncoder;
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
@Inject
|
||||
KeyAgreementTaskFactoryImpl(Clock clock, CryptoComponent crypto,
|
||||
EventBus eventBus, @IoExecutor Executor ioExecutor,
|
||||
PayloadEncoder payloadEncoder, PluginManager pluginManager) {
|
||||
this.clock = clock;
|
||||
this.crypto = crypto;
|
||||
this.eventBus = eventBus;
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.payloadEncoder = payloadEncoder;
|
||||
this.pluginManager = pluginManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyAgreementTask createTask() {
|
||||
return new KeyAgreementTaskImpl(clock, crypto, eventBus, payloadEncoder,
|
||||
pluginManager, ioExecutor);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
@@ -14,6 +15,7 @@ import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFinishedEvent
|
||||
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementListeningEvent;
|
||||
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementStartedEvent;
|
||||
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementWaitingEvent;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||
@@ -23,6 +25,8 @@ import java.io.IOException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -35,6 +39,7 @@ class KeyAgreementTaskImpl extends Thread implements
|
||||
Logger.getLogger(KeyAgreementTaskImpl.class.getName());
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final KeyAgreementCrypto keyAgreementCrypto;
|
||||
private final EventBus eventBus;
|
||||
private final PayloadEncoder payloadEncoder;
|
||||
private final KeyPair localKeyPair;
|
||||
@@ -43,14 +48,17 @@ class KeyAgreementTaskImpl extends Thread implements
|
||||
private Payload localPayload;
|
||||
private Payload remotePayload;
|
||||
|
||||
@Inject
|
||||
KeyAgreementTaskImpl(Clock clock, CryptoComponent crypto,
|
||||
EventBus eventBus, PayloadEncoder payloadEncoder,
|
||||
PluginManager pluginManager, Executor ioExecutor) {
|
||||
KeyAgreementCrypto keyAgreementCrypto, EventBus eventBus,
|
||||
PayloadEncoder payloadEncoder, PluginManager pluginManager,
|
||||
@IoExecutor Executor ioExecutor) {
|
||||
this.crypto = crypto;
|
||||
this.keyAgreementCrypto = keyAgreementCrypto;
|
||||
this.eventBus = eventBus;
|
||||
this.payloadEncoder = payloadEncoder;
|
||||
localKeyPair = crypto.generateAgreementKeyPair();
|
||||
connector = new KeyAgreementConnector(this, clock, crypto,
|
||||
connector = new KeyAgreementConnector(this, clock, keyAgreementCrypto,
|
||||
pluginManager, ioExecutor);
|
||||
}
|
||||
|
||||
@@ -100,8 +108,8 @@ class KeyAgreementTaskImpl extends Thread implements
|
||||
// Run BQP protocol over the connection
|
||||
LOG.info("Starting BQP protocol");
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(this, crypto,
|
||||
payloadEncoder, transport, remotePayload, localPayload,
|
||||
localKeyPair, alice);
|
||||
keyAgreementCrypto, payloadEncoder, transport, remotePayload,
|
||||
localPayload, localKeyPair, alice);
|
||||
try {
|
||||
SecretKey master = protocol.perform();
|
||||
KeyAgreementResult result =
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.crypto.KeyParser;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
@@ -55,6 +56,8 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Mock
|
||||
CryptoComponent crypto;
|
||||
@Mock
|
||||
KeyAgreementCrypto keyAgreementCrypto;
|
||||
@Mock
|
||||
KeyParser keyParser;
|
||||
@Mock
|
||||
PayloadEncoder payloadEncoder;
|
||||
@@ -72,9 +75,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
SecretKey masterSecret = getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
transport, theirPayload, ourPayload, ourKeyPair, true);
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
theirPayload, ourPayload, ourKeyPair, true);
|
||||
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
@@ -100,7 +103,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(bobPubKey));
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
oneOf(crypto).deriveKeyCommitment(bobPubKey);
|
||||
oneOf(keyAgreementCrypto).deriveKeyCommitment(bobPubKey);
|
||||
will(returnValue(bobCommit));
|
||||
|
||||
// Alice computes shared secret
|
||||
@@ -109,8 +112,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(sharedSecret));
|
||||
|
||||
// Alice sends her confirmation record
|
||||
oneOf(crypto).deriveConfirmationRecord(sharedSecret, bobPayload,
|
||||
alicePayload, bobPubKey, ourKeyPair, true, true);
|
||||
oneOf(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
bobPayload, alicePayload, bobPubKey, ourKeyPair,
|
||||
true, true);
|
||||
will(returnValue(aliceConfirm));
|
||||
oneOf(transport).sendConfirm(aliceConfirm);
|
||||
|
||||
@@ -119,8 +123,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(bobConfirm));
|
||||
|
||||
// Alice verifies Bob's confirmation record
|
||||
oneOf(crypto).deriveConfirmationRecord(sharedSecret, bobPayload,
|
||||
alicePayload, bobPubKey, ourKeyPair, true, false);
|
||||
oneOf(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
bobPayload, alicePayload, bobPubKey, ourKeyPair,
|
||||
true, false);
|
||||
will(returnValue(bobConfirm));
|
||||
|
||||
// Alice computes master secret
|
||||
@@ -141,9 +146,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
SecretKey masterSecret = getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
transport, theirPayload, ourPayload, ourKeyPair, false);
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
theirPayload, ourPayload, ourKeyPair, false);
|
||||
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
@@ -165,7 +170,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(alicePubKey));
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
oneOf(crypto).deriveKeyCommitment(alicePubKey);
|
||||
oneOf(keyAgreementCrypto).deriveKeyCommitment(alicePubKey);
|
||||
will(returnValue(aliceCommit));
|
||||
|
||||
// Bob sends his public key
|
||||
@@ -181,13 +186,15 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(aliceConfirm));
|
||||
|
||||
// Bob verifies Alice's confirmation record
|
||||
oneOf(crypto).deriveConfirmationRecord(sharedSecret, alicePayload,
|
||||
bobPayload, alicePubKey, ourKeyPair, false, true);
|
||||
oneOf(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
alicePayload, bobPayload, alicePubKey, ourKeyPair,
|
||||
false, true);
|
||||
will(returnValue(aliceConfirm));
|
||||
|
||||
// Bob sends his confirmation record
|
||||
oneOf(crypto).deriveConfirmationRecord(sharedSecret, alicePayload,
|
||||
bobPayload, alicePubKey, ourKeyPair, false, false);
|
||||
oneOf(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
alicePayload, bobPayload, alicePubKey, ourKeyPair,
|
||||
false, false);
|
||||
will(returnValue(bobConfirm));
|
||||
oneOf(transport).sendConfirm(bobConfirm);
|
||||
|
||||
@@ -207,9 +214,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
Payload ourPayload = new Payload(aliceCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
transport, theirPayload, ourPayload, ourKeyPair, true);
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
theirPayload, ourPayload, ourKeyPair, true);
|
||||
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
@@ -231,7 +238,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(badPubKey));
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
oneOf(crypto).deriveKeyCommitment(badPubKey);
|
||||
oneOf(keyAgreementCrypto).deriveKeyCommitment(badPubKey);
|
||||
will(returnValue(badCommit));
|
||||
|
||||
// Alice aborts
|
||||
@@ -253,9 +260,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
Payload ourPayload = new Payload(bobCommit, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
transport, theirPayload, ourPayload, ourKeyPair, false);
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
theirPayload, ourPayload, ourKeyPair, false);
|
||||
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
@@ -273,7 +280,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(badPubKey));
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
oneOf(crypto).deriveKeyCommitment(badPubKey);
|
||||
oneOf(keyAgreementCrypto).deriveKeyCommitment(badPubKey);
|
||||
will(returnValue(badCommit));
|
||||
|
||||
// Bob aborts
|
||||
@@ -295,9 +302,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
transport, theirPayload, ourPayload, ourKeyPair, true);
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
theirPayload, ourPayload, ourKeyPair, true);
|
||||
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
@@ -323,7 +330,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(bobPubKey));
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
oneOf(crypto).deriveKeyCommitment(bobPubKey);
|
||||
oneOf(keyAgreementCrypto).deriveKeyCommitment(bobPubKey);
|
||||
will(returnValue(bobCommit));
|
||||
|
||||
// Alice computes shared secret
|
||||
@@ -332,8 +339,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(sharedSecret));
|
||||
|
||||
// Alice sends her confirmation record
|
||||
oneOf(crypto).deriveConfirmationRecord(sharedSecret, bobPayload,
|
||||
alicePayload, bobPubKey, ourKeyPair, true, true);
|
||||
oneOf(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
bobPayload, alicePayload, bobPubKey, ourKeyPair,
|
||||
true, true);
|
||||
will(returnValue(aliceConfirm));
|
||||
oneOf(transport).sendConfirm(aliceConfirm);
|
||||
|
||||
@@ -342,8 +350,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(badConfirm));
|
||||
|
||||
// Alice verifies Bob's confirmation record
|
||||
oneOf(crypto).deriveConfirmationRecord(sharedSecret, bobPayload,
|
||||
alicePayload, bobPubKey, ourKeyPair, true, false);
|
||||
oneOf(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
bobPayload, alicePayload, bobPubKey, ourKeyPair,
|
||||
true, false);
|
||||
will(returnValue(bobConfirm));
|
||||
|
||||
// Alice aborts
|
||||
@@ -365,9 +374,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
SecretKey sharedSecret = getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
transport, theirPayload, ourPayload, ourKeyPair, false);
|
||||
KeyAgreementProtocol protocol = new KeyAgreementProtocol(callbacks,
|
||||
crypto, keyAgreementCrypto, payloadEncoder, transport,
|
||||
theirPayload, ourPayload, ourKeyPair, false);
|
||||
|
||||
// expectations
|
||||
context.checking(new Expectations() {{
|
||||
@@ -389,7 +398,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(alicePubKey));
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
oneOf(crypto).deriveKeyCommitment(alicePubKey);
|
||||
oneOf(keyAgreementCrypto).deriveKeyCommitment(alicePubKey);
|
||||
will(returnValue(aliceCommit));
|
||||
|
||||
// Bob sends his public key
|
||||
@@ -405,16 +414,18 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
will(returnValue(badConfirm));
|
||||
|
||||
// Bob verifies Alice's confirmation record
|
||||
oneOf(crypto).deriveConfirmationRecord(sharedSecret, alicePayload,
|
||||
bobPayload, alicePubKey, ourKeyPair, false, true);
|
||||
oneOf(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
alicePayload, bobPayload, alicePubKey, ourKeyPair,
|
||||
false, true);
|
||||
will(returnValue(aliceConfirm));
|
||||
|
||||
// Bob aborts
|
||||
oneOf(transport).sendAbort(false);
|
||||
|
||||
// Bob never sends his confirmation record
|
||||
never(crypto).deriveConfirmationRecord(sharedSecret, alicePayload,
|
||||
bobPayload, alicePubKey, ourKeyPair, false, false);
|
||||
never(keyAgreementCrypto).deriveConfirmationRecord(sharedSecret,
|
||||
alicePayload, bobPayload, alicePubKey, ourKeyPair,
|
||||
false, false);
|
||||
}});
|
||||
|
||||
// execute
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTaskFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
@@ -125,7 +125,7 @@ public interface AndroidComponent
|
||||
|
||||
ContactExchangeTask contactExchangeTask();
|
||||
|
||||
KeyAgreementTaskFactory keyAgreementTaskFactory();
|
||||
KeyAgreementTask keyAgreementTask();
|
||||
|
||||
PayloadEncoder payloadEncoder();
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.google.zxing.Result;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTaskFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
||||
@@ -48,6 +47,7 @@ import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
|
||||
import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
|
||||
@@ -68,7 +68,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
private static final Logger LOG = Logger.getLogger(TAG);
|
||||
|
||||
@Inject
|
||||
KeyAgreementTaskFactory keyAgreementTaskFactory;
|
||||
Provider<KeyAgreementTask> keyAgreementTaskProvider;
|
||||
@Inject
|
||||
PayloadEncoder payloadEncoder;
|
||||
@Inject
|
||||
@@ -187,7 +187,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
@UiThread
|
||||
private void startListening() {
|
||||
KeyAgreementTask oldTask = task;
|
||||
KeyAgreementTask newTask = keyAgreementTaskFactory.createTask();
|
||||
KeyAgreementTask newTask = keyAgreementTaskProvider.get();
|
||||
task = newTask;
|
||||
ioExecutor.execute(() -> {
|
||||
if (oldTask != null) oldTask.stopListening();
|
||||
|
||||
Reference in New Issue
Block a user