Compare commits

...

7 Commits

Author SHA1 Message Date
Sebastian Kürten
426909f735 Make strict mode warnings configurable 2022-06-29 15:15:29 +02:00
akwizgran
b9ba7aded5 Merge branch 'string-utils-checked-exceptions' into 'master'
Let StringUtils throw FormatException instead of IllegalArgumentException

See merge request briar/briar!1682
2022-06-29 12:21:29 +00:00
Sebastian Kürten
4bca9decc1 Let StringUtils throw FormatException instead of IllegalArgumentException 2022-06-29 14:13:42 +02:00
akwizgran
63060679a3 Merge branch '2342-mailbox-setup-stuck' into 'master'
Ensure that mailbox setup can proceed after activity was destroyed

Closes #2342

See merge request briar/briar!1678
2022-06-26 13:04:34 +00:00
Torsten Grote
ddb759dbb8 Merge branch 'mailbox-base-url-refactoring' into 'master'
Refactor MailboxProperties to hold raw onion address

See merge request briar/briar!1680
2022-06-23 17:27:17 +00:00
akwizgran
feb8854678 Add @Inject constructor. 2022-06-23 14:22:25 +01:00
Torsten Grote
1af52b21d5 Ensure that mailbox setup can proceed after activity was destroyed 2022-06-22 11:44:07 -03:00
32 changed files with 277 additions and 119 deletions

View File

@@ -2,6 +2,7 @@ package org.briarproject.bramble.api.mailbox;
import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonValue;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.UniqueId; import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -32,7 +33,7 @@ public abstract class MailboxId extends UniqueId {
} }
try { try {
return fromHexString(token); return fromHexString(token);
} catch (IllegalArgumentException e) { } catch (FormatException e) {
throw new InvalidMailboxIdException(); throw new InvalidMailboxIdException();
} }
} }

View File

