From af3e63f592bb076be15ba8715aa730b7dc11f9d0 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Tue, 9 Feb 2016 17:09:22 +0100 Subject: [PATCH] Improved tests for cryptography --- .../bitmessage/entity/payload/CryptoBox.java | 2 - .../bitmessage/security/CryptographyTest.java | 86 +++++++++++++++---- .../repository/JdbcMessageRepositoryTest.java | 7 +- 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/ch/dissem/bitmessage/entity/payload/CryptoBox.java b/core/src/main/java/ch/dissem/bitmessage/entity/payload/CryptoBox.java index fe45ac5..3d1c926 100644 --- a/core/src/main/java/ch/dissem/bitmessage/entity/payload/CryptoBox.java +++ b/core/src/main/java/ch/dissem/bitmessage/entity/payload/CryptoBox.java @@ -38,8 +38,6 @@ public class CryptoBox implements Streamable { private final byte[] mac; private byte[] encrypted; - private long addressVersion; - public CryptoBox(Streamable data, byte[] K) throws IOException { this(Encode.bytes(data), K); diff --git a/cryptography-bc/src/test/java/ch/dissem/bitmessage/security/CryptographyTest.java b/cryptography-bc/src/test/java/ch/dissem/bitmessage/security/CryptographyTest.java index d4ab2ad..ef3fcbf 100644 --- a/cryptography-bc/src/test/java/ch/dissem/bitmessage/security/CryptographyTest.java +++ b/cryptography-bc/src/test/java/ch/dissem/bitmessage/security/CryptographyTest.java @@ -4,19 +4,24 @@ import ch.dissem.bitmessage.InternalContext; import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography; import ch.dissem.bitmessage.entity.ObjectMessage; import ch.dissem.bitmessage.entity.payload.GenericPayload; +import ch.dissem.bitmessage.entity.valueobject.PrivateKey; import ch.dissem.bitmessage.ports.MultiThreadedPOWEngine; import ch.dissem.bitmessage.ports.ProofOfWorkEngine; import ch.dissem.bitmessage.utils.CallbackWaiter; import ch.dissem.bitmessage.utils.Singleton; import ch.dissem.bitmessage.utils.UnixTime; +import org.junit.BeforeClass; import org.junit.Test; import javax.xml.bind.DatatypeConverter; import java.io.ByteArrayInputStream; import java.io.IOException; +import static ch.dissem.bitmessage.utils.UnixTime.DAY; import static ch.dissem.bitmessage.utils.UnixTime.MINUTE; +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -33,50 +38,51 @@ public class CryptographyTest { public static final byte[] TEST_RIPEMD160 = DatatypeConverter.parseHexBinary("" + "cd566972b5e50104011a92b59fa8e0b1234851ae"); - private static BouncyCryptography security; + private static BouncyCryptography crypto; - public CryptographyTest() { - security = new BouncyCryptography(); - Singleton.initialize(security); + @BeforeClass + public static void setUp() { + crypto = new BouncyCryptography(); + Singleton.initialize(crypto); InternalContext ctx = mock(InternalContext.class); when(ctx.getProofOfWorkEngine()).thenReturn(new MultiThreadedPOWEngine()); - security.setContext(ctx); + crypto.setContext(ctx); } @Test public void testRipemd160() { - assertArrayEquals(TEST_RIPEMD160, security.ripemd160(TEST_VALUE)); + assertArrayEquals(TEST_RIPEMD160, crypto.ripemd160(TEST_VALUE)); } @Test public void testSha1() { - assertArrayEquals(TEST_SHA1, security.sha1(TEST_VALUE)); + assertArrayEquals(TEST_SHA1, crypto.sha1(TEST_VALUE)); } @Test public void testSha512() { - assertArrayEquals(TEST_SHA512, security.sha512(TEST_VALUE)); + assertArrayEquals(TEST_SHA512, crypto.sha512(TEST_VALUE)); } @Test public void testChaining() { - assertArrayEquals(TEST_SHA512, security.sha512("test".getBytes(), "string".getBytes())); + assertArrayEquals(TEST_SHA512, crypto.sha512("test".getBytes(), "string".getBytes())); } @Test - public void testDoubleHash() { - assertArrayEquals(security.sha512(TEST_SHA512), security.doubleSha512(TEST_VALUE)); + public void ensureDoubleHashYieldsSameResultAsHashOfHash() { + assertArrayEquals(crypto.sha512(TEST_SHA512), crypto.doubleSha512(TEST_VALUE)); } @Test(expected = IOException.class) - public void testProofOfWorkFails() throws IOException { + public void ensureExceptionForInsufficientProofOfWork() throws IOException { ObjectMessage objectMessage = new ObjectMessage.Builder() .nonce(new byte[8]) - .expiresTime(UnixTime.now(+2 * MINUTE)) + .expiresTime(UnixTime.now(+28 * DAY)) .objectType(0) .payload(GenericPayload.read(0, new ByteArrayInputStream(new byte[0]), 1, 0)) .build(); - security.checkProofOfWork(objectMessage, 1000, 1000); + crypto.checkProofOfWork(objectMessage, 1000, 1000); } @Test @@ -88,7 +94,7 @@ public class CryptographyTest { .payload(GenericPayload.read(0, new ByteArrayInputStream(new byte[0]), 1, 0)) .build(); final CallbackWaiter waiter = new CallbackWaiter<>(); - security.doProofOfWork(objectMessage, 1000, 1000, + crypto.doProofOfWork(objectMessage, 1000, 1000, new ProofOfWorkEngine.Callback() { @Override public void onNonceCalculated(byte[] initialHash, byte[] nonce) { @@ -96,6 +102,52 @@ public class CryptographyTest { } }); objectMessage.setNonce(waiter.waitForValue()); - security.checkProofOfWork(objectMessage, 1000, 1000); + crypto.checkProofOfWork(objectMessage, 1000, 1000); } -} \ No newline at end of file + + @Test + public void ensureEncryptionAndDecryptionWorks() { + byte[] data = crypto.randomBytes(100); + byte[] key_e = crypto.randomBytes(32); + byte[] iv = crypto.randomBytes(16); + byte[] encrypted = crypto.crypt(true, data, key_e, iv); + byte[] decrypted = crypto.crypt(false, encrypted, key_e, iv); + assertArrayEquals(data, decrypted); + } + + @Test(expected = IllegalArgumentException.class) + public void ensureDecryptionFailsWithInvalidCypherText() { + byte[] data = crypto.randomBytes(128); + byte[] key_e = crypto.randomBytes(32); + byte[] iv = crypto.randomBytes(16); + crypto.crypt(false, data, key_e, iv); + } + + @Test + public void testMultiplication() { + byte[] a = crypto.randomBytes(PrivateKey.PRIVATE_KEY_SIZE); + byte[] A = crypto.createPublicKey(a); + + byte[] b = crypto.randomBytes(PrivateKey.PRIVATE_KEY_SIZE); + byte[] B = crypto.createPublicKey(b); + + assertArrayEquals(crypto.multiply(A, b), crypto.multiply(B, a)); + } + + @Test + public void ensureSignatureIsValid() { + byte[] data = crypto.randomBytes(100); + PrivateKey privateKey = new PrivateKey(false, 1, 1000, 1000); + byte[] signature = crypto.getSignature(data, privateKey); + assertThat(crypto.isSignatureValid(data, signature, privateKey.getPubkey()), is(true)); + } + + @Test + public void ensureSignatureIsInvalidForTemperedData() { + byte[] data = crypto.randomBytes(100); + PrivateKey privateKey = new PrivateKey(false, 1, 1000, 1000); + byte[] signature = crypto.getSignature(data, privateKey); + data[0]++; + assertThat(crypto.isSignatureValid(data, signature, privateKey.getPubkey()), is(false)); + } +} diff --git a/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcMessageRepositoryTest.java b/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcMessageRepositoryTest.java index 4c93271..816eafa 100644 --- a/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcMessageRepositoryTest.java +++ b/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcMessageRepositoryTest.java @@ -30,7 +30,6 @@ import org.junit.Test; import java.util.Arrays; import java.util.List; -import java.util.Random; import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG; import static ch.dissem.bitmessage.utils.Singleton.security; @@ -42,8 +41,6 @@ public class JdbcMessageRepositoryTest extends TestBase { private BitmessageAddress contactB; private BitmessageAddress identity; - private TestJdbcConfig config; - private AddressRepository addressRepo; private MessageRepository repo; private Label inbox; @@ -52,9 +49,9 @@ public class JdbcMessageRepositoryTest extends TestBase { @Before public void setUp() throws Exception { - config = new TestJdbcConfig(); + TestJdbcConfig config = new TestJdbcConfig(); config.reset(); - addressRepo = new JdbcAddressRepository(config); + AddressRepository addressRepo = new JdbcAddressRepository(config); repo = new JdbcMessageRepository(config); new InternalContext(new BitmessageContext.Builder() .cryptography(security())