diff --git a/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java index 86ed51afb12f38f345522aa389ba7aa7970a846b..826524cc18ae7f9a0d86ca37befe6bd924827e5d 100644 --- a/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java +++ b/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java @@ -17,7 +17,6 @@ import org.briarproject.api.contact.ContactManager; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.KeyPair; import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.crypto.Signature; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfEntry; import org.briarproject.api.data.BdfList; @@ -95,6 +94,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE; import static org.briarproject.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.api.sync.ValidationManager.State.INVALID; +import static org.briarproject.introduction.IntroduceeManager.SIGNING_LABEL_RESPONSE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -922,10 +922,8 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest { byte[] nonce1 = crypto.deriveSignatureNonce(secretKey, true); // Signature 1 - Signature signature = crypto.getSignature(); - signature.initSign(keyPair1.getPrivate()); - signature.update(nonce1); - byte[] sig1 = signature.sign(); + byte[] sig1 = crypto.sign(SIGNING_LABEL_RESPONSE, nonce1, + keyPair1.getPrivate().getEncoded()); // MAC 1 SecretKey macKey1 = crypto.deriveMacKey(secretKey, true); diff --git a/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java b/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java index 90830ac1d54327a571c3871c3c5055416aca0995..60a606889a14f1ab846f0c512c467eb96b924561 100644 --- a/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java +++ b/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java @@ -16,8 +16,6 @@ public interface CryptoComponent { SecureRandom getSecureRandom(); - Signature getSignature(); - KeyPair generateAgreementKeyPair(); KeyParser getAgreementKeyParser(); @@ -149,7 +147,7 @@ public interface CryptoComponent { * @param label A label specific to this signature * to ensure that the signature cannot be repurposed */ - byte[] sign(String label, byte[] toSign, PrivateKey privateKey) + byte[] sign(String label, byte[] toSign, byte[] privateKey) throws GeneralSecurityException; /** @@ -160,7 +158,7 @@ public interface CryptoComponent { * to ensure that the signature cannot be repurposed * @return true if the signature was valid, false otherwise. */ - boolean verify(String label, byte[] signedData, PublicKey publicKey, + boolean verify(String label, byte[] signedData, byte[] publicKey, byte[] signature) throws GeneralSecurityException; /** diff --git a/briar-core/src/org/briarproject/clients/ClientHelperImpl.java b/briar-core/src/org/briarproject/clients/ClientHelperImpl.java index 77a3caad1f542e86987e489b146235d3fb0f38f6..bca3812f35a16366c1b570c58df898c8c0adc16d 100644 --- a/briar-core/src/org/briarproject/clients/ClientHelperImpl.java +++ b/briar-core/src/org/briarproject/clients/ClientHelperImpl.java @@ -3,9 +3,6 @@ package org.briarproject.clients; import org.briarproject.api.FormatException; import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.KeyParser; -import org.briarproject.api.crypto.PrivateKey; -import org.briarproject.api.crypto.PublicKey; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfList; import org.briarproject.api.data.BdfReader; @@ -347,19 +344,13 @@ class ClientHelperImpl implements ClientHelper { @Override public byte[] sign(String label, BdfList toSign, byte[] privateKey) throws FormatException, GeneralSecurityException { - KeyParser keyParser = crypto.getSignatureKeyParser(); - PrivateKey key = keyParser.parsePrivateKey(privateKey); - return crypto.sign(label, toByteArray(toSign), key); + return crypto.sign(label, toByteArray(toSign), privateKey); } @Override public void verifySignature(String label, byte[] sig, byte[] publicKey, BdfList signed) throws FormatException, GeneralSecurityException { - // Parse the public key - KeyParser keyParser = crypto.getSignatureKeyParser(); - PublicKey key = keyParser.parsePublicKey(publicKey); - // Verify the signature - if (!crypto.verify(label, toByteArray(signed), key, sig)) { + if (!crypto.verify(label, toByteArray(signed), publicKey, sig)) { throw new GeneralSecurityException("Invalid signature"); } } diff --git a/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java b/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java index 85eb36f9a63ea7900a38fff294d81f5d7fabc0e4..ec825052cc7643795930e40ab89d55b73c205484 100644 --- a/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java +++ b/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java @@ -7,9 +7,7 @@ import org.briarproject.api.contact.ContactExchangeTask; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.KeyParser; import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.crypto.Signature; import org.briarproject.api.data.BdfList; import org.briarproject.api.data.BdfReader; import org.briarproject.api.data.BdfReaderFactory; @@ -55,6 +53,8 @@ public class ContactExchangeTaskImpl extends Thread private static final Logger LOG = Logger.getLogger(ContactExchangeTaskImpl.class.getName()); + private static final String SIGNING_LABEL_EXCHANGE = + "org.briarproject.briar.contact/EXCHANGE"; private final DatabaseComponent db; private final AuthorFactory authorFactory; @@ -219,12 +219,9 @@ public class ContactExchangeTaskImpl extends Thread private void sendPseudonym(BdfWriter w, byte[] nonce) throws GeneralSecurityException, IOException { // Sign the nonce - Signature signature = crypto.getSignature(); - KeyParser keyParser = crypto.getSignatureKeyParser(); byte[] privateKey = localAuthor.getPrivateKey(); - signature.initSign(keyParser.parsePrivateKey(privateKey)); - signature.update(nonce); - byte[] sig = signature.sign(); + byte[] sig = crypto.sign(SIGNING_LABEL_EXCHANGE, nonce, privateKey); + // Write the name, public key and signature w.writeListStart(); w.writeString(localAuthor.getName()); @@ -244,11 +241,7 @@ public class ContactExchangeTaskImpl extends Thread r.readListEnd(); LOG.info("Received pseudonym"); // Verify the signature - Signature signature = crypto.getSignature(); - KeyParser keyParser = crypto.getSignatureKeyParser(); - signature.initVerify(keyParser.parsePublicKey(publicKey)); - signature.update(nonce); - if (!signature.verify(sig)) { + if (!crypto.verify(SIGNING_LABEL_EXCHANGE, nonce, publicKey, sig)) { if (LOG.isLoggable(INFO)) LOG.info("Invalid signature"); throw new GeneralSecurityException(); diff --git a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java index 3ce6e0e61acf4e31672c06f1d7887628952d3e12..eb98217947a30dc7a464033d3a94f5881557003a 100644 --- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java +++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java @@ -1,7 +1,5 @@ package org.briarproject.crypto; -import com.google.common.primitives.Bytes; - import org.briarproject.api.TransportId; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.KeyPair; @@ -166,11 +164,6 @@ class CryptoComponentImpl implements CryptoComponent { return secret; } - @Override - public Signature getSignature() { - return new SignatureImpl(secureRandom); - } - @Override public KeyPair generateAgreementKeyPair() { AsymmetricCipherKeyPair keyPair = @@ -402,25 +395,39 @@ class CryptoComponentImpl implements CryptoComponent { } @Override - public byte[] sign(String label, byte[] toSign, PrivateKey privateKey) + public byte[] sign(String label, byte[] toSign, byte[] privateKey) throws GeneralSecurityException { - Signature signature = getSignature(); - signature.initSign(privateKey); - toSign = Bytes.concat(StringUtils.toUtf8(label), toSign); - signature.update(toSign); + Signature signature = new SignatureImpl(secureRandom); + KeyParser keyParser = getSignatureKeyParser(); + PrivateKey key = keyParser.parsePrivateKey(privateKey); + signature.initSign(key); + updateSignature(signature, label, toSign); return signature.sign(); } @Override - public boolean verify(String label, byte[] signedData, PublicKey publicKey, + public boolean verify(String label, byte[] signedData, byte[] publicKey, byte[] signature) throws GeneralSecurityException { - Signature sig = getSignature(); - sig.initVerify(publicKey); - signedData = Bytes.concat(StringUtils.toUtf8(label), signedData); - sig.update(signedData); + Signature sig = new SignatureImpl(secureRandom); + KeyParser keyParser = getSignatureKeyParser(); + PublicKey key = keyParser.parsePublicKey(publicKey); + sig.initVerify(key); + updateSignature(sig, label, signedData); return sig.verify(signature); } + private void updateSignature(Signature signature, String label, + byte[] toSign) { + byte[] labelBytes = StringUtils.toUtf8(label); + byte[] length = new byte[INT_32_BYTES]; + ByteUtils.writeUint32(labelBytes.length, length, 0); + signature.update(length); + signature.update(labelBytes); + ByteUtils.writeUint32(toSign.length, length, 0); + signature.update(length); + signature.update(toSign); + } + @Override public byte[] hash(byte[]... inputs) { MessageDigest digest = getMessageDigest(); diff --git a/briar-core/src/org/briarproject/introduction/IntroduceeManager.java b/briar-core/src/org/briarproject/introduction/IntroduceeManager.java index 450fc023a39a017b21354abeabb101b2d082e181..e0227b6bc4f436820bd75407aa8169b2fd0a9bd6 100644 --- a/briar-core/src/org/briarproject/introduction/IntroduceeManager.java +++ b/briar-core/src/org/briarproject/introduction/IntroduceeManager.java @@ -13,7 +13,6 @@ import org.briarproject.api.crypto.KeyParser; import org.briarproject.api.crypto.PrivateKey; import org.briarproject.api.crypto.PublicKey; import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.crypto.Signature; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfList; import org.briarproject.api.db.DatabaseComponent; @@ -88,11 +87,13 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE; +import static org.briarproject.api.introduction.IntroductionManager.CLIENT_ID; class IntroduceeManager { private static final Logger LOG = Logger.getLogger(IntroduceeManager.class.getName()); + static final String SIGNING_LABEL_RESPONSE = CLIENT_ID + "/RESPONSE"; private final MessageSender messageSender; private final DatabaseComponent db; @@ -453,12 +454,8 @@ class IntroduceeManager { localState.put(MAC_KEY, theirMacKey.getBytes()); // Sign our nonce with our long-term identity public key - Signature signature = cryptoComponent.getSignature(); - KeyParser sigParser = cryptoComponent.getSignatureKeyParser(); - PrivateKey privKey = sigParser.parsePrivateKey(author.getPrivateKey()); - signature.initSign(privKey); - signature.update(ourNonce); - byte[] sig = signature.sign(); + byte[] sig = cryptoComponent + .sign(SIGNING_LABEL_RESPONSE, ourNonce, author.getPrivateKey()); // Calculate a MAC over identity public key, ephemeral public key, // transport properties and timestamp. @@ -479,16 +476,10 @@ class IntroduceeManager { throws FormatException, GeneralSecurityException { byte[] nonce = localState.getRaw(NONCE); byte[] sig = localState.getRaw(SIGNATURE); - byte[] keyBytes = localState.getRaw(PUBLIC_KEY); + byte[] key = localState.getRaw(PUBLIC_KEY); - // Parse the public key - KeyParser keyParser = cryptoComponent.getSignatureKeyParser(); - PublicKey key = keyParser.parsePublicKey(keyBytes); // Verify the signature - Signature signature = cryptoComponent.getSignature(); - signature.initVerify(key); - signature.update(nonce); - if (!signature.verify(sig)) { + if (!cryptoComponent.verify(SIGNING_LABEL_RESPONSE, nonce, key, sig)) { LOG.warning("Invalid nonce signature in ACK"); throw new GeneralSecurityException(); } diff --git a/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java b/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java index 7c79464517ca6fd4646c7b112b44562f1c4481f5..ccea806ff2037885b5580e02eb341da66816fb71 100644 --- a/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java +++ b/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java @@ -5,10 +5,6 @@ import org.briarproject.TestUtils; import org.briarproject.api.FormatException; import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.KeyParser; -import org.briarproject.api.crypto.PrivateKey; -import org.briarproject.api.crypto.PublicKey; -import org.briarproject.api.crypto.Signature; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfEntry; import org.briarproject.api.data.BdfList; @@ -58,8 +54,6 @@ public class ClientHelperImplTest extends BriarTestCase { context.mock(MetadataEncoder.class); private final CryptoComponent cryptoComponent = context.mock(CryptoComponent.class); - private final KeyParser keyParser = context.mock(KeyParser.class); - private final Signature signature = context.mock(Signature.class); private final ClientHelper clientHelper; private final GroupId groupId = new GroupId(getRandomId()); @@ -286,62 +280,46 @@ public class ClientHelperImplTest extends BriarTestCase { @Test public void testSign() throws Exception { - final byte[] privateKeyBytes = getRandomBytes(42); - final PrivateKey privateKey = context.mock(PrivateKey.class); + final byte[] privateKey = getRandomBytes(42); final byte[] signed = getRandomBytes(42); final byte[] bytes = expectToByteArray(list); context.checking(new Expectations() {{ - oneOf(cryptoComponent).getSignatureKeyParser(); - will(returnValue(keyParser)); - oneOf(keyParser).parsePrivateKey(privateKeyBytes); - will(returnValue(privateKey)); oneOf(cryptoComponent).sign(label, bytes, privateKey); will(returnValue(signed)); }}); - assertArrayEquals(signed, - clientHelper.sign(label, list, privateKeyBytes)); + assertArrayEquals(signed, clientHelper.sign(label, list, privateKey)); context.assertIsSatisfied(); } @Test public void testVerifySignature() throws Exception { - final PublicKey publicKey = context.mock(PublicKey.class); - final byte[] publicKeyBytes = getRandomBytes(42); - + final byte[] publicKey = getRandomBytes(42); final byte[] bytes = expectToByteArray(list); + context.checking(new Expectations() {{ - oneOf(cryptoComponent).getSignatureKeyParser(); - will(returnValue(keyParser)); - oneOf(keyParser).parsePublicKey(publicKeyBytes); - will(returnValue(publicKey)); oneOf(cryptoComponent).verify(label, bytes, publicKey, rawMessage); will(returnValue(true)); }}); - clientHelper.verifySignature(label, rawMessage, publicKeyBytes, list); + clientHelper.verifySignature(label, rawMessage, publicKey, list); context.assertIsSatisfied(); } @Test public void testVerifyWrongSignature() throws Exception { - final PublicKey publicKey = context.mock(PublicKey.class); - final byte[] publicKeyBytes = getRandomBytes(42); - + final byte[] publicKey = getRandomBytes(42); final byte[] bytes = expectToByteArray(list); + context.checking(new Expectations() {{ - oneOf(cryptoComponent).getSignatureKeyParser(); - will(returnValue(keyParser)); - oneOf(keyParser).parsePublicKey(publicKeyBytes); - will(returnValue(publicKey)); oneOf(cryptoComponent).verify(label, bytes, publicKey, rawMessage); will(returnValue(false)); }}); try { clientHelper - .verifySignature(label, rawMessage, publicKeyBytes, list); + .verifySignature(label, rawMessage, publicKey, list); fail(); } catch (GeneralSecurityException e) { // expected diff --git a/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java b/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java index d35da2762e08cc1f24e735a486d236162f2abc8b..b7abf54fb45abfe18a4d6648a2dd0e4301a3c551 100644 --- a/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java +++ b/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java @@ -7,7 +7,6 @@ import org.briarproject.api.crypto.KeyPair; import org.briarproject.api.crypto.KeyParser; import org.briarproject.api.crypto.PrivateKey; import org.briarproject.api.crypto.PublicKey; -import org.briarproject.api.crypto.Signature; import org.junit.Test; import java.security.GeneralSecurityException; @@ -102,15 +101,13 @@ public class KeyEncodingAndParsingTest extends BriarTestCase { @Test public void testSignatureLength() throws Exception { - Signature sig = crypto.getSignature(); // Generate 10 signature key pairs for (int i = 0; i < 10; i++) { KeyPair keyPair = crypto.generateSignatureKeyPair(); + byte[] key = keyPair.getPrivate().getEncoded(); // Sign some random data and check the length of the signature byte[] toBeSigned = TestUtils.getRandomBytes(1234); - sig.initSign(keyPair.getPrivate()); - sig.update(toBeSigned); - byte[] signature = sig.sign(); + byte[] signature = crypto.sign("label", toBeSigned, key); assertTrue(signature.length <= MAX_SIGNATURE_LENGTH); } } diff --git a/briar-tests/src/org/briarproject/crypto/MacTest.java b/briar-tests/src/org/briarproject/crypto/MacTest.java index 336d90952ca4c5dd990a72dddcb67862b902e630..c63fa66c299d864df7d875d051dfbfbe6dc9956a 100644 --- a/briar-tests/src/org/briarproject/crypto/MacTest.java +++ b/briar-tests/src/org/briarproject/crypto/MacTest.java @@ -16,18 +16,17 @@ public class MacTest extends BriarTestCase { private final CryptoComponent crypto; + private final SecretKey k = TestUtils.getSecretKey(); + private final byte[] inputBytes = TestUtils.getRandomBytes(123); + private final byte[] inputBytes1 = TestUtils.getRandomBytes(234); + private final byte[] inputBytes2 = new byte[0]; + public MacTest() { crypto = new CryptoComponentImpl(new TestSeedProvider()); } @Test public void testIdenticalKeysAndInputsProduceIdenticalMacs() { - // Generate a random key and some random input - byte[] keyBytes = TestUtils.getRandomBytes(SecretKey.LENGTH); - SecretKey k = new SecretKey(keyBytes); - byte[] inputBytes = TestUtils.getRandomBytes(123); - byte[] inputBytes1 = TestUtils.getRandomBytes(234); - byte[] inputBytes2 = new byte[0]; // Calculate the MAC twice - the results should be identical byte[] mac = crypto.mac(k, inputBytes, inputBytes1, inputBytes2); byte[] mac1 = crypto.mac(k, inputBytes, inputBytes1, inputBytes2); @@ -36,14 +35,8 @@ public class MacTest extends BriarTestCase { @Test public void testDifferentKeysProduceDifferentMacs() { - // Generate two random keys and some random input - byte[] keyBytes = TestUtils.getRandomBytes(SecretKey.LENGTH); - SecretKey k = new SecretKey(keyBytes); - byte[] keyBytes1 = TestUtils.getRandomBytes(SecretKey.LENGTH); - SecretKey k1 = new SecretKey(keyBytes1); - byte[] inputBytes = TestUtils.getRandomBytes(123); - byte[] inputBytes1 = TestUtils.getRandomBytes(234); - byte[] inputBytes2 = new byte[0]; + // Generate second random key + SecretKey k1 = TestUtils.getSecretKey(); // Calculate the MAC with each key - the results should be different byte[] mac = crypto.mac(k, inputBytes, inputBytes1, inputBytes2); byte[] mac1 = crypto.mac(k1, inputBytes, inputBytes1, inputBytes2); @@ -52,16 +45,11 @@ public class MacTest extends BriarTestCase { @Test public void testDifferentInputsProduceDifferentMacs() { - // Generate a random key and some random input - byte[] keyBytes = TestUtils.getRandomBytes(SecretKey.LENGTH); - SecretKey k = new SecretKey(keyBytes); - byte[] inputBytes = TestUtils.getRandomBytes(123); - byte[] inputBytes1 = TestUtils.getRandomBytes(234); - byte[] inputBytes2 = new byte[0]; // Calculate the MAC with the inputs in different orders - the results // should be different byte[] mac = crypto.mac(k, inputBytes, inputBytes1, inputBytes2); byte[] mac1 = crypto.mac(k, inputBytes2, inputBytes1, inputBytes); assertFalse(Arrays.equals(mac, mac1)); } + } diff --git a/briar-tests/src/org/briarproject/crypto/SignatureTest.java b/briar-tests/src/org/briarproject/crypto/SignatureTest.java new file mode 100644 index 0000000000000000000000000000000000000000..36d718540867bfe7eeec612db75605eef8c81861 --- /dev/null +++ b/briar-tests/src/org/briarproject/crypto/SignatureTest.java @@ -0,0 +1,109 @@ +package org.briarproject.crypto; + +import org.briarproject.BriarTestCase; +import org.briarproject.TestSeedProvider; +import org.briarproject.TestUtils; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.KeyPair; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class SignatureTest extends BriarTestCase { + + private final CryptoComponent crypto; + + private final byte[] publicKey, privateKey; + private final String label = TestUtils.getRandomString(42); + private final byte[] inputBytes = TestUtils.getRandomBytes(123); + + public SignatureTest() { + crypto = new CryptoComponentImpl(new TestSeedProvider()); + KeyPair k = crypto.generateSignatureKeyPair(); + publicKey = k.getPublic().getEncoded(); + privateKey = k.getPrivate().getEncoded(); + } + + @Test + public void testIdenticalKeysAndInputsProduceIdenticalSignatures() + throws Exception { + // Calculate the Signature twice - the results should be identical + byte[] sig1 = crypto.sign(label, inputBytes, privateKey); + byte[] sig2 = crypto.sign(label, inputBytes, privateKey); + assertArrayEquals(sig1, sig2); + } + + @Test + public void testDifferentKeysProduceDifferentSignatures() throws Exception { + // Generate second private key + KeyPair k2 = crypto.generateSignatureKeyPair(); + byte[] privateKey2 = k2.getPrivate().getEncoded(); + // Calculate the signature with each key + byte[] sig1 = crypto.sign(label, inputBytes, privateKey); + byte[] sig2 = crypto.sign(label, inputBytes, privateKey2); + assertFalse(Arrays.equals(sig1, sig2)); + } + + @Test + public void testDifferentInputsProduceDifferentSignatures() + throws Exception { + // Generate a second input + byte[] inputBytes2 = TestUtils.getRandomBytes(123); + // Calculate the signature with different inputs + // the results should be different + byte[] sig1 = crypto.sign(label, inputBytes, privateKey); + byte[] sig2 = crypto.sign(label, inputBytes2, privateKey); + assertFalse(Arrays.equals(sig1, sig2)); + } + + @Test + public void testDifferentLabelsProduceDifferentSignatures() + throws Exception { + // Generate a second label + String label2 = TestUtils.getRandomString(42); + // Calculate the signature with different inputs + // the results should be different + byte[] sig1 = crypto.sign(label, inputBytes, privateKey); + byte[] sig2 = crypto.sign(label2, inputBytes, privateKey); + assertFalse(Arrays.equals(sig1, sig2)); + } + + @Test + public void testSignatureVerification() throws Exception { + byte[] sig = crypto.sign(label, inputBytes, privateKey); + assertTrue(crypto.verify(label, inputBytes, publicKey, sig)); + } + + @Test + public void testDifferentKeyFailsVerification() throws Exception { + // Generate second private key + KeyPair k2 = crypto.generateSignatureKeyPair(); + byte[] privateKey2 = k2.getPrivate().getEncoded(); + // calculate the signature with different key, should fail to verify + byte[] sig = crypto.sign(label, inputBytes, privateKey2); + assertFalse(crypto.verify(label, inputBytes, publicKey, sig)); + } + + @Test + public void testDifferentInputFailsVerification() throws Exception { + // Generate a second input + byte[] inputBytes2 = TestUtils.getRandomBytes(123); + // calculate the signature with different input, should fail to verify + byte[] sig = crypto.sign(label, inputBytes, privateKey); + assertFalse(crypto.verify(label, inputBytes2, publicKey, sig)); + } + + @Test + public void testDifferentLabelFailsVerification() throws Exception { + // Generate a second label + String label2 = TestUtils.getRandomString(42); + // calculate the signature with different label, should fail to verify + byte[] sig = crypto.sign(label, inputBytes, privateKey); + assertFalse(crypto.verify(label2, inputBytes, publicKey, sig)); + } + +} diff --git a/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java b/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java index 2ac86ea65f61ba6fc18d0404f953d7706416808f..c33b308c665e0f5e9156f5277eb893607d15b300 100644 --- a/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java +++ b/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java @@ -10,10 +10,7 @@ import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.KeyParser; -import org.briarproject.api.crypto.PublicKey; import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.crypto.Signature; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfEntry; import org.briarproject.api.data.BdfList; @@ -77,6 +74,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE; import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; +import static org.briarproject.introduction.IntroduceeManager.SIGNING_LABEL_RESPONSE; import static org.hamcrest.Matchers.array; import static org.hamcrest.Matchers.samePropertyValuesAs; import static org.junit.Assert.assertFalse; @@ -91,11 +89,8 @@ public class IntroduceeManagerTest extends BriarTestCase { private final CryptoComponent cryptoComponent; private final ClientHelper clientHelper; private final IntroductionGroupFactory introductionGroupFactory; - private final MessageSender messageSender; - private final TransportPropertyManager transportPropertyManager; private final AuthorFactory authorFactory; private final ContactManager contactManager; - private final IdentityManager identityManager; private final Clock clock; private final Contact introducer; private final Contact introducee1; @@ -105,24 +100,24 @@ public class IntroduceeManagerTest extends BriarTestCase { private final Transaction txn; private final long time = 42L; private final Message localStateMessage; - private final ClientId clientId; private final SessionId sessionId; private final Message message1; public IntroduceeManagerTest() { context = new Mockery(); context.setImposteriser(ClassImposteriser.INSTANCE); - messageSender = context.mock(MessageSender.class); + MessageSender messageSender = context.mock(MessageSender.class); db = context.mock(DatabaseComponent.class); cryptoComponent = context.mock(CryptoComponent.class); clientHelper = context.mock(ClientHelper.class); clock = context.mock(Clock.class); introductionGroupFactory = context.mock(IntroductionGroupFactory.class); - transportPropertyManager = context.mock(TransportPropertyManager.class); + TransportPropertyManager transportPropertyManager = + context.mock(TransportPropertyManager.class); authorFactory = context.mock(AuthorFactory.class); contactManager = context.mock(ContactManager.class); - identityManager = context.mock(IdentityManager.class); + IdentityManager identityManager = context.mock(IdentityManager.class); introduceeManager = new IntroduceeManager(messageSender, db, clientHelper, clock, cryptoComponent, transportPropertyManager, @@ -152,7 +147,7 @@ public class IntroduceeManagerTest extends BriarTestCase { introducee2 = new Contact(contactId2, author2, localAuthorId, true, true); - clientId = IntroductionManagerImpl.CLIENT_ID; + ClientId clientId = IntroductionManagerImpl.CLIENT_ID; localGroup1 = new Group(new GroupId(TestUtils.getRandomId()), clientId, new byte[0]); introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()), @@ -270,20 +265,9 @@ public class IntroduceeManagerTest extends BriarTestCase { new BdfEntry(SIGNATURE, sig) ); - final KeyParser keyParser = context.mock(KeyParser.class); - final PublicKey publicKey = context.mock(PublicKey.class); - final Signature signature = context.mock(Signature.class); context.checking(new Expectations() {{ - oneOf(cryptoComponent).getSignatureKeyParser(); - will(returnValue(keyParser)); - oneOf(keyParser) - .parsePublicKey(introducee2.getAuthor().getPublicKey()); - will(returnValue(publicKey)); - oneOf(cryptoComponent).getSignature(); - will(returnValue(signature)); - oneOf(signature).initVerify(publicKey); - oneOf(signature).update(nonce); - oneOf(signature).verify(sig); + oneOf(cryptoComponent).verify(SIGNING_LABEL_RESPONSE, nonce, + introducee2.getAuthor().getPublicKey(), sig); will(returnValue(false)); }}); @@ -311,19 +295,9 @@ public class IntroduceeManagerTest extends BriarTestCase { state.put(NONCE, nonce); state.put(SIGNATURE, sig); - final KeyParser keyParser = context.mock(KeyParser.class); - final Signature signature = context.mock(Signature.class); - final PublicKey publicKey = context.mock(PublicKey.class); context.checking(new Expectations() {{ - oneOf(cryptoComponent).getSignatureKeyParser(); - will(returnValue(keyParser)); - oneOf(keyParser).parsePublicKey(publicKeyBytes); - will(returnValue(publicKey)); - oneOf(cryptoComponent).getSignature(); - will(returnValue(signature)); - oneOf(signature).initVerify(publicKey); - oneOf(signature).update(nonce); - oneOf(signature).verify(sig); + oneOf(cryptoComponent).verify(SIGNING_LABEL_RESPONSE, nonce, + publicKeyBytes, sig); will(returnValue(true)); }}); introduceeManager.verifySignature(state);