Compare commits

..

117 Commits

Author SHA1 Message Date
akwizgran
189ec874cc @GuardedBy annotations. 2019-02-15 10:16:26 +00:00
akwizgran
8c25732d13 Miscellaneous code cleanups. 2019-02-15 10:16:19 +00:00
akwizgran
c59ef29cdb Minor code cleanups. 2019-02-14 17:37:53 +00:00
akwizgran
56ac755e96 Lint cleanups. 2019-02-14 17:37:51 +00:00
akwizgran
98633f5e7c A few more null safety cleanups. 2019-02-14 17:29:55 +00:00
akwizgran
86130e845a Null safety cleanups. 2019-02-14 17:29:55 +00:00
akwizgran
8ecec8bcf5 More static imports. 2019-02-14 17:29:52 +00:00
akwizgran
ad9191b076 Static imports. 2019-02-14 13:56:20 +00:00
Torsten Grote
b342759e06 Merge branch '978-tor-only-on-battery' into 'master'
Add a setting to disable Tor when running on battery

Closes #978

See merge request briar/briar!1032
2019-02-06 14:46:33 +00:00
akwizgran
93d99b0111 Tweak wording of Tor battery setting. 2019-02-06 14:23:15 +00:00
akwizgran
61e8d576d2 Update mobile data log message, simplify logic. 2019-02-06 14:20:04 +00:00
Torsten Grote
75c37a258e Add a setting to disable Tor when running on battery 2019-02-05 13:46:26 -02:00
akwizgran
e964dae64b Merge branch '1468-image-size-tests' into 'master'
Add tests for parsing image sizes

See merge request briar/briar!1026
2019-01-15 17:26:55 +00:00
akwizgran
986d884b40 Refactor ImageManager to ImageHelper. 2019-01-15 17:14:57 +00:00
akwizgran
9557afabc6 Change MIME types to "image/jpeg", unsuppress warning. 2019-01-15 16:49:18 +00:00
Torsten Grote
ebe6b0d4c0 [android] Split up AttachmentController tests into integration and unit 2019-01-15 16:33:03 +00:00
Torsten Grote
6e83fb7aef [android] add tests for getting attachment items from AttachmentController 2019-01-15 16:33:00 +00:00
Torsten Grote
7a5ec2af12 [android] Add test for MarkEnforcingInputStream 2019-01-15 16:32:23 +00:00
akwizgran
ce1fde496c Merge branch '1477-check-attachment-support' into 'master'
Find out if contacts support image attachments and enable them

Closes #1477

See merge request briar/briar!1019
2019-01-15 15:35:48 +00:00
akwizgran
4b62c51fbf Revert to using a fixed delay for the onboarding. 2019-01-15 15:23:30 +00:00
akwizgran
226ed3dd73 Wrap long line, remove redundant variable. 2019-01-14 14:31:31 +00:00
akwizgran
ab07dfb32c Use expression lambda. 2019-01-14 14:26:09 +00:00
akwizgran
20c51c1aa4 Group together fields with the same access restrictions. 2019-01-14 14:25:32 +00:00
Torsten Grote
232c2129a7 [android] use a LiveData in ConversationActivity to get notified when transition ended 2019-01-14 14:22:31 +00:00
Torsten Grote
3620edbfc9 [android] set a transition animation duration for ConversationActivity
so we know better for how long to delay the onboarding dialogs
2019-01-14 14:21:34 +00:00
Torsten Grote
ad71d69149 Create and use method in MessagingManager for checking for image support 2019-01-14 14:21:33 +00:00
Torsten Grote
f73f8ca7e7 [android] do not show two private conversation onboardings at the same time
Checking for introduction onboarding is now done in the ViewModel
together with the image onboarding. The latter has preference. If both
could be shown, the introduction onboarding will be delayed to the next
time the user enters the conversation.
2019-01-14 14:21:33 +00:00
Torsten Grote
16c701a71a [android] only enable image feature if contact supports it
Also show an onboarding the first time, the feature gets activiated
2019-01-14 14:21:19 +00:00
akwizgran
8183b7b26a Merge branch '1469-hide-ui-without-flashing' into 'master'
Hide UI without flashing

Closes #1469

See merge request briar/briar!1030
2019-01-11 17:22:04 +00:00
akwizgran
bd48c97eab Merge branch 'upgrade-jackson-2.9.8' into 'master'
Upgrade Jackson to 2.9.8

See merge request briar/briar!1031
2019-01-11 17:07:07 +00:00
akwizgran
925dc29a1f Merge branch 'hide-ui-api-15' into 'master'
Improve UI hiding behaviour

See merge request briar/briar!1029
2019-01-11 17:03:24 +00:00
akwizgran
91777fd942 Hide UI without flashing. 2019-01-11 16:59:53 +00:00
akwizgran
fbce8f81c7 Merge branch '1475-transition-name' into 'master'
Use a unique transition name for each AttachmentItem

See merge request briar/briar!1028
2019-01-11 16:54:24 +00:00
akwizgran
d7c72c4d68 Use a unique transition name for each AttachmentItem. 2019-01-11 16:45:20 +00:00
akwizgran
4faf535801 Reduce visibility. 2019-01-11 16:45:20 +00:00
akwizgran
526ef7c6d8 Add array entries for new translations. 2019-01-11 15:13:06 +00:00
akwizgran
798dff1a03 Update translations, add Macedonian and Ukrainian. 2019-01-11 12:18:15 +00:00
akwizgran
a4336776c9 Merge branch '1475-image-transitions' into 'master'
Resolve main issues with image transition animation

See merge request briar/briar!1016
2019-01-09 15:01:29 +00:00
akwizgran
418451cbd9 Use consistent conditions to decide whether to scroll. 2019-01-09 14:30:57 +00:00
akwizgran
045fcfc5fa Remove translucent window effect. 2019-01-09 14:30:57 +00:00
Torsten Grote
ef998577db [android] add nullability annotations to ImageActivity 2019-01-09 14:30:57 +00:00
Torsten Grote
a53345a3c9 [android] scroll down when new messages arrive while conversation is visible
Also shows new message notification when ConversationActivity is paused
2019-01-09 14:30:56 +00:00
Torsten Grote
ed8c09282d [android] enable image shared element transition for API 21+22
There's an Android framework bug (#224270) on these APIs that causes a NPE
when the shared element is not visible anymore when returning.
Since we know restore the list position, the shared element should be
visible and thus not produce NPEs anymore.
2019-01-09 14:30:56 +00:00
Torsten Grote
42197b5b5c [android] Fix enter transition to fullscreen ImageActivity 2019-01-09 14:30:56 +00:00
Torsten Grote
374fc7035b [android] Save and restore list position of conversation across restarts 2019-01-09 14:30:55 +00:00
akwizgran
9b796c7cc3 Merge branch '1438-send-image-attachments-multiple' into 'master'
UX for sending multiple image attachments

See merge request briar/briar!1015
2019-01-04 17:04:43 +00:00
akwizgran
532edff642 Minor code cleanups. 2019-01-04 16:55:29 +00:00
akwizgran
6857252471 Merge branch '1480-window-background' into 'master'
[android] Change light theme background color closer to white

See merge request briar/briar!1020
2018-12-21 16:48:18 +00:00
Torsten Grote
c229e19452 [android] remove images from preview that could not be loaded
We will not even attempt to attach them
2018-12-21 11:05:34 -02:00
Torsten Grote
42bca09d16 [android] Add gap between attached image previews 2018-12-21 11:05:34 -02:00
Torsten Grote
9eacbfa659 [android] Remove palette library
we are not extracting photo colors anymore
2018-12-21 11:05:34 -02:00
Torsten Grote
f14e546dc6 [android] allow to attach multiple images 2018-12-21 11:05:34 -02:00
akwizgran
684c64a1d9 Merge branch '1310-disable-enter-transition-for-samsung7' into 'master'
[android] Disable Conversation Enter Transition for Samsung 7 devices

Closes #1310

See merge request briar/briar!1023
2018-12-19 11:32:51 +00:00
akwizgran
6fdab959b1 Merge branch '631-inject-fragments-early' into 'master'
Inject fragments earlier in their lifecycle

Closes #631

See merge request briar/briar!1024
2018-12-19 11:24:31 +00:00
Torsten Grote
c8487483ff [android] Also consider Android 7.1 (API 25) to be Samsung7
which is used for disabling certain features due to crashes there.
2018-12-18 18:17:27 -02:00
Torsten Grote
a159b23dc0 [android] Disable Conversation Enter Transition for Samsung 7 devices 2018-12-18 18:16:32 -02:00
Torsten Grote
5070a27a83 [android] also fix some activity nullability issues 2018-12-18 18:12:05 -02:00
Torsten Grote
9ce73a6840 [android] inject fragments already in onAttach()
This also removes the need to override the inject method even when
there's nothing to inject.

While passing over all fragments, some nullability issues also have been
addressed.
2018-12-18 18:01:04 -02:00
akwizgran
6e9928f20f Merge branch '1484-wait-for-component-to-be-created' into 'master'
[android] AliasFragment: Wait for activity component to be created

Closes #1484

See merge request briar/briar!1022
2018-12-18 17:46:19 +00:00
Torsten Grote
b31d61afc5 [android] AliasFragment: Wait for activity component to be created
before injecting the ViewModel
2018-12-18 15:32:26 -02:00
akwizgran
5a99cb93cc Merge branch '1482-check-earlier-for-sign-in' into 'master'
[android] don't crash when re-opening conversation after briar exited

Closes #1482

See merge request briar/briar!1021
2018-12-18 12:58:39 +00:00
Torsten Grote
d0bbebd25e [android] don't crash when re-opening conversation after briar exited 2018-12-17 18:42:06 -02:00
Torsten Grote
4307d26606 [android] Change light theme background color closer to white 2018-12-17 17:25:12 -02:00
akwizgran
0089c1ac6d Merge branch '1468-restrict-image-size' into 'master'
Fix first issues related to image size

See merge request briar/briar!1018
2018-12-17 12:48:15 +00:00
akwizgran
2a7aac4930 Upgrade Jackson to 2.9.8. 2018-12-17 12:09:36 +00:00
akwizgran
a37b6d81ed Merge branch '1242-save-snackbar-fix' into 'master'
[android] Clarify the meaning of image save state

See merge request briar/briar!1017
2018-12-17 11:17:12 +00:00
Torsten Grote
1d09a6708a [android] don't ever load an entire image into memory
This happens on API 27+28 if loading TIFF or WebP files.
Using an InputStream with a read limit prevents this.
2018-12-14 20:11:43 -02:00
Torsten Grote
d3b6f484c8 [android] allow image transformations in full-screen view
to prevent crashes from huge images
2018-12-14 20:11:43 -02:00
Torsten Grote
039c6edb66 [android] increase scale levels of PhotoView 2018-12-14 20:11:43 -02:00
Torsten Grote
8b9f89eab2 [android] Clarify the meaning of image save state 2018-12-14 12:27:47 -02:00
akwizgran
1e2c17b170 Merge branch '1242-display-image-attachments-multiple' into 'master'
Swipe left/right in image screen for images from same message

See merge request briar/briar!1012
2018-12-13 16:33:24 +00:00
Torsten Grote
a994966095 [android] address review comments for image fullscreen swiping 2018-12-13 12:00:51 -02:00
Torsten Grote
2bea581654 [android] Swipe left/right in image screen to see other images from the same message 2018-12-13 11:59:41 -02:00
Torsten Grote
87377666aa Merge branch '1473-display-multiple-images' into 'master'
UX for displaying multiple image attachments

Closes #1473

See merge request briar/briar!1010
2018-12-13 13:07:24 +00:00
akwizgran
9d07b2e141 Resolve merge conflicts.
# Conflicts:
#   briar-android/src/main/java/org/briarproject/briar/android/conversation/AttachmentController.java
#   briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
2018-12-13 11:41:04 +00:00
akwizgran
5c312b49e2 Merge branch '1438-send-image-attachments' into 'master'
Store attachments and actually attach them to sent messages

Closes #1438

See merge request briar/briar!1006
2018-12-13 10:27:09 +00:00
Torsten Grote
f56efe45cd Merge branch '1477-get-client-minor-version' into 'master'
Add method for querying client minor version supported by contact

See merge request briar/briar!1014
2018-12-12 19:34:55 +00:00
Torsten Grote
2332a58681 [android] address review comments for displaying multiple images 2018-12-12 17:00:44 -02:00
Torsten Grote
8c6dfaa196 [android] Use @UiThread instead of @MainThread 2018-12-12 16:18:43 -02:00
Torsten Grote
3cfb04b60d Establish some rules for handling InputStreams
* Methods shouldn't place any special requirements on the streams
  passed into them
* This implies that if a stream's going to be marked and reset,
  that should all happen within one method
* This also implies that if a method needs to mark and reset a stream,
  it should wrap the stream in a BufferedInputStream before doing so,
  rather than requiring a markable stream to be passed in
2018-12-12 16:17:50 -02:00
Torsten Grote
e85fbfb952 [android] close InputStream with new IoUtils method 2018-12-12 16:17:50 -02:00
Torsten Grote
80ee35d926 [core] Return fake mini PNG as Attachment instead of throwing exception 2018-12-12 16:17:50 -02:00
Torsten Grote
4796902b9c [android] store attachments and actually attach them to sent messages 2018-12-12 16:17:50 -02:00
akwizgran
149e67c0f7 Reduce code duplication in tests. 2018-12-12 11:57:35 +00:00
akwizgran
1d5214117f Add tests for getClientMinorVersion(). 2018-12-11 17:55:39 +00:00
akwizgran
b8f248ca9c Add tests for getClientVisibility(). 2018-12-11 17:51:42 +00:00
Torsten Grote
dfb71a03a5 [android] Only retrieve image sizes for single images in messages
We need to do this to know the height of messages when binding the view.
The size of single images can be different (e.g. due to orientation).
For multiple images, we use a fixed size, so no retrieval is required.
2018-12-11 15:38:05 -02:00
Torsten Grote
961fdc8e72 [android] Show multiple images in message bubble 2018-12-11 15:28:21 -02:00
Torsten Grote
c3d44663cd [android] Use a nested RecyclerView with a single items to show image attachments
This is preparation for showing multiple image attachments in one
message bubble.
2018-12-11 15:28:21 -02:00
akwizgran
0081472489 Add method for querying contact's client minor version. 2018-12-11 17:25:29 +00:00
akwizgran
cdf4f3a24b Merge branch '1232-add-contacts-remotely-api' into 'master'
[api] Add interface for adding contacts remotely

See merge request briar/briar!1007
2018-12-10 10:53:37 +00:00
Torsten Grote
fb1d8e860f [api] Add interface for adding contacts remotely 2018-12-10 08:30:50 -02:00
akwizgran
a3c526ec9a Merge branch '1298-scrub-wifi-address-in-crash-report' into 'master'
Scrub wifi IP address in crash reports.

Closes #1298

See merge request briar/briar!1013
2018-12-10 10:12:42 +00:00
Jordi Salvat
dee488d06d Scrub wifi IP address in crash reports. 2018-12-10 01:07:37 +01:00
Torsten Grote
b29c7d8022 Merge branch '1385-make-link-cover-entire-word' into 'master'
[android] fix start of link in error message for adding contacts

Closes #1385

See merge request briar/briar!1011
2018-12-07 19:13:54 +00:00
akwizgran
0725d207ec Merge branch '1432-headless-integration-tests' into 'master'
[headless] Add first integration test for ContactController