@@ -11,7 +11,7 @@ import javax.annotation.concurrent.Immutable;
@NotNullByDefault @NotNullByDefault
public class MailboxProperties { public class MailboxProperties {
private final String baseUrl; private final String onion;
private final MailboxAuthToken authToken; private final MailboxAuthToken authToken;
private final boolean owner; private final boolean owner;
private final List<MailboxVersion> serverSupports; private final List<MailboxVersion> serverSupports;
@@ -23,9 +23,9 @@ public class MailboxProperties {
/** /**
* Constructor for properties used by the mailbox's owner. * Constructor for properties used by the mailbox's owner.
*/ */
public MailboxProperties(String baseUrl, MailboxAuthToken authToken, public MailboxProperties(String onion, MailboxAuthToken authToken,
List<MailboxVersion> serverSupports) { List<MailboxVersion> serverSupports) {
this.baseUrl = baseUrl; this.onion = onion;
this.authToken = authToken; this.authToken = authToken;
this.owner = true; this.owner = true;
this.serverSupports = serverSupports; this.serverSupports = serverSupports;
@@ -36,10 +36,10 @@ public class MailboxProperties {
/** /**
* Constructor for properties used by a contact of the mailbox's owner. * Constructor for properties used by a contact of the mailbox's owner.
*/ */
public MailboxProperties(String baseUrl, MailboxAuthToken authToken, public MailboxProperties(String onion, MailboxAuthToken authToken,
List<MailboxVersion> serverSupports, MailboxFolderId inboxId, List<MailboxVersion> serverSupports, MailboxFolderId inboxId,
MailboxFolderId outboxId) { MailboxFolderId outboxId) {
this.baseUrl = baseUrl; this.onion = onion;
this.authToken = authToken; this.authToken = authToken;
this.owner = false; this.owner = false;
this.serverSupports = serverSupports; this.serverSupports = serverSupports;
@@ -47,13 +47,11 @@ public class MailboxProperties {
this.outboxId = outboxId; this.outboxId = outboxId;
} }
public String getBaseUrl() { /**
return baseUrl; * Returns the onion address of the mailbox, excluding the .onion suffix.
} */
public String getOnion() { public String getOnion() {
return baseUrl.replaceFirst("^http://", "") return onion;
.replaceFirst("\\.onion$", "");
} }
public MailboxAuthToken getAuthToken() { public MailboxAuthToken getAuthToken() {

View File

@@ -29,19 +29,35 @@ public interface MailboxUpdateManager {
/** /**
* The number of properties required for an update message with a mailbox. * The number of properties required for an update message with a mailbox.
* <p>
* The required properties are {@link #PROP_KEY_ONION},
* {@link #PROP_KEY_AUTHTOKEN}, {@link #PROP_KEY_INBOXID} and
* {@link #PROP_KEY_OUTBOXID}.
*/ */
int PROP_COUNT = 4; int PROP_COUNT = 4;
/** /**
* The required properties of an update message with a mailbox. * The onion address of the mailbox, excluding the .onion suffix.
*/ */
String PROP_KEY_ONION = "onion"; String PROP_KEY_ONION = "onion";
/**
* A bearer token for accessing the mailbox (64 hex digits).
*/
String PROP_KEY_AUTHTOKEN = "authToken"; String PROP_KEY_AUTHTOKEN = "authToken";
/**
* A folder ID for downloading messages (64 hex digits).
*/
String PROP_KEY_INBOXID = "inboxId"; String PROP_KEY_INBOXID = "inboxId";
/**
* A folder ID for uploading messages (64 hex digits).
*/
String PROP_KEY_OUTBOXID = "outboxId"; String PROP_KEY_OUTBOXID = "outboxId";
/** /**
* Length of the Onion property. * Length of the {@link #PROP_KEY_ONION} property.
*/ */
int PROP_ONION_LENGTH = 56; int PROP_ONION_LENGTH = 56;

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.util; package org.briarproject.bramble.util;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@@ -95,10 +96,10 @@ public class StringUtils {
/** /**
* Converts the given hex string to a byte array. * Converts the given hex string to a byte array.
*/ */
public static byte[] fromHexString(String hex) { public static byte[] fromHexString(String hex) throws FormatException {
int len = hex.length(); int len = hex.length();
if (len % 2 != 0) if (len % 2 != 0)
throw new IllegalArgumentException("Not a hex string"); throw new FormatException();
byte[] bytes = new byte[len / 2]; byte[] bytes = new byte[len / 2];
for (int i = 0, j = 0; i < len; i += 2, j++) { for (int i = 0, j = 0; i < len; i += 2, j++) {
int high = hexDigitToInt(hex.charAt(i)); int high = hexDigitToInt(hex.charAt(i));
@@ -108,11 +109,11 @@ public class StringUtils {
return bytes; return bytes;
} }
private static int hexDigitToInt(char c) { private static int hexDigitToInt(char c) throws FormatException {
if (c >= '0' && c <= '9') return c - '0'; if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'a' && c <= 'f') return c - 'a' + 10;
throw new IllegalArgumentException("Not a hex digit: " + c); throw new FormatException();
} }
public static String trim(String s) { public static String trim(String s) {
@@ -130,13 +131,13 @@ public class StringUtils {
return MAC.matcher(mac).matches(); return MAC.matcher(mac).matches();
} }
public static byte[] macToBytes(String mac) { public static byte[] macToBytes(String mac) throws FormatException {
if (!MAC.matcher(mac).matches()) throw new IllegalArgumentException(); if (!MAC.matcher(mac).matches()) throw new FormatException();
return fromHexString(mac.replaceAll(":", "")); return fromHexString(mac.replaceAll(":", ""));
} }
public static String macToString(byte[] mac) { public static String macToString(byte[] mac) throws FormatException {
if (mac.length != 6) throw new IllegalArgumentException(); if (mac.length != 6) throw new FormatException();
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
for (byte b : mac) { for (byte b : mac) {
if (s.length() > 0) s.append(':'); if (s.length() > 0) s.append(':');

View File

@@ -230,14 +230,14 @@ public class TestUtils {
public static MailboxProperties getMailboxProperties(boolean owner, public static MailboxProperties getMailboxProperties(boolean owner,
List<MailboxVersion> serverSupports) { List<MailboxVersion> serverSupports) {
String baseUrl = "http://" + getRandomString(56) + ".onion"; // TODO String onion = getRandomString(56);
MailboxAuthToken authToken = new MailboxAuthToken(getRandomId()); MailboxAuthToken authToken = new MailboxAuthToken(getRandomId());
if (owner) { if (owner) {
return new MailboxProperties(baseUrl, authToken, serverSupports); return new MailboxProperties(onion, authToken, serverSupports);
} }
MailboxFolderId inboxId = new MailboxFolderId(getRandomId()); MailboxFolderId inboxId = new MailboxFolderId(getRandomId());
MailboxFolderId outboxId = new MailboxFolderId(getRandomId()); MailboxFolderId outboxId = new MailboxFolderId(getRandomId());
return new MailboxProperties(baseUrl, authToken, serverSupports, return new MailboxProperties(onion, authToken, serverSupports,
inboxId, outboxId); inboxId, outboxId);
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.account; package org.briarproject.bramble.account;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.account.AccountManager; import org.briarproject.bramble.api.account.AccountManager;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.DecryptionException; import org.briarproject.bramble.api.crypto.DecryptionException;
@@ -209,7 +210,13 @@ class AccountManagerImpl implements AccountManager {
LOG.warning("Failed to load encrypted database key"); LOG.warning("Failed to load encrypted database key");
throw new DecryptionException(INVALID_CIPHERTEXT); throw new DecryptionException(INVALID_CIPHERTEXT);
} }
byte[] ciphertext = fromHexString(hex); byte[] ciphertext;
try {
ciphertext = fromHexString(hex);
} catch (FormatException e) {
LOG.warning("Encrypted database key has invalid format");
throw new DecryptionException(INVALID_CIPHERTEXT);
}
KeyStrengthener keyStrengthener = databaseConfig.getKeyStrengthener(); KeyStrengthener keyStrengthener = databaseConfig.getKeyStrengthener();
byte[] plaintext = crypto.decryptWithPassword(ciphertext, password, byte[] plaintext = crypto.decryptWithPassword(ciphertext, password,
keyStrengthener); keyStrengthener);

View File

@@ -456,8 +456,7 @@ class ClientHelperImpl implements ClientHelper {
checkLength(inboxId, UniqueId.LENGTH); checkLength(inboxId, UniqueId.LENGTH);
byte[] outboxId = properties.getRaw(PROP_KEY_OUTBOXID); byte[] outboxId = properties.getRaw(PROP_KEY_OUTBOXID);
checkLength(outboxId, UniqueId.LENGTH); checkLength(outboxId, UniqueId.LENGTH);
String baseUrl = "http://" + onion + ".onion"; // TODO MailboxProperties props = new MailboxProperties(onion,
MailboxProperties props = new MailboxProperties(baseUrl,
new MailboxAuthToken(authToken), serverSupportsList, new MailboxAuthToken(authToken), serverSupportsList,
new MailboxFolderId(inboxId), new MailboxFolderId(outboxId)); new MailboxFolderId(inboxId), new MailboxFolderId(outboxId));
return new MailboxUpdateWithMailbox(clientSupportsList, props); return new MailboxUpdateWithMailbox(clientSupportsList, props);

View File

@@ -42,18 +42,22 @@ import static org.briarproject.bramble.util.IoUtils.copyAndClose;
@NotNullByDefault @NotNullByDefault
class MailboxApiImpl implements MailboxApi { class MailboxApiImpl implements MailboxApi {
private final WeakSingletonProvider<OkHttpClient> httpClientProvider;
private final JsonMapper mapper = JsonMapper.builder()
.enable(BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES)
.build();
private static final MediaType JSON = private static final MediaType JSON =
requireNonNull(MediaType.parse("application/json; charset=utf-8")); requireNonNull(MediaType.parse("application/json; charset=utf-8"));
private static final MediaType FILE = private static final MediaType FILE =
requireNonNull(MediaType.parse("application/octet-stream")); requireNonNull(MediaType.parse("application/octet-stream"));
private final WeakSingletonProvider<OkHttpClient> httpClientProvider;
private final JsonMapper mapper = JsonMapper.builder()
.enable(BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES)
.build();
private final UrlConverter urlConverter;
@Inject @Inject
MailboxApiImpl(WeakSingletonProvider<OkHttpClient> httpClientProvider) { MailboxApiImpl(WeakSingletonProvider<OkHttpClient> httpClientProvider,
UrlConverter urlConverter) {
this.httpClientProvider = httpClientProvider; this.httpClientProvider = httpClientProvider;
this.urlConverter = urlConverter;
} }
@Override @Override
@@ -78,7 +82,7 @@ class MailboxApiImpl implements MailboxApi {
throws IOException, ApiException { throws IOException, ApiException {
if (!properties.isOwner()) throw new IllegalArgumentException(); if (!properties.isOwner()) throw new IllegalArgumentException();
Request request = getRequestBuilder(properties.getAuthToken()) Request request = getRequestBuilder(properties.getAuthToken())
.url(properties.getBaseUrl() + "/setup") .url(getBaseUrl(properties) + "/setup")
.put(EMPTY_REQUEST) .put(EMPTY_REQUEST)
.build(); .build();
OkHttpClient client = httpClientProvider.get(); OkHttpClient client = httpClientProvider.get();
@@ -93,7 +97,7 @@ class MailboxApiImpl implements MailboxApi {
if (tokenNode == null) { if (tokenNode == null) {
throw new ApiException(); throw new ApiException();
} }
return new MailboxProperties(properties.getBaseUrl(), return new MailboxProperties(properties.getOnion(),
MailboxAuthToken.fromString(tokenNode.textValue()), MailboxAuthToken.fromString(tokenNode.textValue()),
parseServerSupports(node)); parseServerSupports(node));
} catch (JacksonException | InvalidMailboxIdException e) { } catch (JacksonException | InvalidMailboxIdException e) {
@@ -137,7 +141,7 @@ class MailboxApiImpl implements MailboxApi {
throws IOException, ApiException { throws IOException, ApiException {
if (!properties.isOwner()) throw new IllegalArgumentException(); if (!properties.isOwner()) throw new IllegalArgumentException();
Request request = getRequestBuilder(properties.getAuthToken()) Request request = getRequestBuilder(properties.getAuthToken())
.url(properties.getBaseUrl() + "/") .url(getBaseUrl(properties) + "/")
.delete() .delete()
.build(); .build();
OkHttpClient client = httpClientProvider.get(); OkHttpClient client = httpClientProvider.get();
@@ -162,7 +166,7 @@ class MailboxApiImpl implements MailboxApi {
public void deleteContact(MailboxProperties properties, ContactId contactId) public void deleteContact(MailboxProperties properties, ContactId contactId)
throws IOException, ApiException, TolerableFailureException { throws IOException, ApiException, TolerableFailureException {
if (!properties.isOwner()) throw new IllegalArgumentException(); if (!properties.isOwner()) throw new IllegalArgumentException();
String url = properties.getBaseUrl() + "/contacts/" + String url = getBaseUrl(properties) + "/contacts/" +
contactId.getInt(); contactId.getInt();
Request request = getRequestBuilder(properties.getAuthToken()) Request request = getRequestBuilder(properties.getAuthToken())
.delete() .delete()
@@ -266,7 +270,7 @@ class MailboxApiImpl implements MailboxApi {
String path = "/files/" + folderId + "/" + fileId; String path = "/files/" + folderId + "/" + fileId;
Request request = getRequestBuilder(properties.getAuthToken()) Request request = getRequestBuilder(properties.getAuthToken())
.delete() .delete()
.url(properties.getBaseUrl() + path) .url(getBaseUrl(properties) + path)
.build(); .build();
OkHttpClient client = httpClientProvider.get(); OkHttpClient client = httpClientProvider.get();
Response response = client.newCall(request).execute(); Response response = client.newCall(request).execute();
@@ -308,7 +312,7 @@ class MailboxApiImpl implements MailboxApi {
private Response sendGetRequest(MailboxProperties properties, String path) private Response sendGetRequest(MailboxProperties properties, String path)
throws IOException { throws IOException {
Request request = getRequestBuilder(properties.getAuthToken()) Request request = getRequestBuilder(properties.getAuthToken())
.url(properties.getBaseUrl() + path) .url(getBaseUrl(properties) + path)
.build(); .build();
OkHttpClient client = httpClientProvider.get(); OkHttpClient client = httpClientProvider.get();
return client.newCall(request).execute(); return client.newCall(request).execute();
@@ -317,7 +321,7 @@ class MailboxApiImpl implements MailboxApi {
private Response sendPostRequest(MailboxProperties properties, String path, private Response sendPostRequest(MailboxProperties properties, String path,
RequestBody body) throws IOException { RequestBody body) throws IOException {
Request request = getRequestBuilder(properties.getAuthToken()) Request request = getRequestBuilder(properties.getAuthToken())
.url(properties.getBaseUrl() + path) .url(getBaseUrl(properties) + path)
.post(body) .post(body)
.build(); .build();
OkHttpClient client = httpClientProvider.get(); OkHttpClient client = httpClientProvider.get();
@@ -339,4 +343,7 @@ class MailboxApiImpl implements MailboxApi {
return (ArrayNode) arrayNode; return (ArrayNode) arrayNode;
} }
private String getBaseUrl(MailboxProperties properties) {
return urlConverter.convertOnionToBaseUrl(properties.getOnion());
}
} }

View File

@@ -59,7 +59,12 @@ public class MailboxModule {
} }
@Provides @Provides
MailboxApi providesMailboxApi(MailboxApiImpl mailboxApi) { UrlConverter provideUrlConverter(UrlConverterImpl urlConverter) {
return urlConverter;
}
@Provides
MailboxApi provideMailboxApi(MailboxApiImpl mailboxApi) {
return mailboxApi; return mailboxApi;
} }

View File

@@ -177,10 +177,9 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
LOG.info("QR code is valid"); LOG.info("QR code is valid");
byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33); byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33);
String onion = crypto.encodeOnion(onionPubKey); String onion = crypto.encodeOnion(onionPubKey);
String baseUrl = "http://" + onion + ".onion"; // TODO
byte[] tokenBytes = Arrays.copyOfRange(bytes, 33, 65); byte[] tokenBytes = Arrays.copyOfRange(bytes, 33, 65);
MailboxAuthToken setupToken = new MailboxAuthToken(tokenBytes); MailboxAuthToken setupToken = new MailboxAuthToken(tokenBytes);
return new MailboxProperties(baseUrl, setupToken, new ArrayList<>()); return new MailboxProperties(onion, setupToken, new ArrayList<>());
} }
} }

View File

@@ -74,7 +74,7 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager {
public void setOwnMailboxProperties(Transaction txn, MailboxProperties p) public void setOwnMailboxProperties(Transaction txn, MailboxProperties p)
throws DbException { throws DbException {
Settings s = new Settings(); Settings s = new Settings();
s.put(SETTINGS_KEY_ONION, p.getBaseUrl()); s.put(SETTINGS_KEY_ONION, p.getOnion());
s.put(SETTINGS_KEY_TOKEN, p.getAuthToken().toString()); s.put(SETTINGS_KEY_TOKEN, p.getAuthToken().toString());
List<MailboxVersion> serverSupports = p.getServerSupports(); List<MailboxVersion> serverSupports = p.getServerSupports();
encodeServerSupports(serverSupports, s); encodeServerSupports(serverSupports, s);

View File

@@ -242,8 +242,7 @@ class MailboxUpdateManagerImpl implements MailboxUpdateManager,
private void createAndSendUpdateWithMailbox(Transaction txn, Contact c, private void createAndSendUpdateWithMailbox(Transaction txn, Contact c,
List<MailboxVersion> serverSupports, String ownOnion) List<MailboxVersion> serverSupports, String ownOnion)
throws DbException { throws DbException {
String baseUrl = "http://" + ownOnion + ".onion"; // TODO MailboxProperties properties = new MailboxProperties(ownOnion,
MailboxProperties properties = new MailboxProperties(baseUrl,
new MailboxAuthToken(crypto.generateUniqueId().getBytes()), new MailboxAuthToken(crypto.generateUniqueId().getBytes()),
serverSupports, serverSupports,
new MailboxFolderId(crypto.generateUniqueId().getBytes()), new MailboxFolderId(crypto.generateUniqueId().getBytes()),

View File

@@ -0,0 +1,17 @@
package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
/**
* An interface for converting an onion address to an HTTP URL, allowing the
* conversion to be customised for integration tests.
*/
@NotNullByDefault
interface UrlConverter {
/**
* Converts a raw onion address, excluding the .onion suffix, into an
* HTTP URL.
*/
String convertOnionToBaseUrl(String onion);
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.inject.Inject;
@NotNullByDefault
class UrlConverterImpl implements UrlConverter {
@Inject
UrlConverterImpl() {
}
@Override
public String convertOnionToBaseUrl(String onion) {
return "http://" + onion + ".onion";
}
}

View File

@@ -427,7 +427,13 @@ abstract class AbstractBluetoothPlugin<S, SS> implements BluetoothPlugin,
BdfList descriptor = new BdfList(); BdfList descriptor = new BdfList();
descriptor.add(TRANSPORT_ID_BLUETOOTH); descriptor.add(TRANSPORT_ID_BLUETOOTH);
String address = getBluetoothAddress(); String address = getBluetoothAddress();
if (address != null) descriptor.add(macToBytes(address)); if (address != null) {
try {
descriptor.add(macToBytes(address));
} catch (FormatException e) {
throw new RuntimeException();
}
}
return new BluetoothKeyAgreementListener(descriptor, ss); return new BluetoothKeyAgreementListener(descriptor, ss);
} }

View File

@@ -285,7 +285,7 @@ class LanTcpPlugin extends TcpPlugin {
if (ip.length == 16) addrs.add(InetAddress.getByAddress(ip)); if (ip.length == 16) addrs.add(InetAddress.getByAddress(ip));
} }
return addrs; return addrs;
} catch (IllegalArgumentException | UnknownHostException e) { } catch (FormatException | UnknownHostException e) {
return emptyList(); return emptyList();
} }
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.connection; package org.briarproject.bramble.connection;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.connection.ConnectionRegistry;
import org.briarproject.bramble.api.connection.InterruptibleConnection; import org.briarproject.bramble.api.connection.InterruptibleConnection;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
@@ -57,6 +58,10 @@ public class ConnectionRegistryImplTest extends BrambleMockTestCase {
private final Priority high = private final Priority high =
new Priority(fromHexString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); new Priority(fromHexString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
public ConnectionRegistryImplTest() throws FormatException {
// required for throws declaration
}
@Test @Test
public void testRegisterMultipleConnections() { public void testRegisterMultipleConnections() {
context.checking(new Expectations() {{ context.checking(new Expectations() {{

View File

@@ -1,6 +1,7 @@
package org.briarproject.bramble.crypto; package org.briarproject.bramble.crypto;
import org.bouncycastle.crypto.digests.Blake2bDigest; import org.bouncycastle.crypto.digests.Blake2bDigest;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import org.junit.Test; import org.junit.Test;
@@ -47,7 +48,7 @@ public class Blake2bDigestTest extends BrambleTestCase {
}; };
@Test @Test
public void testDigestWithKeyedTestVectors() { public void testDigestWithKeyedTestVectors() throws FormatException {
for (String[] keyedTestVector : KEYED_TEST_VECTORS) { for (String[] keyedTestVector : KEYED_TEST_VECTORS) {
byte[] input = StringUtils.fromHexString(keyedTestVector[0]); byte[] input = StringUtils.fromHexString(keyedTestVector[0]);
byte[] key = StringUtils.fromHexString(keyedTestVector[1]); byte[] key = StringUtils.fromHexString(keyedTestVector[1]);
@@ -63,7 +64,8 @@ public class Blake2bDigestTest extends BrambleTestCase {
} }
@Test @Test
public void testDigestWithKeyedTestVectorsAndRandomUpdate() { public void testDigestWithKeyedTestVectorsAndRandomUpdate()
throws FormatException {
Random random = new Random(); Random random = new Random();
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
for (String[] keyedTestVector : KEYED_TEST_VECTORS) { for (String[] keyedTestVector : KEYED_TEST_VECTORS) {
@@ -138,7 +140,7 @@ public class Blake2bDigestTest extends BrambleTestCase {
} }
@Test @Test
public void runSelfTest() { public void runSelfTest() throws FormatException {
Blake2bDigest testDigest = new Blake2bDigest(256); Blake2bDigest testDigest = new Blake2bDigest(256);
byte[] md = new byte[64]; byte[] md = new byte[64];

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.crypto; package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.crypto.AgreementPublicKey; import org.briarproject.bramble.api.crypto.AgreementPublicKey;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
@@ -83,7 +84,7 @@ public class KeyAgreementTest extends BrambleTestCase {
} }
@Test @Test
public void testRfc7748TestVector() { public void testRfc7748TestVector() throws FormatException {
byte[] aPriv = parsePrivateKey(ALICE_PRIVATE); byte[] aPriv = parsePrivateKey(ALICE_PRIVATE);
byte[] aPub = fromHexString(ALICE_PUBLIC); byte[] aPub = fromHexString(ALICE_PUBLIC);
byte[] bPriv = parsePrivateKey(BOB_PRIVATE); byte[] bPriv = parsePrivateKey(BOB_PRIVATE);
@@ -97,7 +98,8 @@ public class KeyAgreementTest extends BrambleTestCase {
} }
@Test @Test
public void testDerivesSameSharedSecretFromEquivalentPublicKey() { public void testDerivesSameSharedSecretFromEquivalentPublicKey()
throws FormatException {
byte[] aPub = fromHexString(ALICE_PUBLIC); byte[] aPub = fromHexString(ALICE_PUBLIC);
byte[] bPriv = parsePrivateKey(BOB_PRIVATE); byte[] bPriv = parsePrivateKey(BOB_PRIVATE);
byte[] sharedSecret = fromHexString(SHARED_SECRET); byte[] sharedSecret = fromHexString(SHARED_SECRET);
@@ -168,7 +170,7 @@ public class KeyAgreementTest extends BrambleTestCase {
return crypto.deriveSharedSecret(label, publicKey, keyPair, inputs); return crypto.deriveSharedSecret(label, publicKey, keyPair, inputs);
} }
private byte[] parsePrivateKey(String hex) { private byte[] parsePrivateKey(String hex) throws FormatException {
// Private keys need to be clamped because curve25519-java does the // Private keys need to be clamped because curve25519-java does the
// clamping at key generation time, not multiplication time // clamping at key generation time, not multiplication time
return AgreementKeyParser.clamp(fromHexString(hex)); return AgreementKeyParser.clamp(fromHexString(hex));

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.crypto; package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
@@ -15,11 +16,11 @@ public class XSalsa20Poly1305AuthenticatedCipherTest extends BrambleTestCase {
// Test vectors from the NaCl paper // Test vectors from the NaCl paper
// http://cr.yp.to/highspeed/naclcrypto-20090310.pdf // http://cr.yp.to/highspeed/naclcrypto-20090310.pdf
private static final byte[] TEST_KEY = StringUtils.fromHexString( private final byte[] TEST_KEY = StringUtils.fromHexString(
"1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389"); "1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389");
private static final byte[] TEST_IV = StringUtils.fromHexString( private final byte[] TEST_IV = StringUtils.fromHexString(
"69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37"); "69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37");
private static final byte[] TEST_PLAINTEXT = StringUtils.fromHexString( private final byte[] TEST_PLAINTEXT = StringUtils.fromHexString(
"be075fc53c81f2d5cf141316" + "be075fc53c81f2d5cf141316" +
"ebeb0c7b5228c52a4c62cbd4" + "ebeb0c7b5228c52a4c62cbd4" +
"4b66849b64244ffce5ecbaaf" + "4b66849b64244ffce5ecbaaf" +
@@ -31,7 +32,7 @@ public class XSalsa20Poly1305AuthenticatedCipherTest extends BrambleTestCase {
"048977eb48f59ffd4924ca1c" + "048977eb48f59ffd4924ca1c" +
"60902e52f0a089bc76897040" + "60902e52f0a089bc76897040" +
"e082f937763848645e0705"); "e082f937763848645e0705");
private static final byte[] TEST_CIPHERTEXT = StringUtils.fromHexString( private final byte[] TEST_CIPHERTEXT = StringUtils.fromHexString(
"f3ffc7703f9400e52a7dfb4b" + "f3ffc7703f9400e52a7dfb4b" +
"3d3305d98e993b9f48681273" + "3d3305d98e993b9f48681273" +
"c29650ba32fc76ce48332ea7" + "c29650ba32fc76ce48332ea7" +
@@ -46,6 +47,10 @@ public class XSalsa20Poly1305AuthenticatedCipherTest extends BrambleTestCase {
"a43d14a6599b1f654cb45a74" + "a43d14a6599b1f654cb45a74" +
"e355a5"); "e355a5");
public XSalsa20Poly1305AuthenticatedCipherTest() throws FormatException {
// required for throws declaration
}
@Test @Test
public void testEncrypt() throws Exception { public void testEncrypt() throws Exception {
SecretKey k = new SecretKey(TEST_KEY); SecretKey k = new SecretKey(TEST_KEY);

View File

@@ -618,11 +618,12 @@ public class BdfReaderImplTest extends BrambleTestCase {
r.readDictionary(); r.readDictionary();
} }
private void setContents(String hex) { private void setContents(String hex) throws FormatException {
setContents(hex, DEFAULT_MAX_BUFFER_SIZE); setContents(hex, DEFAULT_MAX_BUFFER_SIZE);
} }
private void setContents(String hex, int maxBufferSize) { private void setContents(String hex, int maxBufferSize)
throws FormatException {
ByteArrayInputStream in = new ByteArrayInputStream(fromHexString(hex)); ByteArrayInputStream in = new ByteArrayInputStream(fromHexString(hex));
r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize); r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize);
} }

View File

@@ -68,7 +68,10 @@ public class MailboxApiTest extends BrambleTestCase {
return client; return client;
} }
}; };
private final MailboxApiImpl api = new MailboxApiImpl(httpClientProvider); // We aren't using a real onion address, so use the given address verbatim
private final UrlConverter urlConverter = onion -> onion;
private final MailboxApiImpl api = new MailboxApiImpl(httpClientProvider,
urlConverter);
private final MailboxAuthToken token = new MailboxAuthToken(getRandomId()); private final MailboxAuthToken token = new MailboxAuthToken(getRandomId());
private final MailboxAuthToken token2 = new MailboxAuthToken(getRandomId()); private final MailboxAuthToken token2 = new MailboxAuthToken(getRandomId());

View File

@@ -49,8 +49,8 @@ public class MailboxIntegrationTest extends BrambleTestCase {
@Rule @Rule
public TemporaryFolder folder = new TemporaryFolder(); public TemporaryFolder folder = new TemporaryFolder();
private final static String URL_BASE = "http://127.0.0.1:8000"; private static final String URL_BASE = "http://127.0.0.1:8000";
private final static MailboxAuthToken SETUP_TOKEN; private static final MailboxAuthToken SETUP_TOKEN;
static { static {
try { try {
@@ -74,8 +74,10 @@ public class MailboxIntegrationTest extends BrambleTestCase {
return client; return client;
} }
}; };
private final static MailboxApiImpl api = // We aren't using a real onion address, so use the given address verbatim
new MailboxApiImpl(httpClientProvider); private static final UrlConverter urlConverter = onion -> onion;
private static final MailboxApiImpl api =
new MailboxApiImpl(httpClientProvider, urlConverter);
// needs to be static to keep values across different tests // needs to be static to keep values across different tests
private static MailboxProperties ownerProperties; private static MailboxProperties ownerProperties;
@@ -121,7 +123,7 @@ public class MailboxIntegrationTest extends BrambleTestCase {
ContactId contactId = new ContactId(1); ContactId contactId = new ContactId(1);
MailboxContact contact = getMailboxContact(contactId); MailboxContact contact = getMailboxContact(contactId);
MailboxProperties contactProperties = new MailboxProperties( MailboxProperties contactProperties = new MailboxProperties(
ownerProperties.getBaseUrl(), contact.token, ownerProperties.getOnion(), contact.token,
new ArrayList<>(), contact.inboxId, contact.outboxId); new ArrayList<>(), contact.inboxId, contact.outboxId);
api.addContact(ownerProperties, contact); api.addContact(ownerProperties, contact);
@@ -167,7 +169,7 @@ public class MailboxIntegrationTest extends BrambleTestCase {
ContactId contactId = new ContactId(1); ContactId contactId = new ContactId(1);
MailboxContact contact = getMailboxContact(contactId); MailboxContact contact = getMailboxContact(contactId);
MailboxProperties contactProperties = new MailboxProperties( MailboxProperties contactProperties = new MailboxProperties(
ownerProperties.getBaseUrl(), contact.token, ownerProperties.getOnion(), contact.token,
new ArrayList<>(), contact.inboxId, contact.outboxId); new ArrayList<>(), contact.inboxId, contact.outboxId);
api.addContact(ownerProperties, contact); api.addContact(ownerProperties, contact);

View File

@@ -55,7 +55,6 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
private final String onion = getRandomString(56); private final String onion = getRandomString(56);
private final byte[] onionBytes = getRandomBytes(32); private final byte[] onionBytes = getRandomBytes(32);
private final String baseUrl = "http://" + onion + ".onion"; // TODO
private final MailboxAuthToken setupToken = private final MailboxAuthToken setupToken =
new MailboxAuthToken(getRandomId()); new MailboxAuthToken(getRandomId());
private final MailboxAuthToken ownerToken = private final MailboxAuthToken ownerToken =
@@ -63,9 +62,9 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
private final String validPayload = getValidPayload(); private final String validPayload = getValidPayload();
private final long time = System.currentTimeMillis(); private final long time = System.currentTimeMillis();
private final MailboxProperties setupProperties = new MailboxProperties( private final MailboxProperties setupProperties = new MailboxProperties(
baseUrl, setupToken, new ArrayList<>()); onion, setupToken, new ArrayList<>());
private final MailboxProperties ownerProperties = new MailboxProperties( private final MailboxProperties ownerProperties = new MailboxProperties(
baseUrl, ownerToken, new ArrayList<>()); onion, ownerToken, new ArrayList<>());
@Test @Test
public void testInitialQrCodeReceivedState() { public void testInitialQrCodeReceivedState() {
@@ -207,7 +206,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
private PredicateMatcher<MailboxProperties> matches(MailboxProperties p2) { private PredicateMatcher<MailboxProperties> matches(MailboxProperties p2) {
return new PredicateMatcher<>(MailboxProperties.class, p1 -> return new PredicateMatcher<>(MailboxProperties.class, p1 ->
p1.getAuthToken().equals(p2.getAuthToken()) && p1.getAuthToken().equals(p2.getAuthToken()) &&
p1.getBaseUrl().equals(p2.getBaseUrl()) && p1.getOnion().equals(p2.getOnion()) &&
p1.isOwner() == p2.isOwner() && p1.isOwner() == p2.isOwner() &&
p1.getServerSupports().equals(p2.getServerSupports())); p1.getServerSupports().equals(p2.getServerSupports()));
} }

View File

@@ -84,7 +84,7 @@ public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
MailboxProperties properties = manager.getOwnMailboxProperties(txn); MailboxProperties properties = manager.getOwnMailboxProperties(txn);
assertNotNull(properties); assertNotNull(properties);
assertEquals(onion, properties.getBaseUrl()); assertEquals(onion, properties.getOnion());
assertEquals(token, properties.getAuthToken()); assertEquals(token, properties.getAuthToken());
assertEquals(serverSupports, properties.getServerSupports()); assertEquals(serverSupports, properties.getServerSupports());
assertTrue(properties.isOwner()); assertTrue(properties.isOwner());

View File

@@ -109,7 +109,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
updateNoMailbox = new MailboxUpdate(someClientSupportsList); updateNoMailbox = new MailboxUpdate(someClientSupportsList);
updateProps = getMailboxProperties(false, someServerSupportsList); updateProps = getMailboxProperties(false, someServerSupportsList);
ownProps = new MailboxProperties(updateProps.getBaseUrl(), ownProps = new MailboxProperties(updateProps.getOnion(),
updateProps.getAuthToken(), someServerSupportsList); updateProps.getAuthToken(), someServerSupportsList);
updateWithMailbox = new MailboxUpdateWithMailbox(someClientSupportsList, updateWithMailbox = new MailboxUpdateWithMailbox(someClientSupportsList,
updateProps); updateProps);
@@ -170,7 +170,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports,
emptyServerSupports, emptyPropsDict, true); emptyServerSupports, emptyPropsDict);
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(), oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
sentDict); sentDict);
@@ -225,7 +225,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports,
someServerSupports, propsDict, true); someServerSupports, propsDict);
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(), oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
sentDict); sentDict);
@@ -276,7 +276,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(emptyMessageMetadata)); will(returnValue(emptyMessageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports,
emptyServerSupports, emptyPropsDict, true); emptyServerSupports, emptyPropsDict);
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(), oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
sentDict); sentDict);
@@ -341,7 +341,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(emptyMessageMetadata)); will(returnValue(emptyMessageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports,
emptyServerSupports, emptyPropsDict, true); emptyServerSupports, emptyPropsDict);
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(), oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
sentDict); sentDict);
@@ -400,7 +400,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 2, expectStoreMessage(txn, contactGroup.getId(), 2,
newerClientSupports, someServerSupports, propsDict, true); newerClientSupports, someServerSupports, propsDict);
oneOf(db).removeMessage(txn, messageId); oneOf(db).removeMessage(txn, messageId);
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(), oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
@@ -441,7 +441,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports,
emptyServerSupports, emptyPropsDict, true); emptyServerSupports, emptyPropsDict);
}}); }});
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList); MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
@@ -484,7 +484,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports,
someServerSupports, propsDict, true); someServerSupports, propsDict);
}}); }});
MailboxUpdateManagerImpl t = createInstance(someClientSupportsList); MailboxUpdateManagerImpl t = createInstance(someClientSupportsList);
@@ -674,7 +674,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 2, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 2, someClientSupports,
someServerSupports, propsDict, true); someServerSupports, propsDict);
oneOf(db).removeMessage(txn, latestId); oneOf(db).removeMessage(txn, latestId);
}}); }});
@@ -712,7 +712,7 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
contactGroup.getId()); contactGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
expectStoreMessage(txn, contactGroup.getId(), 2, someClientSupports, expectStoreMessage(txn, contactGroup.getId(), 2, someClientSupports,
emptyServerSupports, emptyPropsDict, true); emptyServerSupports, emptyPropsDict);
oneOf(db).removeMessage(txn, latestId); oneOf(db).removeMessage(txn, latestId);
}}); }});
@@ -890,15 +890,14 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
private void expectStoreMessage(Transaction txn, GroupId g, private void expectStoreMessage(Transaction txn, GroupId g,
long version, BdfList clientSupports, BdfList serverSupports, long version, BdfList clientSupports, BdfList serverSupports,
BdfDictionary properties, boolean local) BdfDictionary properties) throws Exception {
throws Exception {
BdfList body = BdfList.of(version, clientSupports, serverSupports, BdfList body = BdfList.of(version, clientSupports, serverSupports,
properties); properties);
Message message = getMessage(g); Message message = getMessage(g);
long timestamp = message.getTimestamp(); long timestamp = message.getTimestamp();
BdfDictionary meta = BdfDictionary.of( BdfDictionary meta = BdfDictionary.of(
new BdfEntry(MSG_KEY_VERSION, version), new BdfEntry(MSG_KEY_VERSION, version),
new BdfEntry(MSG_KEY_LOCAL, local) new BdfEntry(MSG_KEY_LOCAL, true)
); );
context.checking(new Expectations() {{ context.checking(new Expectations() {{

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.util; package org.briarproject.bramble.util;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test; import org.junit.Test;
@@ -11,7 +12,7 @@ import static org.junit.Assert.fail;
public class ByteUtilsTest extends BrambleTestCase { public class ByteUtilsTest extends BrambleTestCase {
@Test @Test
public void testReadUint16() { public void testReadUint16() throws FormatException {
byte[] b = StringUtils.fromHexString("00000000"); byte[] b = StringUtils.fromHexString("00000000");
assertEquals(0, ByteUtils.readUint16(b, 1)); assertEquals(0, ByteUtils.readUint16(b, 1));
b = StringUtils.fromHexString("00000100"); b = StringUtils.fromHexString("00000100");
@@ -33,7 +34,7 @@ public class ByteUtilsTest extends BrambleTestCase {
} }
@Test @Test
public void testReadUint32() { public void testReadUint32() throws FormatException {
byte[] b = StringUtils.fromHexString("000000000000"); byte[] b = StringUtils.fromHexString("000000000000");
assertEquals(0, ByteUtils.readUint32(b, 1)); assertEquals(0, ByteUtils.readUint32(b, 1));
b = StringUtils.fromHexString("000000000100"); b = StringUtils.fromHexString("000000000100");
@@ -55,7 +56,7 @@ public class ByteUtilsTest extends BrambleTestCase {
} }
@Test @Test
public void testReadUint64() { public void testReadUint64() throws FormatException {
byte[] b = StringUtils.fromHexString("00000000000000000000"); byte[] b = StringUtils.fromHexString("00000000000000000000");
assertEquals(0L, ByteUtils.readUint64(b, 1)); assertEquals(0L, ByteUtils.readUint64(b, 1));
b = StringUtils.fromHexString("00000000000000000100"); b = StringUtils.fromHexString("00000000000000000100");

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.util; package org.briarproject.bramble.util;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test; import org.junit.Test;
@@ -24,18 +25,19 @@ public class StringUtilsTest extends BrambleTestCase {
assertEquals("", StringUtils.toHexString(new byte[0])); assertEquals("", StringUtils.toHexString(new byte[0]));
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testFromHexStringRejectsInvalidLength() { public void testFromHexStringRejectsInvalidLength() throws FormatException {
StringUtils.fromHexString("12345"); StringUtils.fromHexString("12345");
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testFromHexStringRejectsInvalidCharacter() { public void testFromHexStringRejectsInvalidCharacter()
throws FormatException {
StringUtils.fromHexString("ABCDEFGH"); StringUtils.fromHexString("ABCDEFGH");
} }
@Test @Test
public void testFromHexStringUppercase() { public void testFromHexStringUppercase() throws FormatException {
String s = "000102037F800A0B0C0D0EFF"; String s = "000102037F800A0B0C0D0EFF";
byte[] expected = new byte[] { byte[] expected = new byte[] {
0x00, 0x01, 0x02, 0x03, 0x7F, (byte) 0x80, 0x00, 0x01, 0x02, 0x03, 0x7F, (byte) 0x80,
@@ -45,7 +47,7 @@ public class StringUtilsTest extends BrambleTestCase {
} }
@Test @Test
public void testFromHexStringLowercase() { public void testFromHexStringLowercase() throws FormatException {
String s = "000102037f800a0b0c0d0eff"; String s = "000102037f800a0b0c0d0eff";
byte[] expected = new byte[] { byte[] expected = new byte[] {
0x00, 0x01, 0x02, 0x03, 0x7F, (byte) 0x80, 0x00, 0x01, 0x02, 0x03, 0x7F, (byte) 0x80,
@@ -55,7 +57,7 @@ public class StringUtilsTest extends BrambleTestCase {
} }
@Test @Test
public void testFromHexStringEmptyInput() { public void testFromHexStringEmptyInput() throws FormatException {
assertArrayEquals(new byte[0], StringUtils.fromHexString("")); assertArrayEquals(new byte[0], StringUtils.fromHexString(""));
} }
@@ -174,52 +176,52 @@ public class StringUtilsTest extends BrambleTestCase {
assertEquals("", StringUtils.truncateUtf8("", 123)); assertEquals("", StringUtils.truncateUtf8("", 123));
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testMacToBytesRejectsShortMac() { public void testMacToBytesRejectsShortMac() throws FormatException {
StringUtils.macToBytes("00:00:00:00:00"); StringUtils.macToBytes("00:00:00:00:00");
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testMacToBytesRejectsLongMac() { public void testMacToBytesRejectsLongMac() throws FormatException {
StringUtils.macToBytes("00:00:00:00:00:00:00"); StringUtils.macToBytes("00:00:00:00:00:00:00");
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testMacToBytesRejectsInvalidCharacter() { public void testMacToBytesRejectsInvalidCharacter() throws FormatException {
StringUtils.macToBytes("00:00:00:00:00:0g"); StringUtils.macToBytes("00:00:00:00:00:0g");
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testMacToBytesRejectsInvalidFormat() { public void testMacToBytesRejectsInvalidFormat() throws FormatException {
StringUtils.macToBytes("0:000:00:00:00:00"); StringUtils.macToBytes("0:000:00:00:00:00");
} }
@Test @Test
public void testMacToBytesUpperCase() { public void testMacToBytesUpperCase() throws FormatException {
byte[] expected = new byte[] {0x0A, 0x1B, 0x2C, 0x3D, 0x4E, 0x5F}; byte[] expected = new byte[] {0x0A, 0x1B, 0x2C, 0x3D, 0x4E, 0x5F};
String mac = "0A:1B:2C:3D:4E:5F"; String mac = "0A:1B:2C:3D:4E:5F";
assertArrayEquals(expected, StringUtils.macToBytes(mac)); assertArrayEquals(expected, StringUtils.macToBytes(mac));
} }
@Test @Test
public void testMacToBytesLowerCase() { public void testMacToBytesLowerCase() throws FormatException {
byte[] expected = new byte[] {0x0A, 0x1B, 0x2C, 0x3D, 0x4E, 0x5F}; byte[] expected = new byte[] {0x0A, 0x1B, 0x2C, 0x3D, 0x4E, 0x5F};
String mac = "0a:1b:2c:3d:4e:5f"; String mac = "0a:1b:2c:3d:4e:5f";
assertArrayEquals(expected, StringUtils.macToBytes(mac)); assertArrayEquals(expected, StringUtils.macToBytes(mac));
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testMacToStringRejectsShortMac() { public void testMacToStringRejectsShortMac() throws FormatException {
StringUtils.macToString(new byte[5]); StringUtils.macToString(new byte[5]);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = FormatException.class)
public void testMacToStringRejectsLongMac() { public void testMacToStringRejectsLongMac() throws FormatException {
StringUtils.macToString(new byte[7]); StringUtils.macToString(new byte[7]);
} }
@Test @Test
public void testMacToString() { public void testMacToString() throws FormatException {
byte[] mac = new byte[] {0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f}; byte[] mac = new byte[] {0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f};
String expected = "0A:1B:2C:3D:4E:5F"; String expected = "0A:1B:2C:3D:4E:5F";
assertEquals(expected, StringUtils.macToString(mac)); assertEquals(expected, StringUtils.macToString(mac));

View File

@@ -8,6 +8,7 @@ import android.os.StrictMode;
import com.vanniktech.emoji.RecentEmoji; import com.vanniktech.emoji.RecentEmoji;
import org.briarproject.bramble.api.FeatureFlags; import org.briarproject.bramble.api.FeatureFlags;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyStrengthener; import org.briarproject.bramble.api.crypto.KeyStrengthener;
import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.crypto.PublicKey;
@@ -242,7 +243,7 @@ public class AppModule {
try { try {
return crypto.getMessageKeyParser().parsePublicKey( return crypto.getMessageKeyParser().parsePublicKey(
StringUtils.fromHexString(DEV_PUBLIC_KEY_HEX)); StringUtils.fromHexString(DEV_PUBLIC_KEY_HEX));
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException | FormatException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@@ -6,6 +6,8 @@ import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.StrictMode; import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy; import android.os.StrictMode.ThreadPolicy;
import android.os.StrictMode.VmPolicy; import android.os.StrictMode.VmPolicy;
@@ -120,12 +122,62 @@ public class BriarApplicationImpl extends Application
} }
private void enableStrictMode() { private void enableStrictMode() {
int targetSdk = Build.VERSION.SDK_INT;
ThreadPolicy.Builder threadPolicy = new ThreadPolicy.Builder(); ThreadPolicy.Builder threadPolicy = new ThreadPolicy.Builder();
threadPolicy.detectAll();
// pulled in from threadPolicy.detectAll();
threadPolicy.detectDiskReads();
threadPolicy.detectDiskWrites();
threadPolicy.detectNetwork();
if (targetSdk >= VERSION_CODES.HONEYCOMB) {
threadPolicy.detectCustomSlowCalls();
}
if (targetSdk >= VERSION_CODES.M) {
threadPolicy.detectResourceMismatches();
}
if (targetSdk >= VERSION_CODES.O) {
threadPolicy.detectUnbufferedIo();
}
// -- end detectAll()
threadPolicy.penaltyLog(); threadPolicy.penaltyLog();
StrictMode.setThreadPolicy(threadPolicy.build()); StrictMode.setThreadPolicy(threadPolicy.build());
VmPolicy.Builder vmPolicy = new VmPolicy.Builder(); VmPolicy.Builder vmPolicy = new VmPolicy.Builder();
vmPolicy.detectAll();
// pulled in from vmPolicy.detectAll();
vmPolicy.detectLeakedSqlLiteObjects();
if (targetSdk >= VERSION_CODES.HONEYCOMB) {
vmPolicy.detectActivityLeaks();
vmPolicy.detectLeakedClosableObjects();
}
if (targetSdk >= VERSION_CODES.JELLY_BEAN) {
vmPolicy.detectLeakedRegistrationObjects();
}
if (targetSdk >= VERSION_CODES.JELLY_BEAN_MR2) {
vmPolicy.detectFileUriExposure();
}
if (targetSdk >= VERSION_CODES.M) {
vmPolicy.detectCleartextNetwork();
}
if (targetSdk >= VERSION_CODES.O) {
vmPolicy.detectContentUriWithoutPermission();
// do not detect untagged sockets
// vmPolicy.detectUntaggedSockets();
}
if (targetSdk >= VERSION_CODES.Q) {
vmPolicy.detectCredentialProtectedWhileLocked();
}
if (targetSdk >= VERSION_CODES.R) {
// for some reason this won't compile
// vmPolicy.detectIncorrectContextUse();
}
// -- end detectAll()
// TODO: add detectUnsafeIntentLaunch() after upgrading to API level 31
vmPolicy.penaltyLog(); vmPolicy.penaltyLog();
StrictMode.setVmPolicy(vmPolicy.build()); StrictMode.setVmPolicy(vmPolicy.build());
} }

View File

@@ -22,6 +22,7 @@ import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import org.briarproject.bramble.api.FeatureFlags; import org.briarproject.bramble.api.FeatureFlags;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.connection.ConnectionRegistry;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
@@ -519,8 +520,12 @@ public class ConversationActivity extends BriarActivity
Selection<String> selection = tracker.getSelection(); Selection<String> selection = tracker.getSelection();
List<MessageId> messages = new ArrayList<>(selection.size()); List<MessageId> messages = new ArrayList<>(selection.size());
for (String str : selection) { for (String str : selection) {
MessageId id = new MessageId(fromHexString(str)); try {
messages.add(id); MessageId id = new MessageId(fromHexString(str));
messages.add(id);
} catch (FormatException e) {
LOG.warning("Invalid message id");
}
} }
return messages; return messages;
} }

View File

@@ -109,12 +109,18 @@ public class MailboxActivity extends BriarActivity {
} }
private void onShowDownload() { private void onShowDownload() {
boolean needToShow = true;
FragmentManager fm = getSupportFragmentManager(); FragmentManager fm = getSupportFragmentManager();
// if the fragment is already on the back stack, pop back to it
// instead of adding it to the stack again
if (fm.findFragmentByTag(SetupDownloadFragment.TAG) != null) { if (fm.findFragmentByTag(SetupDownloadFragment.TAG) != null) {
// if the fragment is already on the back stack, pop back to it // if the activity was previously destroyed, the fragment is still
// instead of adding it to the stack again // found, but popping back to it won't work, so we need to handle
fm.popBackStackImmediate(SetupDownloadFragment.TAG, 0); // this case and show the fragment again anyway.
} else { needToShow =
!fm.popBackStackImmediate(SetupDownloadFragment.TAG, 0);
}
if (needToShow) {
showFragment(fm, new SetupDownloadFragment(), showFragment(fm, new SetupDownloadFragment(),
SetupDownloadFragment.TAG); SetupDownloadFragment.TAG);
} }