From cc87e6fd1f1f0199863881e7fbd90a18960683b8 Mon Sep 17 00:00:00 2001 From: akwizgran <michael@briarproject.org> Date: Tue, 28 Nov 2017 10:20:11 +0000 Subject: [PATCH] Factor out key agreement crypto from CryptoComponent. --- .../bramble/api/crypto/CryptoComponent.java | 31 +------ .../api/crypto/KeyAgreementCrypto.java | 50 ++++++++++ .../keyagreement/KeyAgreementTaskFactory.java | 15 --- .../bramble/crypto/CryptoComponentImpl.java | 62 +------------ .../bramble/crypto/CryptoModule.java | 7 ++ .../crypto/KeyAgreementCryptoImpl.java | 56 ++++++++++++ .../keyagreement/KeyAgreementConnector.java | 12 +-- .../keyagreement/KeyAgreementModule.java | 21 +---- .../keyagreement/KeyAgreementProtocol.java | 10 +- .../KeyAgreementTaskFactoryImpl.java | 46 ---------- .../keyagreement/KeyAgreementTaskImpl.java | 18 +++- .../KeyAgreementProtocolTest.java | 91 +++++++++++-------- .../briar/android/AndroidComponent.java | 4 +- .../keyagreement/ShowQrCodeFragment.java | 6 +- 14 files changed, 204 insertions(+), 225 deletions(-) create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyAgreementCrypto.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementTaskFactory.java create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/crypto/KeyAgreementCryptoImpl.java delete mode 100644 bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskFactoryImpl.java diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java index 5fef176712..90f9da6f09 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java @@ -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. * diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyAgreementCrypto.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyAgreementCrypto.java new file mode 100644 index 0000000000..1dcf7ebf8b --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/KeyAgreementCrypto.java @@ -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); +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementTaskFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementTaskFactory.java deleted file mode 100644 index 40d875cc9d..0000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/keyagreement/KeyAgreementTaskFactory.java +++ /dev/null @@ -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(); -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java index 4a04c28a19..5e2985ef8e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java @@ -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); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java index 9988910459..a40b656282 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoModule.java @@ -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 diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/KeyAgreementCryptoImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/KeyAgreementCryptoImpl.java new file mode 100644 index 0000000000..db2f19a7bc --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/KeyAgreementCryptoImpl.java @@ -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); + } + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java index 2ed0b95211..89bf01ee0d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java @@ -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()) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementModule.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementModule.java index 9875387db9..e7ec82dabb 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementModule.java @@ -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 diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocol.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocol.java index be4895ff06..a5c24c6e42 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocol.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocol.java @@ -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, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskFactoryImpl.java deleted file mode 100644 index 4d9dc00cf6..0000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskFactoryImpl.java +++ /dev/null @@ -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); - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskImpl.java index de6dcecf75..e0d97313dc 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementTaskImpl.java @@ -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 = diff --git a/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java b/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java index 25d882d782..c6c55ce040 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/keyagreement/KeyAgreementProtocolTest.java @@ -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 diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index 763c50332d..1c6cc9d86f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -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(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java index 54df56f3ae..fd0d464454 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java @@ -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(); -- GitLab