See merge request briar/briar!1008
2018-12-07 17:37:22 +00:00
akwizgran
5a7599a88d Merge branch '1242-display-image-attachments-save' into 'master'
Allow the user to save image attachment outside of Briar

See merge request briar/briar!1005
2018-12-07 17:31:42 +00:00
Torsten Grote
59cd98db81 [android] Get image extension from MimeTypeMap and store it in AttachmentItem 2018-12-07 15:11:09 -02:00
Torsten Grote
768488eb04 [android] Show (tinted) security icon when warning about saving attachments 2018-12-07 14:39:43 -02:00
Torsten Grote
a6b1ad48c3 [android] Add support for saving image attachments on API < 19
This is done by using the WRITE_EXTERNAL_STORAGE permission
to write the file directly without using the system activity.
2018-12-07 13:01:44 -02:00
Torsten Grote
77299a68ed [android] Allow the user to save image attachment outside of Briar 2018-12-07 13:01:42 -02:00
akwizgran
5e5705c73b Merge branch '1438-send-image-attachments-ui' into 'master'
Implement UX for sending image attachments

See merge request briar/briar!1004
2018-12-07 14:58:23 +00:00
Torsten Grote
e6229a3a13 [android] Factor out image preview into its own view class 2018-12-06 17:56:02 -02:00
Torsten Grote
5fbacb4ee4 [android] Split out an EmojiTextInputView from TextInputViews
This also removes the TextInputController whose job is now done by the view.
2018-12-06 17:56:02 -02:00
Torsten Grote
c7f4e976ed [android] Require users of TextInputView to set its controller 2018-12-06 17:56:02 -02:00
Torsten Grote
419f2d966a [android] Show a toast when an image could not be attached 2018-12-06 17:56:02 -02:00
Torsten Grote
d6c18db9e9 [android] set image preview size to 1/4 of screen height 2018-12-06 17:56:02 -02:00
Torsten Grote
8fe49d9961 [android] Re-factor TextInputViews 2018-12-06 17:56:02 -02:00
Torsten Grote
f536cfdab8 [android] first round of review comments for attaching images 2018-12-06 17:56:02 -02:00
Torsten Grote
4d594acad5 [android] Save attached (but not sent) image on screen rotation 2018-12-06 17:56:02 -02:00
Torsten Grote
800dfed5c1 [android] support adding image attachments to private messages 2018-12-06 17:55:59 -02:00
Jordi Salvat
54b823e401 [android] fix start of link in error message for adding contacts 2018-12-06 20:44:36 +01:00
Torsten Grote
52ec56d690 Merge branch 'invalid-slide-direction' into 'master'
Revert change to slide direction

Closes #1478

See merge request briar/briar!1009
2018-12-06 15:32:07 +00:00
akwizgran
7b3afcca99 Revert change to slide direction. 2018-12-06 15:18:16 +00:00
Torsten Grote
a22d03d028 [headless] wait for lifecycle manager to finish starting
before starting web server
2018-12-05 16:08:03 -02:00
Torsten Grote
d857338ad0 [headless] Add first integration test for ContactController 2018-12-05 16:04:14 -02:00
akwizgran
dcd5e34c6b Improve UI hiding behaviour. 2018-11-30 12:40:45 +00:00
480 changed files with 8171 additions and 3856 deletions

View File

