From cd24be7e42b9e7864e8ae495017f58e107f1fe5b Mon Sep 17 00:00:00 2001 From: akwizgran <michael@briarproject.org> Date: Wed, 17 Apr 2019 18:06:58 +0100 Subject: [PATCH] Add unit tests for pending contact factory. --- .../contact/PendingContactFactoryImpl.java | 2 +- .../PendingContactFactoryImplTest.java | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 bramble-core/src/test/java/org/briarproject/bramble/contact/PendingContactFactoryImplTest.java diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/PendingContactFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/PendingContactFactoryImpl.java index 36a627013c..4e4ac27828 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/contact/PendingContactFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/PendingContactFactoryImpl.java @@ -44,7 +44,7 @@ class PendingContactFactoryImpl implements PendingContactFactory { private PublicKey parseHandshakeLink(String link) throws FormatException { Matcher matcher = LINK_REGEX.matcher(link); - if (!matcher.matches()) throw new FormatException(); + if (!matcher.find()) throw new FormatException(); link = matcher.group(); // Discard anything before or after the link if (link.startsWith("briar://")) link = link.substring(8); byte[] base32 = Base32.decode(link, false); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/contact/PendingContactFactoryImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/contact/PendingContactFactoryImplTest.java new file mode 100644 index 0000000000..bbcde760b3 --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/contact/PendingContactFactoryImplTest.java @@ -0,0 +1,121 @@ +package org.briarproject.bramble.contact; + +import org.briarproject.bramble.api.FormatException; +import org.briarproject.bramble.api.contact.PendingContact; +import org.briarproject.bramble.api.crypto.CryptoComponent; +import org.briarproject.bramble.api.crypto.KeyParser; +import org.briarproject.bramble.api.crypto.PublicKey; +import org.briarproject.bramble.api.system.Clock; +import org.briarproject.bramble.test.BrambleMockTestCase; +import org.briarproject.bramble.util.Base32; +import org.jmock.Expectations; +import org.junit.Test; + +import java.security.GeneralSecurityException; + +import static java.lang.System.arraycopy; +import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.BASE32_LINK_BYTES; +import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.FORMAT_VERSION; +import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL; +import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES; +import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION; +import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; +import static org.briarproject.bramble.test.TestUtils.getRandomBytes; +import static org.briarproject.bramble.test.TestUtils.getRandomId; +import static org.briarproject.bramble.util.StringUtils.getRandomString; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class PendingContactFactoryImplTest extends BrambleMockTestCase { + + private final CryptoComponent crypto = context.mock(CryptoComponent.class); + private final Clock clock = context.mock(Clock.class); + private final KeyParser keyParser = context.mock(KeyParser.class); + private final PublicKey publicKey = context.mock(PublicKey.class); + + private final PendingContactFactory pendingContactFactory = + new PendingContactFactoryImpl(crypto, clock); + private final String alias = getRandomString(MAX_AUTHOR_NAME_LENGTH); + private final byte[] publicKeyBytes = getRandomBytes(RAW_LINK_BYTES - 1); + private final byte[] idBytes = getRandomId(); + private final long timestamp = System.currentTimeMillis(); + + @Test(expected = FormatException.class) + public void testRejectsSyntacticallyInvalidLink() throws Exception { + pendingContactFactory.createPendingContact("briar://potato", alias); + } + + @Test(expected = FormatException.class) + public void testRejectsLinkWithUnknownFormatVersion() throws Exception { + String link = encodeLink(FORMAT_VERSION + 1); + pendingContactFactory.createPendingContact(link, alias); + } + + @Test(expected = FormatException.class) + public void testRejectsLinkWithInvalidPublicKey() throws Exception { + context.checking(new Expectations() {{ + oneOf(crypto).getAgreementKeyParser(); + will(returnValue(keyParser)); + oneOf(keyParser).parsePublicKey(with(equal(publicKeyBytes))); + will(throwException(new GeneralSecurityException())); + }}); + + pendingContactFactory.createPendingContact(encodeLink(), alias); + } + + @Test + public void testAcceptsValidLinkWithoutPrefix() throws Exception { + testAcceptsValidLink(encodeLink()); + } + + @Test + public void testAcceptsValidLinkWithPrefix() throws Exception { + testAcceptsValidLink("briar://" + encodeLink()); + } + + @Test + public void testAcceptsValidLinkWithRubbish() throws Exception { + testAcceptsValidLink("before " + encodeLink() + " after"); + } + + @Test + public void testAcceptsValidLinkWithPrefixAndRubbish() throws Exception { + testAcceptsValidLink("before briar://" + encodeLink() + " after"); + } + + private void testAcceptsValidLink(String link) throws Exception { + context.checking(new Expectations() {{ + oneOf(crypto).getAgreementKeyParser(); + will(returnValue(keyParser)); + oneOf(keyParser).parsePublicKey(with(equal(publicKeyBytes))); + will(returnValue(publicKey)); + allowing(publicKey).getEncoded(); + will(returnValue(publicKeyBytes)); + oneOf(crypto).hash(ID_LABEL, publicKeyBytes); + will(returnValue(idBytes)); + oneOf(clock).currentTimeMillis(); + will(returnValue(timestamp)); + }}); + + PendingContact p = + pendingContactFactory.createPendingContact(link, alias); + assertArrayEquals(idBytes, p.getId().getBytes()); + assertArrayEquals(publicKeyBytes, p.getPublicKey()); + assertEquals(alias, p.getAlias()); + assertEquals(WAITING_FOR_CONNECTION, p.getState()); + assertEquals(timestamp, p.getTimestamp()); + } + + private String encodeLink() { + return encodeLink(FORMAT_VERSION); + } + + private String encodeLink(int formatVersion) { + byte[] rawLink = new byte[RAW_LINK_BYTES]; + rawLink[0] = (byte) formatVersion; + arraycopy(publicKeyBytes, 0, rawLink, 1, publicKeyBytes.length); + String base32 = Base32.encode(rawLink).toLowerCase(); + assertEquals(BASE32_LINK_BYTES, base32.length()); + return base32; + } +} -- GitLab