diff --git a/.classpath b/.classpath
index 2f247967a..210b0bbcf 100644
--- a/.classpath
+++ b/.classpath
@@ -16,5 +16,6 @@
+
diff --git a/api/net/sf/briar/api/crypto/CryptoComponent.java b/api/net/sf/briar/api/crypto/CryptoComponent.java
new file mode 100644
index 000000000..3399127bc
--- /dev/null
+++ b/api/net/sf/briar/api/crypto/CryptoComponent.java
@@ -0,0 +1,17 @@
+package net.sf.briar.api.crypto;
+
+import java.security.KeyPair;
+import java.security.MessageDigest;
+import java.security.Signature;
+
+
+public interface CryptoComponent {
+
+ KeyPair generateKeyPair();
+
+ KeyParser getKeyParser();
+
+ MessageDigest getMessageDigest();
+
+ Signature getSignature();
+}
diff --git a/components/net/sf/briar/crypto/CryptoComponentImpl.java b/components/net/sf/briar/crypto/CryptoComponentImpl.java
new file mode 100644
index 000000000..ab0458e96
--- /dev/null
+++ b/components/net/sf/briar/crypto/CryptoComponentImpl.java
@@ -0,0 +1,66 @@
+package net.sf.briar.crypto;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.Signature;
+
+import net.sf.briar.api.crypto.CryptoComponent;
+import net.sf.briar.api.crypto.KeyParser;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+public class CryptoComponentImpl implements CryptoComponent {
+
+ private static final String PROVIDER = "BC";
+ private static final String DIGEST_ALGO = "SHA-256";
+ private static final String KEY_PAIR_ALGO = "RSA";
+ private static final String SIGNATURE_ALGO = "SHA256withRSA";
+
+ private final KeyParser keyParser;
+ private final KeyPairGenerator keyPairGenerator;
+
+ CryptoComponentImpl() {
+ Security.addProvider(new BouncyCastleProvider());
+ try {
+ keyParser = new KeyParserImpl(KEY_PAIR_ALGO, PROVIDER);
+ keyPairGenerator = KeyPairGenerator.getInstance(KEY_PAIR_ALGO,
+ PROVIDER);
+ } catch(NoSuchAlgorithmException impossible) {
+ throw new RuntimeException(impossible);
+ } catch(NoSuchProviderException impossible) {
+ throw new RuntimeException(impossible);
+ }
+ }
+
+ public KeyPair generateKeyPair() {
+ return keyPairGenerator.generateKeyPair();
+ }
+
+ public KeyParser getKeyParser() {
+ return keyParser;
+ }
+
+ public MessageDigest getMessageDigest() {
+ try {
+ return MessageDigest.getInstance(DIGEST_ALGO, PROVIDER);
+ } catch(NoSuchAlgorithmException impossible) {
+ throw new RuntimeException(impossible);
+ } catch(NoSuchProviderException impossible) {
+ throw new RuntimeException(impossible);
+ }
+ }
+
+ public Signature getSignature() {
+ try {
+ return Signature.getInstance(SIGNATURE_ALGO, PROVIDER);
+ } catch(NoSuchAlgorithmException impossible) {
+ throw new RuntimeException(impossible);
+ } catch(NoSuchProviderException impossible) {
+ throw new RuntimeException(impossible);
+ }
+ }
+}
diff --git a/components/net/sf/briar/crypto/CryptoModule.java b/components/net/sf/briar/crypto/CryptoModule.java
index 93240a483..1f6546a8c 100644
--- a/components/net/sf/briar/crypto/CryptoModule.java
+++ b/components/net/sf/briar/crypto/CryptoModule.java
@@ -1,60 +1,14 @@
package net.sf.briar.crypto;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.Signature;
-
-import net.sf.briar.api.crypto.KeyParser;
+import net.sf.briar.api.crypto.CryptoComponent;
import com.google.inject.AbstractModule;
-import com.google.inject.Provides;
+import com.google.inject.Singleton;
public class CryptoModule extends AbstractModule {
- private static final String DIGEST_ALGO = "SHA-256";
- private static final String KEY_PAIR_ALGO = "RSA";
- private static final String SIGNATURE_ALGO = "SHA256withRSA";
-
@Override
protected void configure() {
- try {
- bind(KeyParser.class).toInstance(new KeyParserImpl(KEY_PAIR_ALGO));
- } catch(NoSuchAlgorithmException e) {
- // FIXME: Can modules throw?
- throw new RuntimeException(e);
- }
- }
-
- @Provides
- MessageDigest getMessageDigest() {
- try {
- return MessageDigest.getInstance(DIGEST_ALGO);
- } catch(NoSuchAlgorithmException e) {
- // FIXME: Providers should not throw
- throw new RuntimeException(e);
- }
- }
-
- @Provides
- Signature getSignature() {
- try {
- return Signature.getInstance(SIGNATURE_ALGO);
- } catch(NoSuchAlgorithmException e) {
- // FIXME: Providers should not throw
- throw new RuntimeException(e);
- }
- }
-
- @Provides
- KeyPair generateKeyPair() {
- try {
- KeyPairGenerator gen = KeyPairGenerator.getInstance(KEY_PAIR_ALGO);
- return gen.generateKeyPair();
- } catch(NoSuchAlgorithmException e) {
- // FIXME: Providers should not throw
- throw new RuntimeException(e);
- }
+ bind(CryptoComponent.class).to(CryptoComponentImpl.class).in(Singleton.class);
}
}
diff --git a/components/net/sf/briar/crypto/KeyParserImpl.java b/components/net/sf/briar/crypto/KeyParserImpl.java
index 13ae3ee5f..ec875f60d 100644
--- a/components/net/sf/briar/crypto/KeyParserImpl.java
+++ b/components/net/sf/briar/crypto/KeyParserImpl.java
@@ -2,6 +2,7 @@ package net.sf.briar.crypto;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
@@ -13,8 +14,9 @@ class KeyParserImpl implements KeyParser {
private final KeyFactory keyFactory;
- KeyParserImpl(String algorithm) throws NoSuchAlgorithmException {
- keyFactory = KeyFactory.getInstance(algorithm);
+ KeyParserImpl(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException {
+ keyFactory = KeyFactory.getInstance(algorithm, provider);
}
public PublicKey parsePublicKey(byte[] encodedKey)
diff --git a/components/net/sf/briar/protocol/GroupFactoryImpl.java b/components/net/sf/briar/protocol/GroupFactoryImpl.java
index b76028565..f704a31e3 100644
--- a/components/net/sf/briar/protocol/GroupFactoryImpl.java
+++ b/components/net/sf/briar/protocol/GroupFactoryImpl.java
@@ -3,6 +3,7 @@ package net.sf.briar.protocol;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
+import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.crypto.KeyParser;
import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupFactory;
@@ -15,8 +16,8 @@ class GroupFactoryImpl implements GroupFactory {
private final KeyParser keyParser;
@Inject
- GroupFactoryImpl(KeyParser keyParser) {
- this.keyParser = keyParser;
+ GroupFactoryImpl(CryptoComponent crypto) {
+ keyParser = crypto.getKeyParser();
}
public Group createGroup(GroupId id, String name, boolean restricted,
diff --git a/components/net/sf/briar/protocol/MessageEncoderImpl.java b/components/net/sf/briar/protocol/MessageEncoderImpl.java
index 102f552e9..ef1107bae 100644
--- a/components/net/sf/briar/protocol/MessageEncoderImpl.java
+++ b/components/net/sf/briar/protocol/MessageEncoderImpl.java
@@ -7,6 +7,7 @@ import java.security.KeyPair;
import java.security.MessageDigest;
import java.security.Signature;
+import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
@@ -25,10 +26,9 @@ class MessageEncoderImpl implements MessageEncoder {
private final WriterFactory writerFactory;
@Inject
- MessageEncoderImpl(Signature signature, MessageDigest messageDigest,
- WriterFactory writerFactory) {
- this.signature = signature;
- this.messageDigest = messageDigest;
+ MessageEncoderImpl(CryptoComponent crypto, WriterFactory writerFactory) {
+ signature = crypto.getSignature();
+ messageDigest = crypto.getMessageDigest();
this.writerFactory = writerFactory;
}
diff --git a/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java b/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java
index 97294daa5..7d0959db5 100644
--- a/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java
+++ b/components/net/sf/briar/protocol/writers/PacketWriterFactoryImpl.java
@@ -3,6 +3,7 @@ package net.sf.briar.protocol.writers;
import java.io.OutputStream;
import java.security.MessageDigest;
+import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.protocol.writers.AckWriter;
import net.sf.briar.api.protocol.writers.BatchWriter;
import net.sf.briar.api.protocol.writers.PacketWriterFactory;
@@ -18,9 +19,9 @@ class PacketWriterFactoryImpl implements PacketWriterFactory {
private final WriterFactory writerFactory;
@Inject
- PacketWriterFactoryImpl(MessageDigest messageDigest,
+ PacketWriterFactoryImpl(CryptoComponent crypto,
WriterFactory writerFactory) {
- this.messageDigest = messageDigest;
+ messageDigest = crypto.getMessageDigest();
this.writerFactory = writerFactory;
}
diff --git a/lib/bcprov-jdk15-146.jar b/lib/bcprov-jdk15-146.jar
new file mode 100644
index 000000000..daa0b54cc
Binary files /dev/null and b/lib/bcprov-jdk15-146.jar differ
diff --git a/test/net/sf/briar/protocol/BatchReaderTest.java b/test/net/sf/briar/protocol/BatchReaderTest.java
index 7e58b5c26..54bb5042c 100644
--- a/test/net/sf/briar/protocol/BatchReaderTest.java
+++ b/test/net/sf/briar/protocol/BatchReaderTest.java
@@ -7,6 +7,7 @@ import java.security.MessageDigest;
import java.util.Collections;
import junit.framework.TestCase;
+import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.Message;
@@ -42,7 +43,7 @@ public class BatchReaderTest extends TestCase {
new CryptoModule());
readerFactory = i.getInstance(ReaderFactory.class);
writerFactory = i.getInstance(WriterFactory.class);
- messageDigest = i.getInstance(MessageDigest.class);
+ messageDigest = i.getInstance(CryptoComponent.class).getMessageDigest();
context = new Mockery();
message = context.mock(Message.class);
}
diff --git a/test/net/sf/briar/protocol/ConsumersTest.java b/test/net/sf/briar/protocol/ConsumersTest.java
index c2d16bf84..22c290830 100644
--- a/test/net/sf/briar/protocol/ConsumersTest.java
+++ b/test/net/sf/briar/protocol/ConsumersTest.java
@@ -7,6 +7,7 @@ import java.util.Arrays;
import java.util.Random;
import junit.framework.TestCase;
+import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.serial.FormatException;
import net.sf.briar.crypto.CryptoModule;
@@ -18,20 +19,18 @@ import com.google.inject.Injector;
public class ConsumersTest extends TestCase {
- private Signature signature = null;
- private KeyPair keyPair = null;
- private MessageDigest messageDigest = null;
+ private CryptoComponent crypto = null;
@Before
public void setUp() {
Injector i = Guice.createInjector(new CryptoModule());
- signature = i.getInstance(Signature.class);
- keyPair = i.getInstance(KeyPair.class);
- messageDigest = i.getInstance(MessageDigest.class);
+ crypto = i.getInstance(CryptoComponent.class);
}
@Test
public void testSigningConsumer() throws Exception {
+ Signature signature = crypto.getSignature();
+ KeyPair keyPair = crypto.generateKeyPair();
byte[] data = new byte[1234];
// Generate some random data and sign it
new Random().nextBytes(data);
@@ -50,6 +49,7 @@ public class ConsumersTest extends TestCase {
@Test
public void testDigestingConsumer() throws Exception {
+ MessageDigest messageDigest = crypto.getMessageDigest();
byte[] data = new byte[1234];
// Generate some random data and digest it
new Random().nextBytes(data);
diff --git a/test/net/sf/briar/protocol/FileReadWriteTest.java b/test/net/sf/briar/protocol/FileReadWriteTest.java
index 27a180459..62ad02a7f 100644
--- a/test/net/sf/briar/protocol/FileReadWriteTest.java
+++ b/test/net/sf/briar/protocol/FileReadWriteTest.java
@@ -13,6 +13,7 @@ import java.util.Iterator;
import junit.framework.TestCase;
import net.sf.briar.TestUtils;
+import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.crypto.KeyParser;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.Batch;
@@ -63,6 +64,7 @@ public class FileReadWriteTest extends TestCase {
private final ReaderFactory readerFactory;
private final WriterFactory writerFactory;
private final PacketWriterFactory packetWriterFactory;
+ private final CryptoComponent crypto;
private final Signature signature;
private final MessageDigest messageDigest, batchDigest;
private final KeyParser keyParser;
@@ -77,15 +79,16 @@ public class FileReadWriteTest extends TestCase {
readerFactory = i.getInstance(ReaderFactory.class);
writerFactory = i.getInstance(WriterFactory.class);
packetWriterFactory = i.getInstance(PacketWriterFactory.class);
- keyParser = i.getInstance(KeyParser.class);
- signature = i.getInstance(Signature.class);
- messageDigest = i.getInstance(MessageDigest.class);
- batchDigest = i.getInstance(MessageDigest.class);
+ crypto = i.getInstance(CryptoComponent.class);
+ keyParser = crypto.getKeyParser();
+ signature = crypto.getSignature();
+ messageDigest = crypto.getMessageDigest();
+ batchDigest = crypto.getMessageDigest();
assertEquals(messageDigest.getDigestLength(), UniqueId.LENGTH);
assertEquals(batchDigest.getDigestLength(), UniqueId.LENGTH);
// Create and encode a test message
MessageEncoder messageEncoder = i.getInstance(MessageEncoder.class);
- KeyPair keyPair = i.getInstance(KeyPair.class);
+ KeyPair keyPair = crypto.generateKeyPair();
message = messageEncoder.encodeMessage(MessageId.NONE, sub, nick,
keyPair, messageBody.getBytes("UTF-8"));
// Create a test group, then write and read it to calculate its ID
@@ -144,7 +147,7 @@ public class FileReadWriteTest extends TestCase {
ObjectReader batchReader = new BatchReader(batchDigest,
messageReader, new BatchFactoryImpl());
ObjectReader groupReader = new GroupReader(batchDigest,
- new GroupFactoryImpl(keyParser));
+ new GroupFactoryImpl(crypto));
ObjectReader subscriptionReader =
new SubscriptionReader(groupReader, new SubscriptionFactoryImpl());
ObjectReader transportReader =
diff --git a/test/net/sf/briar/protocol/SigningDigestingOutputStreamTest.java b/test/net/sf/briar/protocol/SigningDigestingOutputStreamTest.java
index a82f75e98..cf58b29fc 100644
--- a/test/net/sf/briar/protocol/SigningDigestingOutputStreamTest.java
+++ b/test/net/sf/briar/protocol/SigningDigestingOutputStreamTest.java
@@ -9,6 +9,7 @@ import java.util.Arrays;
import java.util.Random;
import junit.framework.TestCase;
+import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.crypto.CryptoModule;
import org.junit.Before;
@@ -19,20 +20,19 @@ import com.google.inject.Injector;
public class SigningDigestingOutputStreamTest extends TestCase {
- private Signature signature = null;
- private KeyPair keyPair = null;
- private MessageDigest messageDigest = null;
+ private CryptoComponent crypto = null;
@Before
public void setUp() throws Exception {
Injector i = Guice.createInjector(new CryptoModule());
- signature = i.getInstance(Signature.class);
- keyPair = i.getInstance(KeyPair.class);
- messageDigest = i.getInstance(MessageDigest.class);
+ crypto = i.getInstance(CryptoComponent.class);
}
@Test
public void testStopAndStart() throws Exception {
+ Signature signature = crypto.getSignature();
+ KeyPair keyPair = crypto.generateKeyPair();
+ MessageDigest messageDigest = crypto.getMessageDigest();
byte[] input = new byte[1024];
new Random().nextBytes(input);
ByteArrayOutputStream out = new ByteArrayOutputStream(input.length);
@@ -69,6 +69,8 @@ public class SigningDigestingOutputStreamTest extends TestCase {
@Test
public void testSignatureExceptionThrowsIOException() throws Exception {
+ Signature signature = crypto.getSignature();
+ MessageDigest messageDigest = crypto.getMessageDigest();
ByteArrayOutputStream out = new ByteArrayOutputStream();
SigningDigestingOutputStream s =
new SigningDigestingOutputStream(out, signature, messageDigest);