@@ -9,19 +9,22 @@ import org.briarproject.bramble.api.account.AccountManager;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.util.IoUtils;
import java.io.File;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.inject.Inject;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
class AndroidAccountManager extends AccountManagerImpl
implements AccountManager {
private static final Logger LOG =
Logger.getLogger(AndroidAccountManager.class.getName());
getLogger(AndroidAccountManager.class.getName());
private static final String PREF_DB_KEY = "key";
@@ -37,7 +40,7 @@ class AndroidAccountManager extends AccountManagerImpl
appContext = app.getApplicationContext();
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
@Override
@Nullable
protected String loadEncryptedDatabaseKey() {
@@ -47,7 +50,7 @@ class AndroidAccountManager extends AccountManagerImpl
return key;
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
@Nullable
private String getDatabaseKeyFromPreferences() {
String key = prefs.getString(PREF_DB_KEY, null);
@@ -56,7 +59,7 @@ class AndroidAccountManager extends AccountManagerImpl
return key;
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
private void migrateDatabaseKeyToFile(String key) {
if (storeEncryptedDatabaseKey(key)) {
if (prefs.edit().remove(PREF_DB_KEY).commit())
@@ -81,7 +84,7 @@ class AndroidAccountManager extends AccountManagerImpl
return PreferenceManager.getDefaultSharedPreferences(appContext);
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
private void deleteAppData(SharedPreferences... clear) {
// Clear and commit shared preferences
for (SharedPreferences prefs : clear) {
@@ -97,7 +100,7 @@ class AndroidAccountManager extends AccountManagerImpl
for (File child : children) {
String name = child.getName();
if (!name.equals("lib") && !name.equals("shared_prefs")) {
IoUtils.deleteFileOrDir(child);
deleteFileOrDir(child);
}
}
}

View File

@@ -19,9 +19,7 @@ import javax.inject.Inject;
import static android.content.Intent.ACTION_BATTERY_CHANGED;
import static android.content.Intent.ACTION_POWER_CONNECTED;
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
import static android.os.BatteryManager.BATTERY_STATUS_CHARGING;
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
import static android.os.BatteryManager.EXTRA_STATUS;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@@ -48,9 +46,8 @@ class AndroidBatteryManager implements BatteryManager, Service {
IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
Intent i = appContext.registerReceiver(null, filter);
if (i == null) return false;
int status = i.getIntExtra(EXTRA_STATUS, -1);
return status == BATTERY_STATUS_CHARGING ||
status == BATTERY_STATUS_FULL;
int status = i.getIntExtra(EXTRA_PLUGGED, 0);
return status != 0;
}
@Override

View File

@@ -13,8 +13,7 @@ import org.briarproject.bramble.api.lifecycle.Service;
import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.network.NetworkStatus;
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.Scheduler;
import java.util.concurrent.Future;
@@ -34,16 +33,17 @@ import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@NotNullByDefault
class AndroidNetworkManager implements NetworkManager, Service {
private static final Logger LOG =
Logger.getLogger(AndroidNetworkManager.class.getName());
getLogger(AndroidNetworkManager.class.getName());
// See android.net.wifi.WifiManager
private static final String WIFI_AP_STATE_CHANGED_ACTION =
@@ -56,6 +56,7 @@ class AndroidNetworkManager implements NetworkManager, Service {
new AtomicReference<>();
private final AtomicBoolean used = new AtomicBoolean(false);
@Nullable
private volatile BroadcastReceiver networkStateReceiver = null;
@Inject
@@ -89,9 +90,8 @@ class AndroidNetworkManager implements NetworkManager, Service {
@Override
public NetworkStatus getNetworkStatus() {
ConnectivityManager cm = (ConnectivityManager)
appContext.getSystemService(CONNECTIVITY_SERVICE);
if (cm == null) throw new AssertionError();
ConnectivityManager cm = (ConnectivityManager) requireNonNull(
appContext.getSystemService(CONNECTIVITY_SERVICE));
NetworkInfo net = cm.getActiveNetworkInfo();
boolean connected = net != null && net.isConnected();
boolean wifi = connected && net.getType() == TYPE_WIFI;

View File

@@ -24,7 +24,6 @@ import java.io.IOException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
@@ -48,9 +47,11 @@ import static android.bluetooth.BluetoothAdapter.STATE_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static android.bluetooth.BluetoothDevice.ACTION_FOUND;
import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
import static java.util.Collections.shuffle;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
@MethodsNotNullByDefault
@@ -58,7 +59,7 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
private static final Logger LOG =
Logger.getLogger(AndroidBluetoothPlugin.class.getName());
getLogger(AndroidBluetoothPlugin.class.getName());
private static final int MAX_DISCOVERY_MS = 10_000;
@@ -259,7 +260,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
appContext.unregisterReceiver(receiver);
}
// Shuffle the addresses so we don't always try the same one first
Collections.shuffle(addresses);
shuffle(addresses);
return addresses;
}

View File

@@ -32,17 +32,19 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
import static java.util.logging.Logger.getLogger;
@NotNullByDefault
class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
private static final Logger LOG =
getLogger(AndroidLanTcpPlugin.class.getName());
private static final byte[] WIFI_AP_ADDRESS_BYTES =
{(byte) 192, (byte) 168, 43, 1};
private static final InetAddress WIFI_AP_ADDRESS;
private static final Logger LOG =
Logger.getLogger(AndroidLanTcpPlugin.class.getName());
static {
try {
WIFI_AP_ADDRESS = InetAddress.getByAddress(WIFI_AP_ADDRESS_BYTES);
@@ -66,10 +68,8 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
// Don't execute more than one connection status check at a time
connectionStatusExecutor =
new PoliteExecutor("AndroidLanTcpPlugin", ioExecutor, 1);
ConnectivityManager connectivityManager = (ConnectivityManager)
appContext.getSystemService(CONNECTIVITY_SERVICE);
if (connectivityManager == null) throw new AssertionError();
this.connectivityManager = connectivityManager;
connectivityManager = (ConnectivityManager) requireNonNull(
appContext.getSystemService(CONNECTIVITY_SERVICE));
wifiManager = (WifiManager) appContext.getApplicationContext()
.getSystemService(WIFI_SERVICE);
socketFactory = SocketFactory.getDefault();

View File

@@ -8,8 +8,7 @@ import android.os.PowerManager;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.system.Clock;
@@ -26,10 +25,10 @@ import javax.net.SocketFactory;
import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.POWER_SERVICE;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MINUTES;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@NotNullByDefault
class AndroidTorPlugin extends TorPlugin {
// This tag may prevent Huawei's power manager from killing us
@@ -52,8 +51,7 @@ class AndroidTorPlugin extends TorPlugin {
appContext.getDir("tor", MODE_PRIVATE));
this.appContext = appContext;
PowerManager pm = (PowerManager)
appContext.getSystemService(POWER_SERVICE);
if (pm == null) throw new AssertionError();
requireNonNull(appContext.getSystemService(POWER_SERVICE));
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
WAKE_LOCK_TAG, 1, MINUTES);
}

View File

@@ -1,7 +1,6 @@
package org.briarproject.bramble.plugin.tor;
import android.content.Context;
import android.os.Build;
import org.briarproject.bramble.api.battery.BatteryManager;
import org.briarproject.bramble.api.event.EventBus;
@@ -26,12 +25,15 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import javax.net.SocketFactory;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.logging.Logger.getLogger;
@Immutable
@NotNullByDefault
public class AndroidTorPluginFactory implements DuplexPluginFactory {
private static final Logger LOG =
Logger.getLogger(AndroidTorPluginFactory.class.getName());
getLogger(AndroidTorPluginFactory.class.getName());
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
@@ -102,7 +104,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
return null;
}
// Use position-independent executable for SDK >= 16
if (Build.VERSION.SDK_INT >= 16) architecture += "_pie";
if (SDK_INT >= 16) architecture += "_pie";
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);

View File

@@ -15,12 +15,13 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static android.content.Context.TELEPHONY_SERVICE;
import static java.util.logging.Logger.getLogger;
@NotNullByDefault
class AndroidLocationUtils implements LocationUtils {
private static final Logger LOG =
Logger.getLogger(AndroidLocationUtils.class.getName());
getLogger(AndroidLocationUtils.class.getName());
private final Context appContext;
@@ -59,14 +60,14 @@ class AndroidLocationUtils implements LocationUtils {
}
private String getCountryFromPhoneNetwork() {
Object o = appContext.getSystemService(TELEPHONY_SERVICE);
TelephonyManager tm = (TelephonyManager) o;
return tm.getNetworkCountryIso();
TelephonyManager tm = (TelephonyManager)
appContext.getSystemService(TELEPHONY_SERVICE);
return tm == null ? "" : tm.getNetworkCountryIso();
}
private String getCountryFromSimCard() {
Object o = appContext.getSystemService(TELEPHONY_SERVICE);
TelephonyManager tm = (TelephonyManager) o;
return tm.getSimCountryIso();
TelephonyManager tm = (TelephonyManager)
appContext.getSystemService(TELEPHONY_SERVICE);
return tm == null ? "" : tm.getSimCountryIso();
}
}

View File

@@ -8,7 +8,6 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Parcel;
import android.os.StrictMode;
import android.provider.Settings;
@@ -23,6 +22,9 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static android.content.Context.WIFI_SERVICE;
import static android.os.Build.FINGERPRINT;
import static android.os.Build.SERIAL;
import static android.os.Build.VERSION.SDK_INT;
import static android.provider.Settings.Secure.ANDROID_ID;
@Immutable
@@ -45,8 +47,8 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
out.writeInt(android.os.Process.myPid());
out.writeInt(android.os.Process.myTid());
out.writeInt(android.os.Process.myUid());
if (Build.FINGERPRINT != null) out.writeUTF(Build.FINGERPRINT);
if (Build.SERIAL != null) out.writeUTF(Build.SERIAL);
if (FINGERPRINT != null) out.writeUTF(FINGERPRINT);
if (SERIAL != null) out.writeUTF(SERIAL);
ContentResolver contentResolver = appContext.getContentResolver();
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
if (id != null) out.writeUTF(id);
@@ -74,15 +76,13 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
// Silence strict mode
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskWrites();
super.writeSeed();
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT <= 18)
applyOpenSslFix();
if (SDK_INT >= 16 && SDK_INT <= 18) applyOpenSslFix();
StrictMode.setThreadPolicy(tp);
}
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
private void applyOpenSslFix() {
byte[] seed = new UnixSecureRandomSpi().engineGenerateSeed(
SEED_LENGTH);
byte[] seed = new UnixSecureRandomSpi().engineGenerateSeed(SEED_LENGTH);
try {
// Seed the OpenSSL PRNG
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")

View File

@@ -3,17 +3,20 @@ package org.briarproject.bramble.util;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static android.content.Context.MODE_PRIVATE;
import static android.os.Build.CPU_ABI;
import static android.os.Build.CPU_ABI2;
import static android.os.Build.SUPPORTED_ABIS;
import static android.os.Build.VERSION.SDK_INT;
import static java.util.Arrays.asList;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
public class AndroidUtils {
@@ -22,14 +25,13 @@ public class AndroidUtils {
private static final String STORED_REPORTS = "dev-reports";
@SuppressWarnings("deprecation")
public static Collection<String> getSupportedArchitectures() {
List<String> abis = new ArrayList<>();
if (SDK_INT >= 21) {
abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
abis.addAll(asList(SUPPORTED_ABIS));
} else {
abis.add(Build.CPU_ABI);
if (Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
abis.add(CPU_ABI);
if (CPU_ABI2 != null) abis.add(CPU_ABI2);
}
return abis;
}
@@ -49,7 +51,7 @@ public class AndroidUtils {
}
private static boolean isValidBluetoothAddress(String address) {
return !StringUtils.isNullOrEmpty(address)
return !isNullOrEmpty(address)
&& BluetoothAdapter.checkBluetoothAddress(address)
&& !address.equals(FAKE_BLUETOOTH_ADDRESS);
}

View File

@@ -10,17 +10,19 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@ThreadSafe
@NotNullByDefault
public class RenewableWakeLock {
private static final Logger LOG =
Logger.getLogger(RenewableWakeLock.class.getName());
getLogger(RenewableWakeLock.class.getName());
/**
* Automatically release the lock this many milliseconds after it's due
@@ -36,10 +38,12 @@ public class RenewableWakeLock {
private final Runnable renewTask;
private final Object lock = new Object();
@GuardedBy("lock")
@Nullable
private PowerManager.WakeLock wakeLock; // Locking: lock
private PowerManager.WakeLock wakeLock;
@GuardedBy("lock")
@Nullable
private ScheduledFuture future; // Locking: lock
private ScheduledFuture future;
public RenewableWakeLock(PowerManager powerManager,
ScheduledExecutorService scheduler, int levelAndFlags, String tag,

View File

@@ -1,13 +1,14 @@
package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import java.util.Arrays;
import java.util.Comparator;
import javax.annotation.concurrent.ThreadSafe;
import static org.briarproject.bramble.util.StringUtils.toHexString;
/**
* A wrapper around a byte array, to allow it to be stored in maps etc.
*/
@@ -56,8 +57,7 @@ public class Bytes implements Comparable<Bytes> {
@Override
public String toString() {
return getClass().getSimpleName() +
"(" + StringUtils.toHexString(getBytes()) + ")";
return getClass().getSimpleName() + "(" + toHexString(getBytes()) + ")";
}
public static class BytesComparator implements Comparator<Bytes> {

View File

@@ -2,7 +2,6 @@ package org.briarproject.bramble.api;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
@@ -10,6 +9,8 @@ import java.util.Set;
import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Collections.unmodifiableSet;
@NotThreadSafe
@NotNullByDefault
public class Multiset<T> {
@@ -96,6 +97,6 @@ public class Multiset<T> {
* is unmodifiable.
*/
public Set<T> keySet() {
return Collections.unmodifiableSet(map.keySet());
return unmodifiableSet(map.keySet());
}
}

View File

@@ -5,10 +5,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;
import java.util.Collection;
import java.util.Collections;
import javax.annotation.concurrent.Immutable;
import static java.util.Collections.emptyList;
@Immutable
@NotNullByDefault
public class BdfMessageContext {
@@ -23,7 +24,7 @@ public class BdfMessageContext {
}
public BdfMessageContext(BdfDictionary dictionary) {
this(dictionary, Collections.emptyList());
this(dictionary, emptyList());
}
public BdfDictionary getDictionary() {

View File

@@ -16,6 +16,7 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
@Immutable
@@ -23,7 +24,7 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC
public abstract class BdfMessageValidator implements MessageValidator {
protected static final Logger LOG =
Logger.getLogger(BdfMessageValidator.class.getName());
getLogger(BdfMessageValidator.class.getName());
protected final ClientHelper clientHelper;
protected final MetadataEncoder metadataEncoder;

View File

@@ -13,6 +13,8 @@ import java.util.Collection;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.FAILED;
@NotNullByDefault
public interface ContactManager {
@@ -52,6 +54,35 @@ public interface ContactManager {
long timestamp, boolean alice, boolean verified, boolean active)
throws DbException;
/**
* Returns the static link that needs to be sent to the contact to be added.
*/
String getRemoteContactLink();
/**
* Returns true if the given link is syntactically valid.
*/
boolean isValidRemoteContactLink(String link);
/**
* Requests a new contact to be added via the given {@code link}.
*
* @param link The link received from the contact we want to add.
* @param alias The alias the user has given this contact.
* @return A PendingContact representing the contact to be added.
*/
PendingContact addRemoteContactRequest(String link, String alias);
/**
* Returns a list of {@link PendingContact}s.
*/
Collection<PendingContact> getPendingContacts();
/**
* Removes a {@link PendingContact} that is in state {@link FAILED}.
*/
void removePendingContact(PendingContact pendingContact);
/**
* Returns the contact with the given ID.
*/

View File

@@ -0,0 +1,54 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class PendingContact {
public enum PendingContactState {
WAITING_FOR_CONNECTION,
CONNECTED,
ADDING_CONTACT,
FAILED
}
private final PendingContactId id;
private final String alias;
private final PendingContactState state;
private final long timestamp;
public PendingContact(PendingContactId id, String alias,
PendingContactState state, long timestamp) {
this.id = id;
this.alias = alias;
this.state = state;
this.timestamp = timestamp;
}
public String getAlias() {
return alias;
}
public PendingContactState getState() {
return state;
}
public long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object o) {
return o instanceof PendingContact &&
id.equals(((PendingContact) o).id);
}
}

View File

@@ -0,0 +1,11 @@
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.UniqueId;
public class PendingContactId extends UniqueId {
public PendingContactId(byte[] id) {
super(id);
}
}

View File

@@ -0,0 +1,34 @@
package org.briarproject.bramble.api.contact.event;
import org.briarproject.bramble.api.contact.PendingContact.PendingContactState;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a pending contact's state is changed.
*/
@Immutable
@NotNullByDefault
public class PendingContactStateChangedEvent extends Event {
private final PendingContactId id;
private final PendingContactState state;
public PendingContactStateChangedEvent(PendingContactId id,
PendingContactState state) {
this.id = id;
this.state = state;
}
public PendingContactId getId() {
return id;
}
public PendingContactState getPendingContactState() {
return state;
}
}

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.annotation.Nullable;
@@ -24,9 +23,9 @@ public class BdfDictionary extends TreeMap<String, Object> {
* );
* </pre>
*/
public static BdfDictionary of(Entry<String, ?>... entries) {
public static BdfDictionary of(BdfEntry... entries) {
BdfDictionary d = new BdfDictionary();
for (Entry<String, ?> e : entries) d.put(e.getKey(), e.getValue());
for (BdfEntry e : entries) d.put(e.getKey(), e.getValue());
return d;
}

View File

@@ -4,12 +4,12 @@ import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Arrays.asList;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
@NotThreadSafe
@@ -22,7 +22,7 @@ public class BdfList extends ArrayList<Object> {
* </pre>
*/
public static BdfList of(Object... items) {
return new BdfList(Arrays.asList(items));
return new BdfList(asList(items));
}
public BdfList() {
@@ -33,6 +33,7 @@ public class BdfList extends ArrayList<Object> {
super(items);
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean isInRange(int index) {
return index >= 0 && index < size();
}

View File

@@ -3,11 +3,12 @@ package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.Event;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Collections.emptyList;
/**
* A wrapper around a database transaction. Transactions are not thread-safe.
*/
@@ -53,7 +54,7 @@ public class Transaction {
* Returns any events attached to the transaction.
*/
public List<Event> getEvents() {
if (events == null) return Collections.emptyList();
if (events == null) return emptyList();
return events;
}

View File

@@ -2,12 +2,12 @@ package org.briarproject.bramble.api.identity;
import org.briarproject.bramble.api.Nameable;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
/**
* A pseudonym for a user.
@@ -28,7 +28,7 @@ public class Author implements Nameable {
public Author(AuthorId id, int formatVersion, String name,
byte[] publicKey) {
int nameLength = StringUtils.toUtf8(name).length;
int nameLength = toUtf8(name).length;
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
throw new IllegalArgumentException();
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)

View File

@@ -16,6 +16,7 @@ public interface TorConstants {
String PREF_TOR_NETWORK = "network2";
String PREF_TOR_PORT = "port";
String PREF_TOR_MOBILE = "useMobileData";
String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging";
int PREF_TOR_NETWORK_AUTOMATIC = 0;
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;

View File

@@ -1,6 +1,6 @@
package org.briarproject.bramble.api.plugin;
import org.briarproject.bramble.util.StringUtils;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
/**
* Type-safe wrapper for a namespaced string that uniquely identifies a
@@ -11,12 +11,12 @@ public class TransportId {
/**
* The maximum length of a transport identifier in UTF-8 bytes.
*/
public static int MAX_TRANSPORT_ID_LENGTH = 100;
public static final int MAX_TRANSPORT_ID_LENGTH = 100;
private final String id;
public TransportId(String id) {
int length = StringUtils.toUtf8(id).length;
int length = toUtf8(id).length;
if (length == 0 || length > MAX_TRANSPORT_ID_LENGTH)
throw new IllegalArgumentException();
this.id = id;

View File

@@ -1,10 +1,11 @@
package org.briarproject.bramble.api.sync;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
/**
* Type-safe wrapper for a namespaced string that uniquely identifies a sync
* client.
@@ -16,12 +17,12 @@ public class ClientId implements Comparable<ClientId> {
/**
* The maximum length of a client identifier in UTF-8 bytes.
*/
public static int MAX_CLIENT_ID_LENGTH = 100;
public static final int MAX_CLIENT_ID_LENGTH = 100;
private final String id;
public ClientId(String id) {
int length = StringUtils.toUtf8(id).length;
int length = toUtf8(id).length;
if (length == 0 || length > MAX_CLIENT_ID_LENGTH)
throw new IllegalArgumentException();
this.id = id;

View File

@@ -4,10 +4,11 @@ import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Collection;
import java.util.Collections;
import javax.annotation.concurrent.Immutable;
import static java.util.Collections.emptyList;
@Immutable
@NotNullByDefault
public class MessageContext {
@@ -22,7 +23,7 @@ public class MessageContext {
}
public MessageContext(Metadata metadata) {
this(metadata, Collections.emptyList());
this(metadata, emptyList());
}
public Metadata getMetadata() {

View File

@@ -38,6 +38,13 @@ public interface ClientVersioningManager {
Visibility getClientVisibility(Transaction txn, ContactId contactId,
ClientId clientId, int majorVersion) throws DbException;
/**
* Returns the minor version of the given client that is supported by the
* given contact, or -1 if the contact does not support the client.
*/
int getClientMinorVersion(Transaction txn, ContactId contactId,
ClientId clientId, int majorVersion) throws DbException;
interface ClientVersioningHook {
void onClientVisibilityChanging(Transaction txn, Contact c,

View File

@@ -1,7 +1,5 @@
package org.briarproject.bramble.util;
import org.briarproject.bramble.api.FormatException;
public class ByteUtils {
/**
@@ -14,26 +12,15 @@ public class ByteUtils {
*/
public static final long MAX_32_BIT_UNSIGNED = 4294967295L; // 2^32 - 1
/**
* The number of bytes needed to encode a 16-bit integer.
*/
/** The number of bytes needed to encode a 16-bit integer. */
public static final int INT_16_BYTES = 2;
/**
* The number of bytes needed to encode a 32-bit integer.
*/
/** The number of bytes needed to encode a 32-bit integer. */
public static final int INT_32_BYTES = 4;
/**
* The number of bytes needed to encode a 64-bit integer.
*/
/** The number of bytes needed to encode a 64-bit integer. */
public static final int INT_64_BYTES = 8;
/**
* The maximum number of bytes needed to encode a variable-length integer.
*/
public static final int MAX_VARINT_BYTES = 9;
public static void writeUint16(int src, byte[] dest, int offset) {
if (src < 0) throw new IllegalArgumentException();
if (src > MAX_16_BIT_UNSIGNED) throw new IllegalArgumentException();
@@ -68,42 +55,6 @@ public class ByteUtils {
dest[offset + 7] = (byte) (src & 0xFF);
}
/**
* Returns the number of bytes needed to represent 'src' as a
* variable-length integer.
* <p>
* 'src' must not be negative.
*/
public static int getVarIntBytes(long src) {
if (src < 0) throw new IllegalArgumentException();
int len = 1;
while ((src >>= 7) > 0) len++;
return len;
}
/**
* Writes 'src' to 'dest' as a variable-length integer, starting at
* 'offset', and returns the number of bytes written.
* <p>
* `src` must not be negative.
*/
public static int writeVarInt(long src, byte[] dest, int offset) {
if (src < 0) throw new IllegalArgumentException();
int len = getVarIntBytes(src);
if (dest.length < offset + len) throw new IllegalArgumentException();
// Work backwards from the end
int end = offset + len - 1;
for (int i = end; i >= offset; i--) {
// Encode 7 bits
dest[i] = (byte) (src & 0x7F);
// Raise the continuation flag, except for the last byte
if (i < end) dest[i] |= (byte) 0x80;
// Shift out the bits that were encoded
src >>= 7;
}
return len;
}
public static int readUint16(byte[] src, int offset) {
if (src.length < offset + INT_16_BYTES)
throw new IllegalArgumentException();
@@ -132,46 +83,14 @@ public class ByteUtils {
| (src[offset + 7] & 0xFFL);
}
/**
* Returns the length in bytes of a variable-length integer encoded in
* 'src' starting at 'offset'.
*
* @throws FormatException if there is not a valid variable-length integer
* at the specified position.
*/
public static int getVarIntBytes(byte[] src, int offset)
throws FormatException {
if (src.length < offset) throw new IllegalArgumentException();
for (int i = 0; i < MAX_VARINT_BYTES && offset + i < src.length; i++) {
// If the continuation flag is lowered, this is the last byte
if ((src[offset + i] & 0x80) == 0) return i + 1;
public static int readUint(byte[] src, int bits) {
if (src.length << 3 < bits) throw new IllegalArgumentException();
int dest = 0;
for (int i = 0; i < bits; i++) {
if ((src[i >> 3] & 128 >> (i & 7)) != 0) dest |= 1 << bits - i - 1;
}
// We've read 9 bytes or reached the end of the input without finding
// the last byte
throw new FormatException();
}
/**
* Reads a variable-length integer from 'src' starting at 'offset' and
* returns it.
*
* @throws FormatException if there is not a valid variable-length integer
* at the specified position.
*/
public static long readVarInt(byte[] src, int offset)
throws FormatException {
if (src.length < offset) throw new IllegalArgumentException();
long dest = 0;
for (int i = 0; i < MAX_VARINT_BYTES && offset + i < src.length; i++) {
// Decode 7 bits
dest |= src[offset + i] & 0x7F;
// If the continuation flag is lowered, this is the last byte
if ((src[offset + i] & 0x80) == 0) return dest;
// Make room for the next 7 bits
dest <<= 7;
}
// We've read 9 bytes or reached the end of the input without finding
// the last byte
throw new FormatException();
if (dest < 0) throw new AssertionError();
if (dest >= 1 << bits) throw new AssertionError();
return dest;
}
}

View File

@@ -16,12 +16,13 @@ import java.util.logging.Logger;
import javax.annotation.Nullable;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
public class IoUtils {
private static final Logger LOG = Logger.getLogger(IoUtils.class.getName());
private static final Logger LOG = getLogger(IoUtils.class.getName());
public static void deleteFileOrDir(File f) {
if (f.isFile()) {

View File

@@ -7,13 +7,15 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@NotNullByDefault
public class ValidationUtils {
public static void checkLength(@Nullable String s, int minLength,
int maxLength) throws FormatException {
if (s != null) {
int length = StringUtils.toUtf8(s).length;
int length = toUtf8(s).length;
if (length < minLength) throw new FormatException();
if (length > maxLength) throw new FormatException();
}
@@ -21,7 +23,7 @@ public class ValidationUtils {
public static void checkLength(@Nullable String s, int length)
throws FormatException {
if (s != null && StringUtils.toUtf8(s).length != length)
if (s != null && toUtf8(s).length != length)
throw new FormatException();
}

View File

@@ -8,6 +8,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.Map.Entry;
import static java.util.Collections.singletonMap;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -19,15 +20,15 @@ public class BdfDictionaryTest extends BrambleTestCase {
public void testConstructors() {
assertEquals(Collections.<String, Object>emptyMap(),
new BdfDictionary());
assertEquals(Collections.singletonMap("foo", NULL_VALUE),
new BdfDictionary(Collections.singletonMap("foo", NULL_VALUE)));
assertEquals(singletonMap("foo", NULL_VALUE),
new BdfDictionary(singletonMap("foo", NULL_VALUE)));
}
@Test
public void testFactoryMethod() {
assertEquals(Collections.<String, Object>emptyMap(),
BdfDictionary.of());
assertEquals(Collections.singletonMap("foo", NULL_VALUE),
assertEquals(singletonMap("foo", NULL_VALUE),
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)));
}
@@ -67,7 +68,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
}
@Test
public void testKeySetIteratorIsOrderedByKeys() throws Exception {
public void testKeySetIteratorIsOrderedByKeys() {
BdfDictionary d = new BdfDictionary();
d.put("a", 1);
d.put("d", 4);
@@ -86,7 +87,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
}
@Test
public void testValuesIteratorIsOrderedByKeys() throws Exception {
public void testValuesIteratorIsOrderedByKeys() {
BdfDictionary d = new BdfDictionary();
d.put("a", 1);
d.put("d", 4);
@@ -105,7 +106,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
}
@Test
public void testEntrySetIteratorIsOrderedByKeys() throws Exception {
public void testEntrySetIteratorIsOrderedByKeys() {
BdfDictionary d = new BdfDictionary();
d.put("a", 1);
d.put("d", 4);

View File

@@ -5,26 +5,31 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
public class BdfListTest extends BrambleTestCase {
private final Random random = new Random();
@Test
public void testConstructors() {
assertEquals(Collections.emptyList(), new BdfList());
assertEquals(Arrays.asList(1, 2, NULL_VALUE),
new BdfList(Arrays.asList(1, 2, NULL_VALUE)));
assertEquals(emptyList(), new BdfList());
assertEquals(asList(1, 2, NULL_VALUE),
new BdfList(asList(1, 2, NULL_VALUE)));
}
@Test
public void testFactoryMethod() {
assertEquals(Collections.emptyList(), BdfList.of());
assertEquals(Arrays.asList(1, 2, NULL_VALUE),
assertEquals(emptyList(), BdfList.of());
assertEquals(asList(1, 2, NULL_VALUE),
BdfList.of(1, 2, NULL_VALUE));
}
@@ -64,22 +69,21 @@ public class BdfListTest extends BrambleTestCase {
}
@Test
@SuppressWarnings("ConstantConditions")
public void testIndexOutOfBoundsReturnsDefaultValue() throws Exception {
public void testIndexOutOfBoundsReturnsDefaultValue() {
BdfList list = BdfList.of(1, 2, 3);
boolean defaultBoolean = true;
boolean defaultBoolean = random.nextBoolean();
assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean));
assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean));
Long defaultLong = 123L;
Long defaultLong = random.nextLong();
assertEquals(defaultLong, list.getLong(-1, defaultLong));
assertEquals(defaultLong, list.getLong(3, defaultLong));
Double defaultDouble = 1.23;
Double defaultDouble = random.nextDouble();
assertEquals(defaultDouble, list.getDouble(-1, defaultDouble));
assertEquals(defaultDouble, list.getDouble(3, defaultDouble));
String defaultString = "123";
String defaultString = getRandomString(123);
assertEquals(defaultString, list.getString(-1, defaultString));
assertEquals(defaultString, list.getString(3, defaultString));
byte[] defaultBytes = new byte[] {1, 2, 3};
byte[] defaultBytes = getRandomBytes(123);
assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes));
assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes));
BdfList defaultList = BdfList.of(1, 2, 3);
@@ -95,18 +99,17 @@ public class BdfListTest extends BrambleTestCase {
}
@Test
@SuppressWarnings("ConstantConditions")
public void testWrongTypeReturnsDefaultValue() throws Exception {
public void testWrongTypeReturnsDefaultValue() {
BdfList list = BdfList.of(1, 2, 3, true);
boolean defaultBoolean = true;
boolean defaultBoolean = random.nextBoolean();
assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean));
Long defaultLong = 123L;
Long defaultLong = random.nextLong();
assertEquals(defaultLong, list.getLong(3, defaultLong));
Double defaultDouble = 1.23;
Double defaultDouble = random.nextDouble();
assertEquals(defaultDouble, list.getDouble(0, defaultDouble));
String defaultString = "123";
String defaultString = getRandomString(123);
assertEquals(defaultString, list.getString(0, defaultString));
byte[] defaultBytes = new byte[] {1, 2, 3};
byte[] defaultBytes = getRandomBytes(123);
assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes));
BdfList defaultList = BdfList.of(1, 2, 3);
assertEquals(defaultList, list.getList(0, defaultList));

View File

@@ -12,12 +12,10 @@ import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.util.IoUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -25,6 +23,7 @@ import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Arrays.asList;
import static java.util.Collections.sort;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
@@ -33,6 +32,7 @@ import static org.briarproject.bramble.api.properties.TransportPropertyConstants
import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
public class TestUtils {
@@ -48,8 +48,10 @@ public class TestUtils {
}
public static void deleteTestDirectory(File testDir) {
IoUtils.deleteFileOrDir(testDir);
testDir.getParentFile().delete(); // Delete if empty
deleteFileOrDir(testDir);
// Delete parent directory only if it's empty
//noinspection ResultOfMethodCallIgnored
testDir.getParentFile().delete();
}
public static byte[] getRandomBytes(int length) {
@@ -145,7 +147,7 @@ public class TestUtils {
if (size == 0) throw new IllegalArgumentException();
List<Double> sorted = new ArrayList<>(size);
for (Number n : samples) sorted.add(n.doubleValue());
Collections.sort(sorted);
sort(sorted);
if (size % 2 == 1) return sorted.get(size / 2);
double low = sorted.get(size / 2 - 1), high = sorted.get(size / 2);
return (low + high) / 2;

View File

@@ -10,6 +10,7 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.GuardedBy;
import static java.util.logging.Level.FINE;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.now;
/**
@@ -42,7 +43,7 @@ public class PoliteExecutor implements Executor {
int maxConcurrentTasks) {
this.delegate = delegate;
this.maxConcurrentTasks = maxConcurrentTasks;
log = Logger.getLogger(tag);
log = getLogger(tag);
}
@Override

View File

@@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault
@@ -22,7 +23,7 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
RejectedExecutionHandler handler) {
super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue,
handler);
log = Logger.getLogger(tag);
log = getLogger(tag);
}
@Override

View File

@@ -6,9 +6,7 @@ import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.io.BufferedReader;
import java.io.File;
@@ -19,19 +17,21 @@ import java.io.InputStreamReader;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.fromHexString;
import static org.briarproject.bramble.util.StringUtils.toHexString;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@NotNullByDefault
class AccountManagerImpl implements AccountManager {
private static final Logger LOG =
Logger.getLogger(AccountManagerImpl.class.getName());
getLogger(AccountManagerImpl.class.getName());
private static final String DB_KEY_FILENAME = "db.key";
private static final String DB_KEY_BACKUP_FILENAME = "db.key.bak";
@@ -68,7 +68,7 @@ class AccountManagerImpl implements AccountManager {
return databaseKey;
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
@Nullable
protected String loadEncryptedDatabaseKey() {
String key = readDbKeyFromFile(dbKeyFile);
@@ -83,7 +83,7 @@ class AccountManagerImpl implements AccountManager {
return key;
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
@Nullable
private String readDbKeyFromFile(File f) {
if (!f.exists()) {
@@ -102,8 +102,8 @@ class AccountManagerImpl implements AccountManager {
}
}
// Locking: stateChangeLock
protected boolean storeEncryptedDatabaseKey(String hex) {
@GuardedBy("stateChangeLock")
boolean storeEncryptedDatabaseKey(String hex) {
LOG.info("Storing database key in file");
// Create the directory if necessary
if (databaseConfig.getDatabaseKeyDirectory().mkdirs())
@@ -140,7 +140,7 @@ class AccountManagerImpl implements AccountManager {
}
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
private void writeDbKeyToFile(String key, File f) throws IOException {
FileOutputStream out = new FileOutputStream(f);
out.write(key.getBytes("UTF-8"));
@@ -170,7 +170,7 @@ class AccountManagerImpl implements AccountManager {
}
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
private boolean encryptAndStoreDatabaseKey(SecretKey key, String password) {
byte[] plaintext = key.getBytes();
byte[] ciphertext = crypto.encryptWithPassword(plaintext, password);
@@ -181,8 +181,8 @@ class AccountManagerImpl implements AccountManager {
public void deleteAccount() {
synchronized (stateChangeLock) {
LOG.info("Deleting account");
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseDirectory());
deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
deleteFileOrDir(databaseConfig.getDatabaseDirectory());
databaseKey = null;
}
}
@@ -197,7 +197,7 @@ class AccountManagerImpl implements AccountManager {
}
}
// Locking: stateChangeLock
@GuardedBy("stateChangeLock")
@Nullable
private SecretKey loadAndDecryptDatabaseKey(String password) {
String hex = loadEncryptedDatabaseKey();

View File

@@ -43,6 +43,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.util.LogUtils.logException;
@@ -54,7 +55,7 @@ import static org.briarproject.bramble.util.ValidationUtils.checkSize;
class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
private static final Logger LOG =
Logger.getLogger(ContactExchangeTaskImpl.class.getName());
getLogger(ContactExchangeTaskImpl.class.getName());
private static final String SIGNING_LABEL_EXCHANGE =
"org.briarproject.briar.contact/EXCHANGE";
@@ -190,6 +191,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
streamWriter.sendEndOfStream();
// Skip any remaining records from the incoming stream
try {
//noinspection InfiniteLoopStatement
while (true) recordReader.readRecord();
} catch (EOFException expected) {
LOG.info("End of stream");

View File

@@ -3,6 +3,8 @@ package org.briarproject.bramble.contact;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
@@ -19,12 +21,16 @@ import org.briarproject.bramble.api.transport.KeyManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.Collections.emptyList;
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.WAITING_FOR_CONNECTION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
@@ -36,6 +42,12 @@ import static org.briarproject.bramble.util.StringUtils.toUtf8;
@NotNullByDefault
class ContactManagerImpl implements ContactManager {
private static final int LINK_LENGTH = 64;
private static final String REMOTE_CONTACT_LINK =
"briar://" + getRandomBase32String(LINK_LENGTH);
private static final Pattern LINK_REGEX =
Pattern.compile("(briar://)?([a-z2-7]{" + LINK_LENGTH + "})");
private final DatabaseComponent db;
private final KeyManager keyManager;
private final IdentityManager identityManager;
@@ -84,6 +96,48 @@ class ContactManagerImpl implements ContactManager {
verified, active));
}
@Override
public String getRemoteContactLink() {
// TODO replace with real implementation
return REMOTE_CONTACT_LINK;
}
@SuppressWarnings("SameParameterValue")
private static String getRandomBase32String(int length) {
Random random = new Random();
char[] c = new char[length];
for (int i = 0; i < length; i++) {
int character = random.nextInt(32);
if (character < 26) c[i] = (char) ('a' + character);
else c[i] = (char) ('2' + (character - 26));
}
return new String(c);
}
@Override
public boolean isValidRemoteContactLink(String link) {
return LINK_REGEX.matcher(link).matches();
}
@Override
public PendingContact addRemoteContactRequest(String link, String alias) {
// TODO replace with real implementation
PendingContactId id = new PendingContactId(link.getBytes());
return new PendingContact(id, alias, WAITING_FOR_CONNECTION,
System.currentTimeMillis());
}
@Override
public Collection<PendingContact> getPendingContacts() {
// TODO replace with real implementation
return emptyList();
}
@Override
public void removePendingContact(PendingContact pendingContact) {
// TODO replace with real implementation
}
@Override
public Contact getContact(ContactId c) throws DbException {
return db.transactionWithResult(true, txn -> db.getContact(txn, c));

View File

@@ -2,18 +2,20 @@ package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import static org.briarproject.bramble.util.StringUtils.fromHexString;
import static org.briarproject.bramble.util.StringUtils.toHexString;
@NotNullByDefault
class AsciiArmour {
static String wrap(byte[] b, int lineLength) {
String wrapped = StringUtils.toHexString(b);
String wrapped = toHexString(b);
StringBuilder s = new StringBuilder();
int length = wrapped.length();
for (int i = 0; i < length; i += lineLength) {
int end = Math.min(i + lineLength, length);
s.append(wrapped.substring(i, end));
s.append(wrapped, i, end);
s.append("\r\n");
}
return s.toString();
@@ -21,7 +23,7 @@ class AsciiArmour {
static byte[] unwrap(String s) throws FormatException {
try {
return StringUtils.fromHexString(s.replaceAll("[^0-9a-fA-F]", ""));
return fromHexString(s.replaceAll("[^0-9a-fA-F]", ""));
} catch (IllegalArgumentException e) {
throw new FormatException();
}

View File

@@ -12,8 +12,6 @@ import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.SecureRandomProvider;
import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.bramble.util.StringUtils;
import org.spongycastle.crypto.CryptoException;
import org.spongycastle.crypto.Digest;
import org.spongycastle.crypto.digests.Blake2bDigest;
@@ -30,16 +28,21 @@ import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import static java.lang.System.arraycopy;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.ByteUtils.readUint32;
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@NotNullByDefault
class CryptoComponentImpl implements CryptoComponent {
private static final Logger LOG =
Logger.getLogger(CryptoComponentImpl.class.getName());
getLogger(CryptoComponentImpl.class.getName());
private static final int SIGNATURE_KEY_PAIR_BITS = 256;
private static final int STORAGE_IV_BYTES = 24; // 196 bits
@@ -188,7 +191,7 @@ class CryptoComponentImpl implements CryptoComponent {
PrivateKey ourPriv = ourKeyPair.getPrivate();
byte[][] hashInputs = new byte[inputs.length + 1][];
hashInputs[0] = performRawKeyAgreement(ourPriv, theirPublicKey);
System.arraycopy(inputs, 0, hashInputs, 1, inputs.length);
arraycopy(inputs, 0, hashInputs, 1, inputs.length);
byte[] hash = hash(label, hashInputs);
if (hash.length != SecretKey.LENGTH) throw new IllegalStateException();
return new SecretKey(hash);
@@ -216,26 +219,26 @@ class CryptoComponentImpl implements CryptoComponent {
private void updateSignature(Signature signature, String label,
byte[] toSign) throws GeneralSecurityException {
byte[] labelBytes = StringUtils.toUtf8(label);
byte[] labelBytes = toUtf8(label);
byte[] length = new byte[INT_32_BYTES];
ByteUtils.writeUint32(labelBytes.length, length, 0);
writeUint32(labelBytes.length, length, 0);
signature.update(length);
signature.update(labelBytes);
ByteUtils.writeUint32(toSign.length, length, 0);
writeUint32(toSign.length, length, 0);
signature.update(length);
signature.update(toSign);
}
@Override
public byte[] hash(String label, byte[]... inputs) {
byte[] labelBytes = StringUtils.toUtf8(label);
byte[] labelBytes = toUtf8(label);
Digest digest = new Blake2bDigest(256);
byte[] length = new byte[INT_32_BYTES];
ByteUtils.writeUint32(labelBytes.length, length, 0);
writeUint32(labelBytes.length, length, 0);
digest.update(length, 0, length.length);
digest.update(labelBytes, 0, labelBytes.length);
for (byte[] input : inputs) {
ByteUtils.writeUint32(input.length, length, 0);
writeUint32(input.length, length, 0);
digest.update(length, 0, length.length);
digest.update(input, 0, input.length);
}
@@ -246,14 +249,14 @@ class CryptoComponentImpl implements CryptoComponent {
@Override
public byte[] mac(String label, SecretKey macKey, byte[]... inputs) {
byte[] labelBytes = StringUtils.toUtf8(label);
byte[] labelBytes = toUtf8(label);
Digest mac = new Blake2bDigest(macKey.getBytes(), 32, null, null);
byte[] length = new byte[INT_32_BYTES];
ByteUtils.writeUint32(labelBytes.length, length, 0);
writeUint32(labelBytes.length, length, 0);
mac.update(length, 0, length.length);
mac.update(labelBytes, 0, labelBytes.length);
for (byte[] input : inputs) {
ByteUtils.writeUint32(input.length, length, 0);
writeUint32(input.length, length, 0);
mac.update(length, 0, length.length);
mac.update(input, 0, input.length);
}
@@ -297,13 +300,13 @@ class CryptoComponentImpl implements CryptoComponent {
output[outputOff] = PBKDF_FORMAT_SCRYPT;
outputOff++;
// Salt
System.arraycopy(salt, 0, output, outputOff, salt.length);
arraycopy(salt, 0, output, outputOff, salt.length);
outputOff += salt.length;
// Cost parameter
ByteUtils.writeUint32(cost, output, outputOff);
writeUint32(cost, output, outputOff);
outputOff += INT_32_BYTES;
// IV
System.arraycopy(iv, 0, output, outputOff, iv.length);
arraycopy(iv, 0, output, outputOff, iv.length);
outputOff += iv.length;
// Initialise the cipher and encrypt the plaintext
try {
@@ -333,16 +336,16 @@ class CryptoComponentImpl implements CryptoComponent {
return null; // Unknown format
// Salt
byte[] salt = new byte[PBKDF_SALT_BYTES];
System.arraycopy(input, inputOff, salt, 0, salt.length);
arraycopy(input, inputOff, salt, 0, salt.length);
inputOff += salt.length;
// Cost parameter
long cost = ByteUtils.readUint32(input, inputOff);
long cost = readUint32(input, inputOff);
inputOff += INT_32_BYTES;
if (cost < 2 || cost > Integer.MAX_VALUE)
return null; // Invalid cost parameter
// IV
byte[] iv = new byte[STORAGE_IV_BYTES];
System.arraycopy(input, inputOff, iv, 0, iv.length);
arraycopy(input, inputOff, iv, 0, iv.length);
inputOff += iv.length;
// Derive the key from the password
SecretKey key = passwordBasedKdf.deriveKey(password, salt, (int) cost);

View File

@@ -7,6 +7,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.security.GeneralSecurityException;
import static java.lang.System.arraycopy;
@NotNullByDefault
class Curve25519KeyParser implements KeyParser {
@@ -26,7 +28,7 @@ class Curve25519KeyParser implements KeyParser {
static byte[] clamp(byte[] b) {
byte[] clamped = new byte[32];
System.arraycopy(b, 0, clamped, 0, 32);
arraycopy(b, 0, clamped, 0, 32);
clamped[0] &= 248;
clamped[31] &= 127;
clamped[31] |= 64;

View File

@@ -1,13 +1,15 @@
package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.ByteUtils;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
import static org.briarproject.bramble.util.ByteUtils.readUint16;
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
import static org.briarproject.bramble.util.ByteUtils.writeUint64;
@NotNullByDefault
class FrameEncoder {
@@ -16,7 +18,7 @@ class FrameEncoder {
if (dest.length < FRAME_NONCE_LENGTH)
throw new IllegalArgumentException();
if (frameNumber < 0) throw new IllegalArgumentException();
ByteUtils.writeUint64(frameNumber, dest, 0);
writeUint64(frameNumber, dest, 0);
if (header) dest[0] |= 0x80;
for (int i = INT_64_BYTES; i < FRAME_NONCE_LENGTH; i++) dest[i] = 0;
}
@@ -29,8 +31,8 @@ class FrameEncoder {
if (paddingLength < 0) throw new IllegalArgumentException();
if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
throw new IllegalArgumentException();
ByteUtils.writeUint16(payloadLength, dest, 0);
ByteUtils.writeUint16(paddingLength, dest, INT_16_BYTES);
writeUint16(payloadLength, dest, 0);
writeUint16(paddingLength, dest, INT_16_BYTES);
if (finalFrame) dest[0] |= 0x80;
}
@@ -43,12 +45,12 @@ class FrameEncoder {
static int getPayloadLength(byte[] header) {
if (header.length < FRAME_HEADER_PLAINTEXT_LENGTH)
throw new IllegalArgumentException();
return ByteUtils.readUint16(header, 0) & 0x7FFF;
return readUint16(header, 0) & 0x7FFF;
}
static int getPaddingLength(byte[] header) {
if (header.length < FRAME_HEADER_PLAINTEXT_LENGTH)
throw new IllegalArgumentException();
return ByteUtils.readUint16(header, INT_16_BYTES);
return readUint16(header, INT_16_BYTES);
}
}

View File

@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.crypto.SecretKey;
import javax.inject.Inject;
import static java.lang.System.arraycopy;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
class KeyAgreementCryptoImpl implements KeyAgreementCrypto {
@@ -24,7 +25,7 @@ class KeyAgreementCryptoImpl implements KeyAgreementCrypto {
byte[] hash = crypto.hash(COMMIT_LABEL, publicKey.getEncoded());
// The output is the first COMMIT_LENGTH bytes of the hash
byte[] commitment = new byte[COMMIT_LENGTH];
System.arraycopy(hash, 0, commitment, 0, COMMIT_LENGTH);
arraycopy(hash, 0, commitment, 0, COMMIT_LENGTH);
return commitment;
}

View File

@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.crypto.KeyParser;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
import org.spongycastle.asn1.x9.X9ECParameters;
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
@@ -45,6 +44,9 @@ import java.util.Scanner;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.util.StringUtils.fromHexString;
import static org.briarproject.bramble.util.StringUtils.toHexString;
@Immutable
@NotNullByDefault
public class MessageEncrypter {
@@ -157,6 +159,7 @@ public class MessageEncrypter {
printUsage();
System.exit(1);
}
//noinspection IfCanBeSwitch
if (args[0].equals("generate")) {
if (args.length != 3) {
printUsage();
@@ -210,11 +213,11 @@ public class MessageEncrypter {
MessageEncrypter encrypter = new MessageEncrypter(random);
KeyPair keyPair = encrypter.generateKeyPair();
PrintStream out = new PrintStream(new FileOutputStream(publicKeyFile));
out.print(StringUtils.toHexString(keyPair.getPublic().getEncoded()));
out.print(toHexString(keyPair.getPublic().getEncoded()));
out.flush();
out.close();
out = new PrintStream(new FileOutputStream(privateKeyFile));
out.print(StringUtils.toHexString(keyPair.getPrivate().getEncoded()));
out.print(toHexString(keyPair.getPrivate().getEncoded()));
out.flush();
out.close();
}
@@ -223,7 +226,7 @@ public class MessageEncrypter {
SecureRandom random = new SecureRandom();
MessageEncrypter encrypter = new MessageEncrypter(random);
InputStream in = new FileInputStream(publicKeyFile);
byte[] keyBytes = StringUtils.fromHexString(readFully(in).trim());
byte[] keyBytes = fromHexString(readFully(in).trim());
PublicKey publicKey =
encrypter.getKeyParser().parsePublicKey(keyBytes);
String message = readFully(System.in);
@@ -236,7 +239,7 @@ public class MessageEncrypter {
SecureRandom random = new SecureRandom();
MessageEncrypter encrypter = new MessageEncrypter(random);
InputStream in = new FileInputStream(privateKeyFile);
byte[] keyBytes = StringUtils.fromHexString(readFully(in).trim());
byte[] keyBytes = fromHexString(readFully(in).trim());
PrivateKey privateKey =
encrypter.getKeyParser().parsePrivateKey(keyBytes);
byte[] ciphertext = AsciiArmour.unwrap(readFully(System.in));

View File

@@ -2,7 +2,6 @@ package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.StringUtils;
import org.spongycastle.crypto.generators.SCrypt;
import java.util.logging.Logger;
@@ -10,13 +9,14 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
class ScryptKdf implements PasswordBasedKdf {
private static final Logger LOG =
Logger.getLogger(ScryptKdf.class.getName());
private static final Logger LOG = getLogger(ScryptKdf.class.getName());
private static final int MIN_COST = 256; // Min parameter N
private static final int MAX_COST = 1024 * 1024; // Max parameter N
@@ -53,7 +53,7 @@ class ScryptKdf implements PasswordBasedKdf {
@Override
public SecretKey deriveKey(String password, byte[] salt, int cost) {
long start = now();
byte[] passwordBytes = StringUtils.toUtf8(password);
byte[] passwordBytes = toUtf8(password);
SecretKey k = new SecretKey(SCrypt.generate(passwordBytes, salt, cost,
BLOCK_SIZE, PARALLELIZATION, SecretKey.LENGTH));
logDuration(LOG, "Deriving key from password", start);

View File

@@ -16,6 +16,8 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import static java.lang.System.arraycopy;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
@@ -28,8 +30,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault
class Sec1KeyParser implements KeyParser {
private static final Logger LOG =
Logger.getLogger(Sec1KeyParser.class.getName());
private static final Logger LOG = getLogger(Sec1KeyParser.class.getName());
private final ECDomainParameters params;
private final BigInteger modulus;
@@ -56,12 +57,12 @@ class Sec1KeyParser implements KeyParser {
if (encodedKey[0] != 4) throw new GeneralSecurityException();
// The x co-ordinate must be >= 0 and < p
byte[] xBytes = new byte[bytesPerInt];
System.arraycopy(encodedKey, 1, xBytes, 0, bytesPerInt);
arraycopy(encodedKey, 1, xBytes, 0, bytesPerInt);
BigInteger x = new BigInteger(1, xBytes); // Positive signum
if (x.compareTo(modulus) >= 0) throw new GeneralSecurityException();
// The y co-ordinate must be >= 0 and < p
byte[] yBytes = new byte[bytesPerInt];
System.arraycopy(encodedKey, 1 + bytesPerInt, yBytes, 0, bytesPerInt);
arraycopy(encodedKey, 1 + bytesPerInt, yBytes, 0, bytesPerInt);
BigInteger y = new BigInteger(1, yBytes); // Positive signum
if (y.compareTo(modulus) >= 0) throw new GeneralSecurityException();
// Verify that y^2 == x^3 + ax + b (mod p)

View File

@@ -2,6 +2,8 @@ package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import static java.lang.System.arraycopy;
@NotNullByDefault
class Sec1Utils {
@@ -10,10 +12,10 @@ class Sec1Utils {
if (src.length < destLen) {
int padding = destLen - src.length;
for (int i = destOff; i < destOff + padding; i++) dest[i] = 0;
System.arraycopy(src, 0, dest, destOff + padding, src.length);
arraycopy(src, 0, dest, destOff + padding, src.length);
} else {
int srcOff = src.length - destLen;
System.arraycopy(src, srcOff, dest, destOff, destLen);
arraycopy(src, srcOff, dest, destOff, destLen);
}
}
}

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.crypto.StreamDecrypter;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.ByteUtils;
import java.io.EOFException;
import java.io.IOException;
@@ -14,6 +13,7 @@ import java.security.GeneralSecurityException;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import static java.lang.System.arraycopy;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
@@ -26,6 +26,8 @@ import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_H
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_PLAINTEXT_LENGTH;
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
import static org.briarproject.bramble.util.ByteUtils.readUint16;
import static org.briarproject.bramble.util.ByteUtils.readUint64;
@NotThreadSafe
@NotNullByDefault
@@ -130,7 +132,7 @@ class StreamDecrypterImpl implements StreamDecrypter {
}
// Extract the nonce
byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
System.arraycopy(streamHeaderCiphertext, 0, streamHeaderNonce, 0,
arraycopy(streamHeaderCiphertext, 0, streamHeaderNonce, 0,
STREAM_HEADER_NONCE_LENGTH);
// Decrypt and authenticate the stream header
try {
@@ -145,17 +147,16 @@ class StreamDecrypterImpl implements StreamDecrypter {
throw new FormatException();
}
// Check the protocol version
int receivedProtocolVersion =
ByteUtils.readUint16(streamHeaderPlaintext, 0);
int receivedProtocolVersion = readUint16(streamHeaderPlaintext, 0);
if (receivedProtocolVersion != PROTOCOL_VERSION)
throw new FormatException();
// Check the stream number
long receivedStreamNumber = ByteUtils.readUint64(streamHeaderPlaintext,
long receivedStreamNumber = readUint64(streamHeaderPlaintext,
INT_16_BYTES);
if (receivedStreamNumber != streamNumber) throw new FormatException();
// Extract the frame key
byte[] frameKeyBytes = new byte[SecretKey.LENGTH];
System.arraycopy(streamHeaderPlaintext, INT_16_BYTES + INT_64_BYTES,
arraycopy(streamHeaderPlaintext, INT_16_BYTES + INT_64_BYTES,
frameKeyBytes, 0, SecretKey.LENGTH);
frameKey = new SecretKey(frameKeyBytes);
}

View File

@@ -3,7 +3,6 @@ package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.crypto.StreamEncrypter;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.ByteUtils;
import java.io.IOException;
import java.io.OutputStream;
@@ -12,6 +11,7 @@ import java.security.GeneralSecurityException;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import static java.lang.System.arraycopy;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
@@ -24,6 +24,8 @@ import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_H
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_PLAINTEXT_LENGTH;
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
import static org.briarproject.bramble.util.ByteUtils.writeUint64;
@NotThreadSafe
@NotNullByDefault
@@ -88,7 +90,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
throw new RuntimeException(badCipher);
}
// Combine the payload and padding
System.arraycopy(payload, 0, framePlaintext, 0, payloadLength);
arraycopy(payload, 0, framePlaintext, 0, payloadLength);
for (int i = 0; i < paddingLength; i++)
framePlaintext[payloadLength + i] = 0;
// Encrypt and authenticate the payload and padding
@@ -118,13 +120,12 @@ class StreamEncrypterImpl implements StreamEncrypter {
private void writeStreamHeader() throws IOException {
// The header contains the protocol version, stream number and frame key
byte[] streamHeaderPlaintext = new byte[STREAM_HEADER_PLAINTEXT_LENGTH];
ByteUtils.writeUint16(PROTOCOL_VERSION, streamHeaderPlaintext, 0);
ByteUtils.writeUint64(streamNumber, streamHeaderPlaintext,
INT_16_BYTES);
System.arraycopy(frameKey.getBytes(), 0, streamHeaderPlaintext,
writeUint16(PROTOCOL_VERSION, streamHeaderPlaintext, 0);
writeUint64(streamNumber, streamHeaderPlaintext, INT_16_BYTES);
arraycopy(frameKey.getBytes(), 0, streamHeaderPlaintext,
INT_16_BYTES + INT_64_BYTES, SecretKey.LENGTH);
byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH];
System.arraycopy(streamHeaderNonce, 0, streamHeaderCiphertext, 0,
arraycopy(streamHeaderNonce, 0, streamHeaderCiphertext, 0,
STREAM_HEADER_NONCE_LENGTH);
// Encrypt and authenticate the stream header key
try {

View File

@@ -7,13 +7,12 @@ import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.transport.IncomingKeys;
import org.briarproject.bramble.api.transport.OutgoingKeys;
import org.briarproject.bramble.api.transport.TransportKeys;
import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.bramble.util.StringUtils;
import org.spongycastle.crypto.Digest;
import org.spongycastle.crypto.digests.Blake2bDigest;
import javax.inject.Inject;
import static java.lang.System.arraycopy;
import static org.briarproject.bramble.api.transport.TransportConstants.ALICE_HEADER_LABEL;
import static org.briarproject.bramble.api.transport.TransportConstants.ALICE_TAG_LABEL;
import static org.briarproject.bramble.api.transport.TransportConstants.BOB_HEADER_LABEL;
@@ -24,6 +23,9 @@ import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
import static org.briarproject.bramble.util.ByteUtils.MAX_32_BIT_UNSIGNED;
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
import static org.briarproject.bramble.util.ByteUtils.writeUint64;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
class TransportCryptoImpl implements TransportCrypto {
@@ -91,21 +93,21 @@ class TransportCryptoImpl implements TransportCrypto {
private SecretKey rotateKey(SecretKey k, long rotationPeriod) {
byte[] period = new byte[INT_64_BYTES];
ByteUtils.writeUint64(rotationPeriod, period, 0);
writeUint64(rotationPeriod, period, 0);
return crypto.deriveKey(ROTATE_LABEL, k, period);
}
private SecretKey deriveTagKey(SecretKey master, TransportId t,
boolean alice) {
String label = alice ? ALICE_TAG_LABEL : BOB_TAG_LABEL;
byte[] id = StringUtils.toUtf8(t.getString());
byte[] id = toUtf8(t.getString());
return crypto.deriveKey(label, master, id);
}
private SecretKey deriveHeaderKey(SecretKey master, TransportId t,
boolean alice) {
String label = alice ? ALICE_HEADER_LABEL : BOB_HEADER_LABEL;
byte[] id = StringUtils.toUtf8(t.getString());
byte[] id = toUtf8(t.getString());
return crypto.deriveKey(label, master, id);
}
@@ -125,14 +127,14 @@ class TransportCryptoImpl implements TransportCrypto {
// The input is the protocol version as a 16-bit integer, followed by
// the stream number as a 64-bit integer
byte[] protocolVersionBytes = new byte[INT_16_BYTES];
ByteUtils.writeUint16(protocolVersion, protocolVersionBytes, 0);
writeUint16(protocolVersion, protocolVersionBytes, 0);
prf.update(protocolVersionBytes, 0, protocolVersionBytes.length);
byte[] streamNumberBytes = new byte[INT_64_BYTES];
ByteUtils.writeUint64(streamNumber, streamNumberBytes, 0);
writeUint64(streamNumber, streamNumberBytes, 0);
prf.update(streamNumberBytes, 0, streamNumberBytes.length);
byte[] mac = new byte[macLength];
prf.doFinal(mac, 0);
// The output is the first TAG_LENGTH bytes of the MAC
System.arraycopy(mac, 0, tag, 0, TAG_LENGTH);
arraycopy(mac, 0, tag, 0, TAG_LENGTH);
}
}

View File

@@ -242,7 +242,7 @@ interface Database<T> {
* bytes. This is based on the minimum of the space available on the device
* where the database is stored and the database's configured size.
*/
long getFreeSpace() throws DbException;
long getFreeSpace();
/**
* Returns the group with the given ID.

View File

@@ -61,7 +61,6 @@ import org.briarproject.bramble.api.transport.TransportKeys;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -72,7 +71,9 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.Collections.singletonList;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
@@ -87,7 +88,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
class DatabaseComponentImpl<T> implements DatabaseComponent {
private static final Logger LOG =
Logger.getLogger(DatabaseComponentImpl.class.getName());
getLogger(DatabaseComponentImpl.class.getName());
private final Database<T> db;
private final Class<T> txnClass;
@@ -898,7 +899,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
if (old == INVISIBLE) db.addGroupVisibility(txn, c, g, v == SHARED);
else if (v == INVISIBLE) db.removeGroupVisibility(txn, c, g);
else db.setGroupVisibility(txn, c, g, v == SHARED);
List<ContactId> affected = Collections.singletonList(c);
List<ContactId> affected = singletonList(c);
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
}

View File

@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.db.MigrationListener;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.StringUtils;
import java.io.File;
import java.sql.Connection;
@@ -23,6 +22,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
import static org.briarproject.bramble.util.StringUtils.toHexString;
/**
* Contains all the H2-specific code for the database.
@@ -107,7 +107,7 @@ class H2Database extends JdbcDatabase {
Properties props = new Properties();
props.setProperty("user", "user");
// Separate the file password from the user password with a space
String hex = StringUtils.toHexString(key.getBytes());
String hex = toHexString(key.getBytes());
props.put("password", hex + " password");
return DriverManager.getConnection(getUrl(), props);
}

View File

@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.db.MigrationListener;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.StringUtils;
import java.io.File;
import java.sql.Connection;
@@ -22,6 +21,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
import static org.briarproject.bramble.util.StringUtils.toHexString;
/**
* Contains all the HSQLDB-specific code for the database.
@@ -114,7 +114,7 @@ class HyperSqlDatabase extends JdbcDatabase {
protected Connection createConnection() throws SQLException {
SecretKey key = this.key;
if (key == null) throw new IllegalStateException();
String hex = StringUtils.toHexString(key.getBytes());
String hex = toHexString(key.getBytes());
return DriverManager.getConnection(url + ";crypt_key=" + hex);
}

View File

@@ -38,9 +38,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -54,11 +52,17 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import static java.lang.System.arraycopy;
import static java.sql.Types.INTEGER;
import static java.sql.Types.VARCHAR;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
@@ -309,19 +313,20 @@ abstract class JdbcDatabase implements Database<Connection> {
"CREATE INDEX IF NOT EXISTS statusesByContactIdTimestamp"
+ " ON statuses (contactId, timestamp)";
private static final Logger LOG =
Logger.getLogger(JdbcDatabase.class.getName());
private static final Logger LOG = getLogger(JdbcDatabase.class.getName());
// Different database libraries use different names for certain types
private final MessageFactory messageFactory;
private final Clock clock;
private final DatabaseTypes dbTypes;
// Locking: connectionsLock
@GuardedBy("connectionsLock")
private final LinkedList<Connection> connections = new LinkedList<>();
private int openConnections = 0; // Locking: connectionsLock
private boolean closed = false; // Locking: connectionsLock
@GuardedBy("connectionsLock")
private int openConnections = 0;
@GuardedBy("connectionsLock")
private boolean closed = false;
protected abstract Connection createConnection() throws SQLException;
@@ -337,6 +342,7 @@ abstract class JdbcDatabase implements Database<Connection> {
this.clock = clock;
}
@SuppressWarnings("unused")
protected void open(String driverClass, boolean reopen, SecretKey key,
@Nullable MigrationListener listener) throws DbException {
// Load the JDBC driver
@@ -424,7 +430,7 @@ abstract class JdbcDatabase implements Database<Connection> {
// Package access for testing
List<Migration<Connection>> getMigrations() {
return Arrays.asList(
return asList(
new Migration38_39(),
new Migration39_40(),
new Migration40_41(dbTypes)
@@ -766,7 +772,7 @@ abstract class JdbcDatabase implements Database<Connection> {
for (Entry<ContactId, Boolean> e : visibility.entrySet()) {
ContactId c = e.getKey();
boolean offered = removeOfferedMessage(txn, c, m.getId());
boolean seen = offered || (sender != null && c.equals(sender));
boolean seen = offered || c.equals(sender);
addStatus(txn, m.getId(), c, m.getGroupId(), m.getTimestamp(),
raw.length, state, e.getValue(), messageShared,
false, seen);
@@ -1536,7 +1542,7 @@ abstract class JdbcDatabase implements Database<Connection> {
if (raw == null) throw new MessageDeletedException();
if (raw.length <= MESSAGE_HEADER_LENGTH) throw new AssertionError();
byte[] body = new byte[raw.length - MESSAGE_HEADER_LENGTH];
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
return new Message(m, g, timestamp, body);
} catch (SQLException e) {
tryToClose(rs, LOG, WARNING);
@@ -1596,7 +1602,7 @@ abstract class JdbcDatabase implements Database<Connection> {
if (intersection == null) intersection = ids;
else intersection.retainAll(ids);
// Return early if there are no matches
if (intersection.isEmpty()) return Collections.emptySet();
if (intersection.isEmpty()) return emptySet();
}
if (intersection == null) throw new AssertionError();
return intersection;
@@ -1645,7 +1651,7 @@ abstract class JdbcDatabase implements Database<Connection> {
GroupId g, Metadata query) throws DbException {
// Retrieve the matching message IDs
Collection<MessageId> matches = getMessageIds(txn, g, query);
if (matches.isEmpty()) return Collections.emptyMap();
if (matches.isEmpty()) return emptyMap();
// Retrieve the metadata for each match
Map<MessageId, Metadata> all = new HashMap<>(matches.size());
for (MessageId m : matches) all.put(m, getMessageMetadata(txn, m));
@@ -2395,7 +2401,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
ps.close();
}
if (notRemoved.isEmpty()) return Collections.emptyMap();
if (notRemoved.isEmpty()) return emptyMap();
// Update any keys that already exist
String sql = "UPDATE " + tableName + " SET value = ?"
+ " WHERE " + columnName + " = ? AND metaKey = ?";

View File

@@ -8,12 +8,12 @@ import java.sql.Statement;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
class Migration38_39 implements Migration<Connection> {
private static final Logger LOG =
Logger.getLogger(Migration38_39.class.getName());
private static final Logger LOG = getLogger(Migration38_39.class.getName());
@Override
public int getStartVersion() {

View File

@@ -8,12 +8,12 @@ import java.sql.Statement;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
class Migration39_40 implements Migration<Connection> {
private static final Logger LOG =
Logger.getLogger(Migration39_40.class.getName());
private static final Logger LOG = getLogger(Migration39_40.class.getName());
@Override
public int getStartVersion() {

View File

@@ -17,7 +17,7 @@ class Migration40_41 implements Migration<Connection> {
private final DatabaseTypes dbTypes;
public Migration40_41(DatabaseTypes databaseTypes) {
Migration40_41(DatabaseTypes databaseTypes) {
this.dbTypes = databaseTypes;
}

View File

@@ -7,8 +7,6 @@ import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
@@ -16,6 +14,8 @@ import javax.inject.Inject;
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
import static org.briarproject.bramble.api.identity.AuthorId.LABEL;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@Immutable
@NotNullByDefault
@@ -58,8 +58,8 @@ class AuthorFactoryImpl implements AuthorFactory {
private AuthorId getId(int formatVersion, String name, byte[] publicKey) {
byte[] formatVersionBytes = new byte[INT_32_BYTES];
ByteUtils.writeUint32(formatVersion, formatVersionBytes, 0);
writeUint32(formatVersion, formatVersionBytes, 0);
return new AuthorId(crypto.hash(LABEL, formatVersionBytes,
StringUtils.toUtf8(name), publicKey));
toUtf8(name), publicKey));
}
}

View File

@@ -16,6 +16,7 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
@@ -24,7 +25,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
class IdentityManagerImpl implements IdentityManager {
private static final Logger LOG =
Logger.getLogger(IdentityManagerImpl.class.getName());
getLogger(IdentityManagerImpl.class.getName());
private final DatabaseComponent db;
private final CryptoComponent crypto;

View File

@@ -2,7 +2,7 @@ package org.briarproject.bramble.keyagreement;
class AbortException extends Exception {
boolean receivedAbort;
final boolean receivedAbort;
AbortException() {
this(false);

View File

@@ -20,13 +20,14 @@ import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@NotNullByDefault
@ThreadSafe
class ConnectionChooserImpl implements ConnectionChooser {
private static final Logger LOG =
Logger.getLogger(ConnectionChooserImpl.class.getName());
getLogger(ConnectionChooserImpl.class.getName());
private final Clock clock;
private final Executor ioExecutor;

View File

@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.CONNECTION_TIMEOUT;
import static org.briarproject.bramble.util.LogUtils.logException;
@@ -41,7 +42,7 @@ class KeyAgreementConnector {
}
private static final Logger LOG =
Logger.getLogger(KeyAgreementConnector.class.getName());
getLogger(KeyAgreementConnector.class.getName());
private final Callbacks callbacks;
private final KeyAgreementCrypto keyAgreementCrypto;

View File

@@ -28,6 +28,7 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@@ -36,7 +37,7 @@ class KeyAgreementTaskImpl extends Thread implements KeyAgreementTask,
KeyAgreementProtocol.Callbacks, KeyAgreementConnector.Callbacks {
private static final Logger LOG =
Logger.getLogger(KeyAgreementTaskImpl.class.getName());
getLogger(KeyAgreementTaskImpl.class.getName());
private final CryptoComponent crypto;
private final KeyAgreementCrypto keyAgreementCrypto;

View File

@@ -16,6 +16,7 @@ import java.io.OutputStream;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.RecordTypes.ABORT;
import static org.briarproject.bramble.api.keyagreement.RecordTypes.CONFIRM;
@@ -29,7 +30,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
class KeyAgreementTransport {
private static final Logger LOG =
Logger.getLogger(KeyAgreementTransport.class.getName());
getLogger(KeyAgreementTransport.class.getName());
private final KeyAgreementConnection kac;
private final RecordReader reader;

View File

@@ -28,6 +28,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.COMPACTING_DATABASE;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
@@ -49,7 +50,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
private static final Logger LOG =
Logger.getLogger(LifecycleManagerImpl.class.getName());
getLogger(LifecycleManagerImpl.class.getName());
private final DatabaseComponent db;
private final EventBus eventBus;

View File

@@ -26,13 +26,14 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.util.LogUtils.logException;
class ConnectionManagerImpl implements ConnectionManager {
private static final Logger LOG =
Logger.getLogger(ConnectionManagerImpl.class.getName());
getLogger(ConnectionManagerImpl.class.getName());
private final Executor ioExecutor;
private final KeyManager keyManager;

View File

@@ -13,7 +13,6 @@ import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -24,14 +23,16 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.Collections.emptyList;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
@ThreadSafe
@NotNullByDefault
class ConnectionRegistryImpl implements ConnectionRegistry {
private static final Logger LOG =
Logger.getLogger(ConnectionRegistryImpl.class.getName());
getLogger(ConnectionRegistryImpl.class.getName());
private final EventBus eventBus;
private final Lock lock = new ReentrantLock();
@@ -103,7 +104,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
lock.lock();
try {
Multiset<ContactId> m = connections.get(t);
if (m == null) return Collections.emptyList();
if (m == null) return emptyList();
List<ContactId> ids = new ArrayList<>(m.keySet());
if (LOG.isLoggable(INFO))
LOG.info(ids.size() + " contacts connected: " + t);

View File

@@ -52,6 +52,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@@ -61,7 +62,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
class PluginManagerImpl implements PluginManager, Service {
private static final Logger LOG =
Logger.getLogger(PluginManagerImpl.class.getName());
getLogger(PluginManagerImpl.class.getName());
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;

View File

@@ -36,18 +36,20 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe
@NotNullByDefault
class Poller implements EventListener {
private static final Logger LOG = Logger.getLogger(Poller.class.getName());
private static final Logger LOG = getLogger(Poller.class.getName());
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
@@ -58,7 +60,8 @@ class Poller implements EventListener {
private final SecureRandom random;
private final Clock clock;
private final Lock lock;
private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock
@GuardedBy("lock")
private final Map<TransportId, ScheduledPollTask> tasks;
Poller(@IoExecutor Executor ioExecutor,
@Scheduler ScheduledExecutorService scheduler,

View File

@@ -20,6 +20,7 @@ interface BluetoothConnectionLimiter {
* Returns true if a contact connection can be opened. This method does not
* need to be called for key agreement connections.
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
boolean canOpenContactConnection();
/**

View File

@@ -13,6 +13,7 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
@@ -20,7 +21,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
private static final Logger LOG =
Logger.getLogger(BluetoothConnectionLimiterImpl.class.getName());
getLogger(BluetoothConnectionLimiterImpl.class.getName());
private final Object lock = new Object();
// The following are locking: lock

View File

@@ -37,6 +37,7 @@ import javax.annotation.Nullable;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE;
@@ -54,7 +55,7 @@ import static org.briarproject.bramble.util.StringUtils.macToString;
abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
private static final Logger LOG =
Logger.getLogger(BluetoothPlugin.class.getName());
getLogger(BluetoothPlugin.class.getName());
final BluetoothConnectionLimiter connectionLimiter;

View File

@@ -14,6 +14,7 @@ import java.io.IOException;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@@ -21,8 +22,7 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@NotNullByDefault
abstract class FilePlugin implements SimplexPlugin {
private static final Logger LOG =
Logger.getLogger(FilePlugin.class.getName());
private static final Logger LOG = getLogger(FilePlugin.class.getName());
protected final SimplexPluginCallback callback;
protected final int maxLatency;

View File

@@ -8,13 +8,14 @@ import java.io.InputStream;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.IoUtils.tryToClose;
@NotNullByDefault
class FileTransportReader implements TransportConnectionReader {
private static final Logger LOG =
Logger.getLogger(FileTransportReader.class.getName());
getLogger(FileTransportReader.class.getName());
private final File file;
private final InputStream in;

View File

@@ -8,13 +8,14 @@ import java.io.OutputStream;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.IoUtils.tryToClose;
@NotNullByDefault
class FileTransportWriter implements TransportConnectionWriter {
private static final Logger LOG =
Logger.getLogger(FileTransportWriter.class.getName());
getLogger(FileTransportWriter.class.getName());
private final File file;
private final OutputStream out;

View File

@@ -12,7 +12,6 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.StringUtils;
import java.io.IOException;
import java.net.Inet4Address;
@@ -23,26 +22,30 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import static java.util.Collections.addAll;
import static java.util.Collections.emptyList;
import static java.util.Collections.sort;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS;
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
import static org.briarproject.bramble.util.StringUtils.join;
@NotNullByDefault
class LanTcpPlugin extends TcpPlugin {
private static final Logger LOG =
Logger.getLogger(LanTcpPlugin.class.getName());
private static final Logger LOG = getLogger(LanTcpPlugin.class.getName());
private static final LanAddressComparator ADDRESS_COMPARATOR =
new LanAddressComparator();
@@ -77,12 +80,13 @@ class LanTcpPlugin extends TcpPlugin {
locals.add(new InetSocketAddress(local, 0));
}
}
Collections.sort(locals, ADDRESS_COMPARATOR);
//noinspection Java8ListSort
sort(locals, ADDRESS_COMPARATOR);
return locals;
}
private List<InetSocketAddress> parseSocketAddresses(String ipPorts) {
if (StringUtils.isNullOrEmpty(ipPorts)) return Collections.emptyList();
if (isNullOrEmpty(ipPorts)) return emptyList();
String[] split = ipPorts.split(SEPARATOR);
List<InetSocketAddress> addresses = new ArrayList<>();
for (String ipPort : split) {
@@ -98,24 +102,23 @@ class LanTcpPlugin extends TcpPlugin {
// Get the list of recently used addresses
String setting = callback.getSettings().get(PREF_LAN_IP_PORTS);
List<String> recent = new ArrayList<>();
if (!StringUtils.isNullOrEmpty(setting))
Collections.addAll(recent, setting.split(SEPARATOR));
if (!isNullOrEmpty(setting)) addAll(recent, setting.split(SEPARATOR));
// Is the address already in the list?
if (recent.remove(ipPort)) {
// Move the address to the start of the list
recent.add(0, ipPort);
setting = StringUtils.join(recent, SEPARATOR);
setting = join(recent, SEPARATOR);
} else {
// Add the address to the start of the list
recent.add(0, ipPort);
// Drop the least recently used address if the list is full
if (recent.size() > MAX_ADDRESSES)
recent = recent.subList(0, MAX_ADDRESSES);
setting = StringUtils.join(recent, SEPARATOR);
setting = join(recent, SEPARATOR);
// Update the list of addresses shared with contacts
List<String> shared = new ArrayList<>(recent);
Collections.sort(shared);
String property = StringUtils.join(shared, SEPARATOR);
sort(shared);
String property = join(shared, SEPARATOR);
TransportProperties properties = new TransportProperties();
properties.put(PROP_IP_PORTS, property);
callback.mergeLocalProperties(properties);

View File

@@ -17,6 +17,7 @@ import javax.xml.parsers.ParserConfigurationException;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
@@ -25,8 +26,7 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
@ParametersNotNullByDefault
class PortMapperImpl implements PortMapper {
private static final Logger LOG =
Logger.getLogger(PortMapperImpl.class.getName());
private static final Logger LOG = getLogger(PortMapperImpl.class.getName());
private final ShutdownManager shutdownManager;
private final AtomicBoolean started = new AtomicBoolean(false);

View File

@@ -12,7 +12,6 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.StringUtils;
import java.io.IOException;
import java.net.InetAddress;
@@ -41,17 +40,19 @@ import static java.util.Collections.emptyList;
import static java.util.Collections.list;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
abstract class TcpPlugin implements DuplexPlugin {
private static final Logger LOG = getLogger(TcpPlugin.class.getName());
private static final Pattern DOTTED_QUAD =
Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$");
private static final Logger LOG =
Logger.getLogger(TcpPlugin.class.getName());
protected final Executor ioExecutor, bindExecutor;
protected final Backoff backoff;
@@ -84,6 +85,7 @@ abstract class TcpPlugin implements DuplexPlugin {
/**
* Returns true if connections to the given address can be attempted.
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
protected abstract boolean isConnectable(InetSocketAddress remote);
TcpPlugin(Executor ioExecutor, Backoff backoff,
@@ -263,7 +265,7 @@ abstract class TcpPlugin implements DuplexPlugin {
@Nullable
InetSocketAddress parseSocketAddress(String ipPort) {
if (StringUtils.isNullOrEmpty(ipPort)) return null;
if (isNullOrEmpty(ipPort)) return null;
String[] split = ipPort.split(":");
if (split.length != 2) return null;
String addr = split[0], port = split[1];

View File

@@ -10,11 +10,12 @@ import org.briarproject.bramble.api.properties.TransportProperties;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID;
@MethodsNotNullByDefault
@@ -80,8 +81,7 @@ class WanTcpPlugin extends TcpPlugin {
protected List<InetSocketAddress> getRemoteSocketAddresses(
TransportProperties p) {
InetSocketAddress parsed = parseSocketAddress(p.get(PROP_IP_PORT));
if (parsed == null) return Collections.emptyList();
return Collections.singletonList(parsed);
return parsed == null ? emptyList() : singletonList(parsed);
}
@Override

View File

@@ -42,9 +42,7 @@ import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -58,8 +56,12 @@ import java.util.zip.ZipInputStream;
import javax.annotation.Nullable;
import javax.net.SocketFactory;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
@@ -69,9 +71,11 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ONLY_WHEN_CHARGING;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V2;
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3;
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@@ -80,8 +84,7 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@ParametersNotNullByDefault
abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private static final Logger LOG =
Logger.getLogger(TorPlugin.class.getName());
private static final Logger LOG = getLogger(TorPlugin.class.getName());
private static final String[] EVENTS = {
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
@@ -250,11 +253,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
controlConnection.authenticate(read(cookieFile));
// Tell Tor to exit when the control connection is closed
controlConnection.takeOwnership();
controlConnection.resetConf(Collections.singletonList(OWNER));
controlConnection.resetConf(singletonList(OWNER));
running = true;
// Register to receive events from the Tor process
controlConnection.setEventHandler(this);
controlConnection.setEvents(Arrays.asList(EVENTS));
controlConnection.setEvents(asList(EVENTS));
// Check whether Tor has already bootstrapped
String phase = controlConnection.getInfo("status/bootstrap-phase");
if (phase != null && phase.contains("PROGRESS=100")) {
@@ -279,28 +282,31 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
InputStream in = null;
OutputStream out = null;
try {
// The done file may already exist from a previous installation
//noinspection ResultOfMethodCallIgnored
doneFile.delete();
// Unzip the Tor binary to the filesystem
in = getTorInputStream();
out = new FileOutputStream(torFile);
IoUtils.copyAndClose(in, out);
copyAndClose(in, out);
// Make the Tor binary executable
if (!torFile.setExecutable(true, true)) throw new IOException();
// Unzip the GeoIP database to the filesystem
in = getGeoIpInputStream();
out = new FileOutputStream(geoIpFile);
IoUtils.copyAndClose(in, out);
copyAndClose(in, out);
// Unzip the Obfs4 proxy to the filesystem
in = getObfs4InputStream();
out = new FileOutputStream(obfs4File);
IoUtils.copyAndClose(in, out);
copyAndClose(in, out);
// Make the Obfs4 proxy executable
if (!obfs4File.setExecutable(true, true)) throw new IOException();
// Copy the config file to the filesystem
in = getConfigInputStream();
out = new FileOutputStream(configFile);
IoUtils.copyAndClose(in, out);
doneFile.createNewFile();
copyAndClose(in, out);
if (!doneFile.createNewFile())
LOG.warning("Failed to create done file");
} catch (IOException e) {
IoUtils.tryToClose(in, LOG, WARNING);
IoUtils.tryToClose(out, LOG, WARNING);
@@ -409,8 +415,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (!running) return;
LOG.info("Creating hidden service");
String privKey = settings.get(HS_PRIVKEY);
Map<Integer, String> portLines =
Collections.singletonMap(80, "127.0.0.1:" + port);
Map<Integer, String> portLines = singletonMap(80, "127.0.0.1:" + port);
Map<String, String> response;
try {
// Use the control connection to set up the hidden service
@@ -648,8 +653,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (s.getNamespace().equals(ID.getString())) {
LOG.info("Tor settings updated");
settings = s.getSettings();
// Works around a bug introduced in Tor 0.3.4.8. Could be
// replaced with callback.transportDisabled() when fixed.
// Works around a bug introduced in Tor 0.3.4.8.
// https://trac.torproject.org/projects/tor/ticket/28027
// Could be replaced with callback.transportDisabled()
// when fixed.
disableNetwork();
updateConnectionStatus(networkManager.getNetworkStatus(),
batteryManager.isCharging());
@@ -685,6 +692,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
int network = settings.getInt(PREF_TOR_NETWORK,
PREF_TOR_NETWORK_AUTOMATIC);
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
boolean onlyWhenCharging =
settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false);
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
@@ -699,9 +708,12 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (!online) {
LOG.info("Disabling network, device is offline");
enableNetwork(false);
} else if (!charging && onlyWhenCharging) {
LOG.info("Disabling network, device is on battery");
enableNetwork(false);
} else if (network == PREF_TOR_NETWORK_NEVER ||
(!useMobile && !wifi)) {
LOG.info("Disabling network due to setting");
LOG.info("Disabling network, device is using mobile data");
enableNetwork(false);
} else if (automatic && blocked && !bridgesWork) {
LOG.info("Disabling network, country is blocked");

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.record.Record;
import org.briarproject.bramble.api.record.RecordReader;
import org.briarproject.bramble.util.ByteUtils;
import java.io.DataInputStream;
import java.io.IOException;
@@ -14,6 +13,7 @@ import javax.annotation.concurrent.NotThreadSafe;
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
import static org.briarproject.bramble.api.record.Record.RECORD_HEADER_BYTES;
import static org.briarproject.bramble.util.ByteUtils.readUint16;
@NotThreadSafe
@NotNullByDefault
@@ -31,7 +31,7 @@ class RecordReaderImpl implements RecordReader {
in.readFully(header);
byte protocolVersion = header[0];
byte recordType = header[1];
int payloadLength = ByteUtils.readUint16(header, 2);
int payloadLength = readUint16(header, 2);
if (payloadLength < 0 || payloadLength > MAX_RECORD_PAYLOAD_BYTES)
throw new FormatException();
byte[] payload = new byte[payloadLength];

View File

@@ -3,7 +3,6 @@ package org.briarproject.bramble.record;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.record.Record;
import org.briarproject.bramble.api.record.RecordWriter;
import org.briarproject.bramble.util.ByteUtils;
import java.io.IOException;
import java.io.OutputStream;
@@ -11,6 +10,7 @@ import java.io.OutputStream;
import javax.annotation.concurrent.NotThreadSafe;
import static org.briarproject.bramble.api.record.Record.RECORD_HEADER_BYTES;
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
@NotThreadSafe
@NotNullByDefault
@@ -28,7 +28,7 @@ class RecordWriterImpl implements RecordWriter {
byte[] payload = r.getPayload();
header[0] = r.getProtocolVersion();
header[1] = r.getRecordType();
ByteUtils.writeUint16(payload.length, header, 2);
writeUint16(payload.length, header, 2);
out.write(header);
out.write(payload);
}

View File

@@ -1,10 +1,12 @@
package org.briarproject.bramble.reliability;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.ByteUtils;
import javax.annotation.concurrent.NotThreadSafe;
import static org.briarproject.bramble.util.ByteUtils.readUint16;
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
@NotThreadSafe
@NotNullByDefault
class Ack extends Frame {
@@ -23,10 +25,10 @@ class Ack extends Frame {
}
int getWindowSize() {
return ByteUtils.readUint16(buf, 5);
return readUint16(buf, 5);
}
void setWindowSize(int windowSize) {
ByteUtils.writeUint16(windowSize, buf, 5);
writeUint16(windowSize, buf, 5);
}
}

View File

@@ -1,17 +1,19 @@
package org.briarproject.bramble.reliability;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.ByteUtils;
import javax.annotation.concurrent.NotThreadSafe;
import static org.briarproject.bramble.util.ByteUtils.readUint32;
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
@NotThreadSafe
@NotNullByDefault
abstract class Frame {
static final byte ACK_FLAG = (byte) 128, FIN_FLAG = 64;
protected final byte[] buf;
final byte[] buf;
Frame(byte[] buf) {
this.buf = buf;
@@ -26,11 +28,11 @@ abstract class Frame {
}
long getChecksum() {
return ByteUtils.readUint32(buf, buf.length - 4);
return readUint32(buf, buf.length - 4);
}
void setChecksum(long checksum) {
ByteUtils.writeUint32(checksum, buf, buf.length - 4);
writeUint32(checksum, buf, buf.length - 4);
}
long calculateChecksum() {
@@ -38,11 +40,11 @@ abstract class Frame {
}
long getSequenceNumber() {
return ByteUtils.readUint32(buf, 1);
return readUint32(buf, 1);
}
void setSequenceNumber(long sequenceNumber) {
ByteUtils.writeUint32(sequenceNumber, buf, 1);
writeUint32(sequenceNumber, buf, 1);
}
@Override

View File

@@ -101,6 +101,7 @@ class Receiver implements ReadHandler {
}
}
@SuppressWarnings("StatementWithEmptyBody")
private void handleData(byte[] b) throws IOException {
windowLock.lock();
try {
@@ -124,6 +125,7 @@ class Receiver implements ReadHandler {
finalSequenceNumber = sequenceNumber;
// Remove any data frames with higher sequence numbers
Iterator<Data> it = dataFrames.iterator();
//noinspection Java8CollectionRemoveIf
while (it.hasNext()) {
Data d1 = it.next();
if (d1.getSequenceNumber() >= finalSequenceNumber)
@@ -148,6 +150,7 @@ class Receiver implements ReadHandler {
private static class SequenceNumberComparator implements Comparator<Data> {
@SuppressWarnings("UseCompareMethod")
@Override
public int compare(Data d1, Data d2) {
long s1 = d1.getSequenceNumber(), s2 = d2.getSequenceNumber();

View File

@@ -8,6 +8,8 @@ import java.io.InputStream;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import static java.lang.System.arraycopy;
@NotThreadSafe
@NotNullByDefault
class ReceiverInputStream extends InputStream {
@@ -44,12 +46,13 @@ class ReceiverInputStream extends InputStream {
while (length == 0) if (!receive()) return -1;
if (data == null) throw new AssertionError();
len = Math.min(len, length);
System.arraycopy(data.getBuffer(), offset, b, off, len);
arraycopy(data.getBuffer(), offset, b, off, len);
offset += len;
length -= len;
return len;
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean receive() throws IOException {
if (length != 0) throw new AssertionError();
if (data != null && data.isLastFrame()) {

View File

@@ -16,6 +16,7 @@ import java.util.logging.Logger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@@ -25,7 +26,7 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
private static final int TICK_INTERVAL = 500; // Milliseconds
private static final Logger LOG =
Logger.getLogger(ReliabilityLayerImpl.class.getName());
getLogger(ReliabilityLayerImpl.class.getName());
private final Executor executor;
private final Clock clock;

View File

@@ -16,6 +16,7 @@ import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
@ThreadSafe
@NotNullByDefault
@@ -96,7 +97,7 @@ class Sender {
}
// If any older data frames are outstanding, retransmit the oldest
if (foundIndex > 0) {
fastRetransmit = outstanding.poll();
fastRetransmit = requireNonNull(outstanding.poll());
fastRetransmit.lastTransmitted = now;
fastRetransmit.retransmitted = true;
outstanding.add(fastRetransmit);
@@ -191,7 +192,7 @@ class Sender {
writeHandler.handleWrite(d.getBuffer());
}
void flush() throws IOException, InterruptedException {
void flush() throws InterruptedException {
windowLock.lock();
try {
while (dataWaiting || !outstanding.isEmpty())

View File

@@ -7,6 +7,8 @@ import java.io.OutputStream;
import javax.annotation.concurrent.NotThreadSafe;
import static java.lang.System.arraycopy;
@NotThreadSafe
@NotNullByDefault
class SenderOutputStream extends OutputStream {
@@ -59,20 +61,20 @@ class SenderOutputStream extends OutputStream {
public void write(byte[] b, int off, int len) throws IOException {
int available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
while (available <= len) {
System.arraycopy(b, off, buf, offset, available);
arraycopy(b, off, buf, offset, available);
offset += available;
send(false);
off += available;
len -= available;
available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
}
System.arraycopy(b, off, buf, offset, len);
arraycopy(b, off, buf, offset, len);
offset += len;
}
private void send(boolean lastFrame) throws IOException {
byte[] frame = new byte[offset + Data.FOOTER_LENGTH];
System.arraycopy(buf, 0, frame, 0, frame.length);
arraycopy(buf, 0, frame, 0, frame.length);
Data d = new Data(frame);
d.setLastFrame(lastFrame);
d.setSequenceNumber(sequenceNumber++);

View File

@@ -7,6 +7,8 @@ import java.io.IOException;
import javax.annotation.concurrent.Immutable;
import static java.lang.System.arraycopy;
@Immutable
@NotNullByDefault
class SlipDecoder implements ReadHandler {
@@ -36,7 +38,7 @@ class SlipDecoder implements ReadHandler {
} else {
if (decodedLength > 0) {
byte[] decoded = new byte[decodedLength];
System.arraycopy(buf, 0, decoded, 0, decodedLength);
arraycopy(buf, 0, decoded, 0, decodedLength);
readHandler.handleRead(decoded);
}
reset(false);

View File

@@ -1,7 +1,6 @@
package org.briarproject.bramble.reporting;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.IoUtils;
import java.io.Closeable;
import java.io.File;
@@ -17,6 +16,9 @@ import java.util.concurrent.Semaphore;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static java.io.File.createTempFile;
import static org.briarproject.bramble.util.IoUtils.getInputStream;
@Immutable
@NotNullByDefault
public class DevReportServer {
@@ -42,6 +44,7 @@ public class DevReportServer {
TokenBucket bucket = new TokenBucket();
bucket.start();
try {
//noinspection InfiniteLoopStatement
while (true) {
Socket s = ss.accept();
System.out.println("Incoming connection");
@@ -101,6 +104,7 @@ public class DevReportServer {
@Override
public void run() {
try {
//noinspection InfiniteLoopStatement
while (true) {
// If the bucket isn't full, add a token
if (semaphore.availablePermits() < MAX_TOKENS) {
@@ -131,9 +135,11 @@ public class DevReportServer {
OutputStream out = null;
try {
socket.setSoTimeout(SOCKET_TIMEOUT_MS);
in = IoUtils.getInputStream(socket);
in = getInputStream(socket);
// Directory may already exist
//noinspection ResultOfMethodCallIgnored
reportDir.mkdirs();
reportFile = File.createTempFile(FILE_PREFIX, FILE_SUFFIX,
reportFile = createTempFile(FILE_PREFIX, FILE_SUFFIX,
reportDir);
out = new FileOutputStream(reportFile);
System.out.println("Saving report to " + reportFile);
@@ -151,7 +157,8 @@ public class DevReportServer {
System.out.println("Saved " + length + " bytes");
} catch (IOException e) {
e.printStackTrace();
if (reportFile != null) reportFile.delete();
if (reportFile != null && !reportFile.delete())
System.err.println("Failed to delete report");
} finally {
tryToClose(in);
tryToClose(out);

View File

@@ -9,8 +9,6 @@ import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent;
import org.briarproject.bramble.api.reporting.DevConfig;
import org.briarproject.bramble.api.reporting.DevReporter;
import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.StringUtils;
import java.io.File;
import java.io.FileInputStream;
@@ -30,14 +28,18 @@ import javax.inject.Inject;
import javax.net.SocketFactory;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
import static org.briarproject.bramble.util.IoUtils.getOutputStream;
import static org.briarproject.bramble.util.IoUtils.tryToClose;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@Immutable
@NotNullByDefault
class DevReporterImpl implements DevReporter, EventListener {
private static final Logger LOG =
Logger.getLogger(DevReporterImpl.class.getName());
getLogger(DevReporterImpl.class.getName());
private static final int SOCKET_TIMEOUT = 30 * 1000; // 30 seconds
private static final int LINE_LENGTH = 70;
@@ -73,7 +75,7 @@ class DevReporterImpl implements DevReporter, EventListener {
public void encryptReportToFile(File reportDir, String filename,
String report) throws FileNotFoundException {
LOG.info("Encrypting report to file");
byte[] plaintext = StringUtils.toUtf8(report);
byte[] plaintext = toUtf8(report);
byte[] ciphertext = crypto.encryptToKey(devConfig.getDevPublicKey(),
plaintext);
String armoured = crypto.asciiArmour(ciphertext, LINE_LENGTH);
@@ -109,17 +111,15 @@ class DevReporterImpl implements DevReporter, EventListener {
LOG.info("Sending reports to developers");
for (File f : reports) {
OutputStream out = null;
InputStream in = null;
try {
Socket s = connectToDevelopers();
out = IoUtils.getOutputStream(s);
in = new FileInputStream(f);
IoUtils.copyAndClose(in, out);
f.delete();
out = getOutputStream(s);
InputStream in = new FileInputStream(f);
copyAndClose(in, out);
if (!f.delete()) LOG.warning("Failed to delete report");
} catch (IOException e) {
LOG.log(WARNING, "Failed to send reports", e);
tryToClose(out, LOG, WARNING);
tryToClose(in, LOG, WARNING);
return;
}
}

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.socks;
import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.bramble.util.IoUtils;
import java.io.IOException;
@@ -12,6 +11,9 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.util.Arrays;
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
import static org.briarproject.bramble.util.IoUtils.read;
class SocksSocket extends Socket {
private static final String[] ERRORS = {
@@ -26,6 +28,7 @@ class SocksSocket extends Socket {
"Address type not supported"
};
@SuppressWarnings("MismatchedReadAndWriteOfArray")
private static final byte[] UNSPECIFIED_ADDRESS = new byte[4];
private final SocketAddress proxy;
@@ -88,7 +91,7 @@ class SocksSocket extends Socket {
private void receiveMethodResponse(InputStream in) throws IOException {
byte[] methodResponse = new byte[2];
IoUtils.read(in, methodResponse);
read(in, methodResponse);
byte version = methodResponse[0];
byte method = methodResponse[1];
if (version != 5)
@@ -108,14 +111,14 @@ class SocksSocket extends Socket {
connectRequest[4] = (byte) host.length(); // Length of domain name
for (int i = 0; i < host.length(); i++)
connectRequest[5 + i] = (byte) host.charAt(i);
ByteUtils.writeUint16(port, connectRequest, connectRequest.length - 2);
writeUint16(port, connectRequest, connectRequest.length - 2);
out.write(connectRequest);
out.flush();
}
private void receiveConnectResponse(InputStream in) throws IOException {
byte[] connectResponse = new byte[4];
IoUtils.read(in, connectResponse);
read(in, connectResponse);
int version = connectResponse[0] & 0xFF;
int reply = connectResponse[1] & 0xFF;
int addressType = connectResponse[3] & 0xFF;
@@ -126,9 +129,9 @@ class SocksSocket extends Socket {
throw new IOException("Connection failed: " + ERRORS[reply]);
else throw new IOException("Connection failed: " + reply);
}
if (addressType == 1) IoUtils.read(in, new byte[4]); // IPv4
else if (addressType == 4) IoUtils.read(in, new byte[16]); // IPv6
if (addressType == 1) read(in, new byte[4]); // IPv4
else if (addressType == 4) read(in, new byte[16]); // IPv6
else throw new IOException("Unsupported address type: " + addressType);
IoUtils.read(in, new byte[2]); // Port number
read(in, new byte[2]); // Port number
}
}

View File

@@ -45,7 +45,7 @@ class SocksSocketFactory extends SocketFactory {
@Override
public Socket createSocket(InetAddress address, int port,
InetAddress localAddress, int localPort) throws IOException {
InetAddress localAddress, int localPort) {
throw new UnsupportedOperationException();
}
}

View File

@@ -39,6 +39,7 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
@@ -55,7 +56,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
class DuplexOutgoingSession implements SyncSession, EventListener {
private static final Logger LOG =
Logger.getLogger(DuplexOutgoingSession.class.getName());
getLogger(DuplexOutgoingSession.class.getName());
private static final ThrowingRunnable<IOException> CLOSE = () -> {
};

View File

@@ -6,8 +6,6 @@ import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupFactory;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.util.ByteUtils;
import org.briarproject.bramble.util.StringUtils;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
@@ -15,6 +13,8 @@ import javax.inject.Inject;
import static org.briarproject.bramble.api.sync.Group.FORMAT_VERSION;
import static org.briarproject.bramble.api.sync.GroupId.LABEL;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@Immutable
@NotNullByDefault
@@ -33,10 +33,9 @@ class GroupFactoryImpl implements GroupFactory {
@Override
public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) {
byte[] majorVersionBytes = new byte[INT_32_BYTES];
ByteUtils.writeUint32(majorVersion, majorVersionBytes, 0);
writeUint32(majorVersion, majorVersionBytes, 0);
byte[] hash = crypto.hash(LABEL, FORMAT_VERSION_BYTES,
StringUtils.toUtf8(c.getString()), majorVersionBytes,
descriptor);
toUtf8(c.getString()), majorVersionBytes, descriptor);
return new Group(new GroupId(hash), c, majorVersion, descriptor);
}
}

View File

@@ -26,6 +26,7 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.ThreadSafe;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.util.LogUtils.logException;
@@ -37,7 +38,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
class IncomingSession implements SyncSession, EventListener {
private static final Logger LOG =
Logger.getLogger(IncomingSession.class.getName());
getLogger(IncomingSession.class.getName());
private final DatabaseComponent db;
private final Executor dbExecutor;

View File

@@ -7,11 +7,11 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageFactory;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.util.ByteUtils;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static java.lang.System.arraycopy;
import static org.briarproject.bramble.api.sync.Message.FORMAT_VERSION;
import static org.briarproject.bramble.api.sync.MessageId.BLOCK_LABEL;
import static org.briarproject.bramble.api.sync.MessageId.ID_LABEL;
@@ -19,6 +19,8 @@ import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_L
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
import static org.briarproject.bramble.util.ByteUtils.readUint64;
import static org.briarproject.bramble.util.ByteUtils.writeUint64;
@Immutable
@NotNullByDefault
@@ -47,7 +49,7 @@ class MessageFactoryImpl implements MessageFactory {
// There's only one block, so the root hash is the hash of the block
byte[] rootHash = crypto.hash(BLOCK_LABEL, FORMAT_VERSION_BYTES, body);
byte[] timeBytes = new byte[INT_64_BYTES];
ByteUtils.writeUint64(timestamp, timeBytes, 0);
writeUint64(timestamp, timeBytes, 0);
byte[] idHash = crypto.hash(ID_LABEL, FORMAT_VERSION_BYTES,
g.getBytes(), timeBytes, rootHash);
return new MessageId(idHash);
@@ -60,11 +62,11 @@ class MessageFactoryImpl implements MessageFactory {
if (raw.length > MAX_MESSAGE_LENGTH)
throw new IllegalArgumentException();
byte[] groupId = new byte[UniqueId.LENGTH];
System.arraycopy(raw, 0, groupId, 0, UniqueId.LENGTH);
arraycopy(raw, 0, groupId, 0, UniqueId.LENGTH);
GroupId g = new GroupId(groupId);
long timestamp = ByteUtils.readUint64(raw, UniqueId.LENGTH);
long timestamp = readUint64(raw, UniqueId.LENGTH);
byte[] body = new byte[raw.length - MESSAGE_HEADER_LENGTH];
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
MessageId id = getMessageId(g, timestamp, body);
return new Message(id, g, timestamp, body);
}
@@ -73,9 +75,9 @@ class MessageFactoryImpl implements MessageFactory {
public byte[] getRawMessage(Message m) {
byte[] body = m.getBody();
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
System.arraycopy(m.getGroupId().getBytes(), 0, raw, 0, UniqueId.LENGTH);
ByteUtils.writeUint64(m.getTimestamp(), raw, UniqueId.LENGTH);
System.arraycopy(body, 0, raw, MESSAGE_HEADER_LENGTH, body.length);
arraycopy(m.getGroupId().getBytes(), 0, raw, 0, UniqueId.LENGTH);
writeUint64(m.getTimestamp(), raw, UniqueId.LENGTH);
arraycopy(body, 0, raw, MESSAGE_HEADER_LENGTH, body.length);
return raw;
}
}

Some files were not shown because too many files have changed in this diff Show More