mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Migrate all custom signature code to new methods and add test
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
109
briar-tests/src/org/briarproject/crypto/SignatureTest.java
Normal file
109
briar-tests/src/org/briarproject/crypto/SignatureTest.java
Normal file
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user