Compare commits

...

15 Commits

Author SHA1 Message Date
Jason A. Donenfeld 3de549d2c7 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-25 16:18:57 +02:00
Jason A. Donenfeld 408e9004b0 libwg-quick: add iptables output allowance
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-25 16:16:27 +02:00
Jason A. Donenfeld e1a66d5766 global: Small cleanups
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-25 16:10:02 +02:00
Harsh Shandilya 99cf2152c4 android: Consolidate getPrefActivity into FragmentUtils
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
[Samuel: Changed static to non-static import]
Signed-off-by: Samuel Holland <samuel@sholland.org>
2018-06-23 01:00:07 -05:00
Harsh Shandilya 53e8d425e9 QuickTileService: Remove useless override
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-06-23 00:57:31 -05:00
Harsh Shandilya 9e5f45da15 gradle: Style
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-06-23 00:57:31 -05:00
Harsh Shandilya 4c0caa10e9 treewide: Optimize imports
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-06-23 00:57:31 -05:00
Samuel Holland b9991e4229 config: Refactor IPCidr and use of InetAddress
Use a canonically-named utility class to tack on methods to the existing
InetAddress class. Rename IPCidr to InetNetwork so it better matches
InetAddress and is more pronouceable :) While here, simplify the
constructor and toString() functions, and properly implement hashCode().

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-19 21:59:44 -05:00
Samuel Holland 4acee49d4b util: Extract non-Android utility interfaces
As part of a refactoring that will likely introduce more custom
collection classes, move the non-Android-specific parts outside the
com.wireguard.android package.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-19 21:59:44 -05:00
Samuel Holland d3a8291a7a crypto: Slightly Java-ify the Curve25519 implementation
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-19 21:59:42 -05:00
Samuel Holland bcae77b989 app: Regularly scheduled gradle updates
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-19 21:35:54 -05:00
Samuel Holland de75ff4bea idea: Disable an unwanted inspection
Android Studio isn't smart enough to realize that the public/private
keys and the keypair are effectively the same thing. Just turn off the
inspection because it's usually tripped by intentional things.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-19 21:33:36 -05:00
Jason A. Donenfeld b10a6171a5 Application: make lock final
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-17 22:34:22 +02:00
Jason A. Donenfeld 6534f45a3a application: style fix
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-17 14:53:31 +02:00
Jason A. Donenfeld 373145d30e Version bump for clat fix
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-06-17 05:25:42 +02:00
37 changed files with 254 additions and 236 deletions
-1
View File
@@ -150,7 +150,6 @@
<inspection_tool class="FieldMayBeFinal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FieldMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FieldMustBeInitialized" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="FieldNotUsedInToString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FinalMethodInFinalClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FloatingPointEquality" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ForLoopReplaceableByWhile" enabled="true" level="WARNING" enabled_by_default="true">
+6 -7
View File
@@ -5,21 +5,19 @@ apply plugin: 'com.android.application'
final def keystorePropertiesFile = rootProject.file("keystore.properties")
android {
buildToolsVersion '27.0.3'
buildToolsVersion '28.0.0'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
compileSdkVersion 27
dataBinding {
enabled true
}
dataBinding.enabled true
defaultConfig {
applicationId 'com.wireguard.android'
minSdkVersion 21
targetSdkVersion 27
versionCode 425
versionName '0.0.20180613'
versionCode 427
versionName '0.0.20180625'
}
// If the keystore file exists
if (keystorePropertiesFile.exists()) {
@@ -49,8 +47,9 @@ android {
}
}
}
ext {
databindingVersion = '3.1.2'
databindingVersion = '3.1.3'
supportLibsVersion = '27.1.1'
streamsupportVersion = '1.6.0'
}
@@ -38,7 +38,7 @@ public class Application extends android.app.Application {
private TunnelManager tunnelManager;
private Handler handler;
private List<BackendCallback> haveBackendCallbacks = new ArrayList<>();
private Object haveBackendCallbacksLock = new Object();
private final Object haveBackendCallbacksLock = new Object();
public Application() {
weakSelf = new WeakReference<>(this);
@@ -54,7 +54,7 @@ public class Application extends android.app.Application {
public static Backend getBackend() {
final Application app = get();
synchronized(app) {
synchronized (app) {
if (app.backend == null) {
if (new File("/sys/module/wireguard").exists()) {
try {
@@ -20,7 +20,6 @@ import android.widget.Toast;
import com.wireguard.android.activity.MainActivity;
import com.wireguard.android.model.Tunnel;
import com.wireguard.android.model.Tunnel.State;
import com.wireguard.android.model.TunnelManager;
import com.wireguard.android.util.ExceptionLoggers;
import java.util.Objects;
@@ -50,11 +49,6 @@ public class QuickTileService extends TileService {
}
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onStartListening() {
Application.getTunnelManager().addOnPropertyChangedCallback(onTunnelChangedCallback);
@@ -10,7 +10,6 @@ import android.content.Intent;
import android.databinding.CallbackRegistry;
import android.databinding.CallbackRegistry.NotifierCallback;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.wireguard.android.Application;
import com.wireguard.android.backend.GoBackend;
@@ -6,14 +6,11 @@
package com.wireguard.android.activity;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
@@ -21,7 +21,7 @@ import com.wireguard.android.model.Tunnel.Statistics;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.android.util.SharedLibraryLoader;
import com.wireguard.config.Config;
import com.wireguard.config.IPCidr;
import com.wireguard.config.InetNetwork;
import com.wireguard.config.Interface;
import com.wireguard.config.Peer;
import com.wireguard.crypto.KeyEncoding;
@@ -156,7 +156,7 @@ public final class GoBackend implements Backend {
fmt.format("endpoint=%s\n", peer.getResolvedEndpointString());
if (peer.getPersistentKeepalive() != 0)
fmt.format("persistent_keepalive_interval=%d\n", peer.getPersistentKeepalive());
for (final IPCidr addr : peer.getAllowedIPs()) {
for (final InetNetwork addr : peer.getAllowedIPs()) {
fmt.format("allowed_ip=%s\n", addr.toString());
}
}
@@ -171,15 +171,15 @@ public final class GoBackend implements Backend {
configureIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
builder.setConfigureIntent(PendingIntent.getActivity(context, 0, configureIntent, 0));
for (final IPCidr addr : config.getInterface().getAddresses())
builder.addAddress(addr.getAddress(), addr.getCidr());
for (final InetNetwork addr : config.getInterface().getAddresses())
builder.addAddress(addr.getAddress(), addr.getMask());
for (final InetAddress addr : config.getInterface().getDnses())
builder.addDnsServer(addr.getHostAddress());
for (final Peer peer : config.getPeers()) {
for (final IPCidr addr : peer.getAllowedIPs())
builder.addRoute(addr.getAddress(), addr.getCidr());
for (final InetNetwork addr : peer.getAllowedIPs())
builder.addRoute(addr.getAddress(), addr.getMask());
}
int mtu = config.getInterface().getMtu();
@@ -15,7 +15,7 @@ import android.widget.ListView;
import android.widget.TextView;
import com.wireguard.android.R;
import com.wireguard.android.util.Keyed;
import com.wireguard.util.Keyed;
import com.wireguard.android.util.ObservableKeyedList;
import com.wireguard.android.widget.ToggleSwitch;
import com.wireguard.android.widget.ToggleSwitch.OnBeforeCheckedChangeListener;
@@ -16,7 +16,7 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.wireguard.android.BR;
import com.wireguard.android.util.Keyed;
import com.wireguard.util.Keyed;
import com.wireguard.android.util.ObservableKeyedList;
import java.lang.ref.WeakReference;
@@ -38,8 +38,6 @@ import com.wireguard.android.R;
import com.wireguard.android.activity.TunnelCreatorActivity;
import com.wireguard.android.databinding.TunnelListFragmentBinding;
import com.wireguard.android.model.Tunnel;
import com.wireguard.android.model.TunnelManager;
import com.wireguard.android.util.AsyncWorker;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.config.Config;
@@ -13,7 +13,7 @@ import android.support.annotation.Nullable;
import com.wireguard.android.BR;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.android.util.Keyed;
import com.wireguard.util.Keyed;
import com.wireguard.config.Config;
import java.util.regex.Pattern;
@@ -14,12 +14,11 @@ import android.support.design.widget.Snackbar;
import android.support.v7.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextThemeWrapper;
import com.wireguard.android.Application;
import com.wireguard.android.R;
import com.wireguard.android.activity.SettingsActivity;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.android.util.FragmentUtils;
import java.io.BufferedReader;
import java.io.File;
@@ -40,16 +39,6 @@ public class LogExporterPreference extends Preference {
super(context, attrs);
}
private static SettingsActivity getPrefActivity(final Preference preference) {
final Context context = preference.getContext();
if (context instanceof ContextThemeWrapper) {
if (((ContextThemeWrapper) context).getBaseContext() instanceof SettingsActivity) {
return ((SettingsActivity) ((ContextThemeWrapper) context).getBaseContext());
}
}
return null;
}
private void exportLog() {
Application.getAsyncWorker().supplyAsync(() -> {
final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
@@ -90,7 +79,7 @@ public class LogExporterPreference extends Preference {
final String message = getContext().getString(R.string.log_export_error, error);
Log.e(TAG, message, throwable);
Snackbar.make(
getPrefActivity(this).findViewById(android.R.id.content),
FragmentUtils.getPrefActivity(this).findViewById(android.R.id.content),
message, Snackbar.LENGTH_LONG).show();
setEnabled(true);
} else {
@@ -113,7 +102,7 @@ public class LogExporterPreference extends Preference {
@Override
protected void onClick() {
getPrefActivity(this).ensurePermissions(
FragmentUtils.getPrefActivity(this).ensurePermissions(
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
(permissions, granted) -> {
if (granted.length > 0 && granted[0] == PackageManager.PERMISSION_GRANTED) {
@@ -9,9 +9,7 @@ package com.wireguard.android.preference;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.preference.Preference;
import android.system.OsConstants;
import android.util.AttributeSet;
import android.util.Log;
import com.wireguard.android.Application;
import com.wireguard.android.R;
@@ -14,12 +14,6 @@ import android.util.AttributeSet;
import com.wireguard.android.Application;
import com.wireguard.android.BuildConfig;
import com.wireguard.android.R;
import com.wireguard.android.backend.Backend;
import com.wireguard.android.backend.GoBackend;
import com.wireguard.android.backend.WgQuickBackend;
import java.util.ArrayList;
import java.util.List;
public class VersionPreference extends Preference {
private String versionSummary;
@@ -14,13 +14,12 @@ import android.support.design.widget.Snackbar;
import android.support.v7.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextThemeWrapper;
import com.wireguard.android.Application;
import com.wireguard.android.R;
import com.wireguard.android.activity.SettingsActivity;
import com.wireguard.android.model.Tunnel;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.android.util.FragmentUtils;
import com.wireguard.config.Config;
import java.io.File;
@@ -47,16 +46,6 @@ public class ZipExporterPreference extends Preference {
super(context, attrs);
}
private static SettingsActivity getPrefActivity(final Preference preference) {
final Context context = preference.getContext();
if (context instanceof ContextThemeWrapper) {
if (((ContextThemeWrapper) context).getBaseContext() instanceof SettingsActivity) {
return ((SettingsActivity) ((ContextThemeWrapper) context).getBaseContext());
}
}
return null;
}
private void exportZip() {
final List<Tunnel> tunnels = new ArrayList<>(Application.getTunnelManager().getTunnels());
final List<CompletableFuture<Config>> futureConfigs = new ArrayList<>(tunnels.size());
@@ -96,7 +85,7 @@ public class ZipExporterPreference extends Preference {
final String message = getContext().getString(R.string.zip_export_error, error);
Log.e(TAG, message, throwable);
Snackbar.make(
getPrefActivity(this).findViewById(android.R.id.content),
FragmentUtils.getPrefActivity(this).findViewById(android.R.id.content),
message, Snackbar.LENGTH_LONG).show();
setEnabled(true);
} else {
@@ -119,7 +108,7 @@ public class ZipExporterPreference extends Preference {
@Override
protected void onClick() {
getPrefActivity(this).ensurePermissions(
FragmentUtils.getPrefActivity(this).ensurePermissions(
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
(permissions, granted) -> {
if (granted.length > 0 && granted[0] == PackageManager.PERMISSION_GRANTED) {
@@ -0,0 +1,25 @@
/*
* Copyright © 2018 Harsh Shandilya <msfjarvis@gmail.com>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package com.wireguard.android.util;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.view.ContextThemeWrapper;
import com.wireguard.android.activity.SettingsActivity;
public class FragmentUtils {
public static SettingsActivity getPrefActivity(final Preference preference) {
final Context context = preference.getContext();
if (context instanceof ContextThemeWrapper) {
if (((ContextThemeWrapper) context).getBaseContext() instanceof SettingsActivity) {
return ((SettingsActivity) ((ContextThemeWrapper) context).getBaseContext());
}
}
return null;
}
}
@@ -9,6 +9,8 @@ package com.wireguard.android.util;
import android.databinding.ObservableArrayList;
import android.support.annotation.NonNull;
import com.wireguard.util.Keyed;
import java.util.Collection;
import java.util.ListIterator;
import java.util.Objects;
@@ -8,6 +8,9 @@ package com.wireguard.android.util;
import android.databinding.ObservableList;
import com.wireguard.util.Keyed;
import com.wireguard.util.KeyedList;
/**
* A list that is both keyed and observable.
*/
@@ -8,6 +8,9 @@ package com.wireguard.android.util;
import android.support.annotation.NonNull;
import com.wireguard.util.Keyed;
import com.wireguard.util.SortedKeyedList;
import java.util.AbstractList;
import java.util.Collection;
import java.util.Collections;
@@ -6,6 +6,9 @@
package com.wireguard.android.util;
import com.wireguard.util.Keyed;
import com.wireguard.util.SortedKeyedList;
/**
* A list that is both sorted/keyed and observable.
*/
@@ -13,8 +13,8 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public final class SharedLibraryLoader {
private static final String TAG = "WireGuard/" + SharedLibraryLoader.class.getSimpleName();
@@ -27,7 +27,7 @@ public final class SharedLibraryLoader {
try {
System.loadLibrary(libName);
return;
} catch (UnsatisfiedLinkError e) {
} catch (final UnsatisfiedLinkError e) {
Log.d(TAG, "Failed to load library normally, so attempting to extract from apk", e);
noAbiException = e;
}
@@ -59,7 +59,7 @@ public final class SharedLibraryLoader {
}
System.load(f.getAbsolutePath());
return;
} catch (Exception e) {
} catch (final Exception e) {
Log.d(TAG, "Failed to load library apk:/" + libZipPath, e);
noAbiException = e;
} finally {
@@ -8,13 +8,26 @@ package com.wireguard.android.widget.fab;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.*;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.ShapeDrawable.ShaderFactory;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.support.annotation.*;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.AppCompatImageButton;
import android.util.AttributeSet;
@@ -466,7 +466,7 @@ public class FloatingActionsMenu extends ViewGroup {
}
@Override
public void setEnabled(boolean enabled) {
public void setEnabled(final boolean enabled) {
super.setEnabled(enabled);
mAddButton.setEnabled(enabled);
@@ -13,11 +13,11 @@ import android.view.TouchDelegate;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
public class TouchDelegateGroup extends TouchDelegate {
private static final Rect USELESS_HACKY_RECT = new Rect();
private final List<TouchDelegate> mTouchDelegates = new ArrayList<>();
private final Collection<TouchDelegate> mTouchDelegates = new ArrayList<>();
private TouchDelegate mCurrentTouchDelegate;
private boolean mEnabled;
@@ -49,8 +49,7 @@ public class TouchDelegateGroup extends TouchDelegate {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
for (int i = 0; i < mTouchDelegates.size(); i++) {
final TouchDelegate touchDelegate = mTouchDelegates.get(i);
for (final TouchDelegate touchDelegate : mTouchDelegates) {
if (touchDelegate.onTouchEvent(event)) {
mCurrentTouchDelegate = touchDelegate;
return true;
@@ -8,9 +8,6 @@ package com.wireguard.config;
import android.text.TextUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -36,7 +33,6 @@ enum Attribute {
private static final String[] EMPTY_LIST = new String[0];
private static final Map<String, Attribute> KEY_MAP;
private static final Pattern LIST_SEPARATOR_PATTERN = Pattern.compile("\\s*,\\s*");
private static final Method NUMERIC_ADDRESS_PARSER;
private static final Pattern SEPARATOR_PATTERN = Pattern.compile("\\s|=");
static {
@@ -46,14 +42,6 @@ enum Attribute {
}
}
static {
try {
NUMERIC_ADDRESS_PARSER = InetAddress.class.getMethod("parseNumericAddress", String.class);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private final Pattern pattern;
private final String token;
@@ -70,21 +58,6 @@ enum Attribute {
return KEY_MAP.get(SEPARATOR_PATTERN.split(line)[0].toLowerCase());
}
public static InetAddress parseIPString(final String address) {
if (address == null || address.isEmpty())
throw new IllegalArgumentException("Empty address");
try {
return (InetAddress) NUMERIC_ADDRESS_PARSER.invoke(null, address);
} catch (final IllegalAccessException e) {
throw new RuntimeException(e);
} catch (final InvocationTargetException e) {
if (e.getCause() instanceof IllegalArgumentException)
throw (IllegalArgumentException) e.getCause();
else
throw new IllegalArgumentException(e.getCause());
}
}
public static String[] stringToList(final String string) {
if (string == null)
return EMPTY_LIST;
@@ -1,48 +0,0 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package com.wireguard.config;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.Locale;
public class IPCidr {
private final InetAddress address;
private int cidr;
@SuppressWarnings("MagicNumber")
public IPCidr(String in) {
cidr = -1;
final int slash = in.lastIndexOf('/');
if (slash != -1 && slash < in.length() - 1) {
try {
cidr = Integer.parseInt(in.substring(slash + 1), 10);
in = in.substring(0, slash);
} catch (final Exception ignored) {
}
}
address = Attribute.parseIPString(in);
if ((address instanceof Inet6Address) && (cidr > 128 || cidr < 0))
cidr = 128;
else if ((address instanceof Inet4Address) && (cidr > 32 || cidr < 0))
cidr = 32;
}
public InetAddress getAddress() {
return address;
}
public int getCidr() {
return cidr;
}
@Override
public String toString() {
return String.format(Locale.getDefault(), "%s/%d", address.getHostAddress(), cidr);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package com.wireguard.config;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
public final class InetAddresses {
private static final Method PARSER_METHOD;
static {
try {
// This method is only present on Android.
PARSER_METHOD = InetAddress.class.getMethod("parseNumericAddress", String.class);
} catch (final NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
private InetAddresses() {
// Prevent instantiation.
}
@NonNull
public static InetAddress parse(@Nullable final String address) {
if (address == null || address.isEmpty())
throw new IllegalArgumentException("Empty address");
try {
return (InetAddress) PARSER_METHOD.invoke(null, address);
} catch (final IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,61 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package com.wireguard.config;
import android.support.annotation.NonNull;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Objects;
public class InetNetwork {
private final InetAddress address;
private final int mask;
public InetNetwork(@NonNull final String input) {
final int slash = input.lastIndexOf('/');
final int rawMask;
final String rawAddress;
if (slash >= 0) {
rawMask = Integer.parseInt(input.substring(slash + 1), 10);
rawAddress = input.substring(0, slash);
} else {
rawMask = -1;
rawAddress = input;
}
address = InetAddresses.parse(rawAddress);
final int maxMask = (address instanceof Inet4Address) ? 32 : 128;
mask = rawMask >= 0 && rawMask <= maxMask ? rawMask : maxMask;
}
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof InetNetwork))
return false;
final InetNetwork other = (InetNetwork) obj;
return Objects.equals(address, other.address) && mask == other.mask;
}
@NonNull
public InetAddress getAddress() {
return address;
}
public int getMask() {
return mask;
}
@Override
public int hashCode() {
return address.hashCode() ^ mask;
}
@Override
public String toString() {
return address.getHostAddress() + '/' + mask;
}
}
@@ -23,7 +23,7 @@ import java.util.List;
*/
public class Interface {
private final List<IPCidr> addressList;
private final List<InetNetwork> addressList;
private final List<InetAddress> dnsList;
private Keypair keypair;
private int listenPort;
@@ -39,7 +39,7 @@ public class Interface {
for (final String addr : addresses) {
if (addr.isEmpty())
throw new IllegalArgumentException("Address is empty");
addressList.add(new IPCidr(addr));
addressList.add(new InetNetwork(addr));
}
}
}
@@ -47,7 +47,7 @@ public class Interface {
private void addDnses(final String[] dnses) {
if (dnses != null && dnses.length > 0) {
for (final String dns : dnses) {
dnsList.add(Attribute.parseIPString(dns));
dnsList.add(InetAddresses.parse(dns));
}
}
}
@@ -58,8 +58,8 @@ public class Interface {
return Attribute.iterableToString(addressList);
}
public IPCidr[] getAddresses() {
return addressList.toArray(new IPCidr[addressList.size()]);
public InetNetwork[] getAddresses() {
return addressList.toArray(new InetNetwork[addressList.size()]);
}
private String getDnsString() {
@@ -28,7 +28,7 @@ import java.util.Locale;
*/
public class Peer {
private final List<IPCidr> allowedIPsList;
private final List<InetNetwork> allowedIPsList;
private InetSocketAddress endpoint;
private int persistentKeepalive;
private String preSharedKey;
@@ -41,13 +41,13 @@ public class Peer {
private void addAllowedIPs(final String[] allowedIPs) {
if (allowedIPs != null && allowedIPs.length > 0) {
for (final String allowedIP : allowedIPs) {
allowedIPsList.add(new IPCidr(allowedIP));
allowedIPsList.add(new InetNetwork(allowedIP));
}
}
}
public IPCidr[] getAllowedIPs() {
return allowedIPsList.toArray(new IPCidr[allowedIPsList.size()]);
public InetNetwork[] getAllowedIPs() {
return allowedIPsList.toArray(new InetNetwork[allowedIPsList.size()]);
}
private String getAllowedIPsString() {
@@ -10,23 +10,23 @@ import java.util.Arrays;
/**
* Implementation of the Curve25519 elliptic curve algorithm.
* <p>
* This implementation was imported to WireGuard from noise-java:
* https://github.com/rweather/noise-java
* <p>
* This implementation is based on that from arduinolibs:
* https://github.com/rweather/arduinolibs
* <p>
* This implementation is copied verbatim from noise-java:
* https://github.com/rweather/noise-java
* <p>
* Differences in this version are due to using 26-bit limbs for the
* representation instead of the 8/16/32-bit limbs in the original.
* <p>
* References: http://cr.yp.to/ecdh.html, RFC 7748
*/
@SuppressWarnings("MagicNumber")
@SuppressWarnings({"MagicNumber", "NonConstantFieldWithUpperCaseName", "SuspiciousNameCombination"})
public final class Curve25519 {
// Numbers modulo 2^255 - 19 are broken up into ten 26-bit words.
private static final int NUM_LIMBS_255BIT = 10;
private static final int NUM_LIMBS_510BIT = 20;
private final int[] A;
private final int[] AA;
private final int[] B;
@@ -152,6 +152,38 @@ public final class Curve25519 {
}
}
/**
* Subtracts two numbers modulo 2^255 - 19.
*
* @param result The result.
* @param x The first number to subtract.
* @param y The second number to subtract.
*/
private static void sub(final int[] result, final int[] x, final int[] y) {
int index;
int borrow;
// Subtract y from x to generate the intermediate result.
borrow = 0;
for (index = 0; index < NUM_LIMBS_255BIT; ++index) {
borrow = x[index] - y[index] - ((borrow >> 26) & 0x01);
result[index] = borrow & 0x03FFFFFF;
}
// If we had a borrow, then the result has gone negative and we
// have to add 2^255 - 19 to the result to make it positive again.
// The top bits of "borrow" will be all 1's if there is a borrow
// or it will be all 0's if there was no borrow. Easiest is to
// conditionally subtract 19 and then mask off the high bits.
borrow = result[0] - ((-((borrow >> 26) & 0x01)) & 19);
result[0] = borrow & 0x03FFFFFF;
for (index = 1; index < NUM_LIMBS_255BIT; ++index) {
borrow = result[index] - ((borrow >> 26) & 0x01);
result[index] = borrow & 0x03FFFFFF;
}
result[NUM_LIMBS_255BIT - 1] &= 0x001FFFFF;
}
/**
* Adds two numbers modulo 2^255 - 19.
*
@@ -160,8 +192,7 @@ public final class Curve25519 {
* @param y The second number to add.
*/
private void add(final int[] result, final int[] x, final int[] y) {
int carry;
carry = x[0] + y[0];
int carry = x[0] + y[0];
result[0] = carry & 0x03FFFFFF;
for (int index = 1; index < NUM_LIMBS_255BIT; ++index) {
carry = (carry >> 26) + x[index] + y[index];
@@ -200,12 +231,13 @@ public final class Curve25519 {
*/
private void evalCurve(final byte[] s) {
int sposn = 31;
int sbit = 6;
int svalue = s[sposn] | 0x40;
int swap = 0;
// Iterate over all 255 bits of "s" from the highest to the lowest.
// We ignore the high bit of the 256-bit representation of "s".
for (int sbit = 6; ; ) {
while (true) {
// Conditional swaps on entry to this bit but only if we
// didn't swap on the previous bit.
final int select = (svalue >> sbit) & 0x01;
@@ -263,14 +295,12 @@ public final class Curve25519 {
* @param y The second number to multiply.
*/
private void mul(final int[] result, final int[] x, final int[] y) {
int i;
// Multiply the two numbers to create the intermediate result.
long v = x[0];
for (i = 0; i < NUM_LIMBS_255BIT; ++i) {
for (int i = 0; i < NUM_LIMBS_255BIT; ++i) {
t1[i] = v * y[i];
}
for (i = 1; i < NUM_LIMBS_255BIT; ++i) {
for (int i = 1; i < NUM_LIMBS_255BIT; ++i) {
v = x[i];
for (int j = 0; j < (NUM_LIMBS_255BIT - 1); ++j) {
t1[i + j] += v * y[j];
@@ -281,7 +311,7 @@ public final class Curve25519 {
// Propagate carries and convert back into 26-bit words.
v = t1[0];
t2[0] = ((int) v) & 0x03FFFFFF;
for (i = 1; i < NUM_LIMBS_510BIT; ++i) {
for (int i = 1; i < NUM_LIMBS_510BIT; ++i) {
v = (v >> 26) + t1[i];
t2[i] = ((int) v) & 0x03FFFFFF;
}
@@ -315,8 +345,6 @@ public final class Curve25519 {
* @param x The argument.
*/
private void pow250(final int[] result, final int[] x) {
int j;
// The big-endian hexadecimal expansion of (2^250 - 1) is:
// 03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
//
@@ -329,11 +357,11 @@ public final class Curve25519 {
// Build a pattern of 250 bits in length of repeated copies of 0000000001.
square(A, x);
for (j = 0; j < 9; ++j)
for (int j = 0; j < 9; ++j)
square(A, A);
mul(result, A, x);
for (int i = 0; i < 23; ++i) {
for (j = 0; j < 10; ++j)
for (int j = 0; j < 10; ++j)
square(A, A);
mul(result, result, A);
}
@@ -342,7 +370,7 @@ public final class Curve25519 {
// the result to "fill in" the gaps in the pattern.
square(A, result);
mul(result, result, A);
for (j = 0; j < 8; ++j) {
for (int j = 0; j < 8; ++j) {
square(A, A);
mul(result, result, A);
}
@@ -381,18 +409,14 @@ public final class Curve25519 {
* @param size The number of limbs in the high order half of x.
*/
private void reduce(final int[] result, final int[] x, final int size) {
int index;
int limb;
int carry;
// Calculate (x mod 2^255) + ((x / 2^255) * 19) which will
// either produce the answer we want or it will produce a
// value of the form "answer + j * (2^255 - 19)". There are
// 5 left-over bits in the top-most limb of the bottom half.
carry = 0;
limb = x[NUM_LIMBS_255BIT - 1] >> 21;
int carry = 0;
int limb = x[NUM_LIMBS_255BIT - 1] >> 21;
x[NUM_LIMBS_255BIT - 1] &= 0x001FFFFF;
for (index = 0; index < size; ++index) {
for (int index = 0; index < size; ++index) {
limb += x[NUM_LIMBS_255BIT + index] << 5;
carry += (limb & 0x03FFFFFF) * 19 + x[index];
x[index] = carry & 0x03FFFFFF;
@@ -402,7 +426,7 @@ public final class Curve25519 {
if (size < NUM_LIMBS_255BIT) {
// The high order half of the number is short; e.g. for mulA24().
// Propagate the carry through the rest of the low order part.
for (index = size; index < NUM_LIMBS_255BIT; ++index) {
for (int index = size; index < NUM_LIMBS_255BIT; ++index) {
carry += x[index];
x[index] = carry & 0x03FFFFFF;
carry >>= 26;
@@ -417,7 +441,7 @@ public final class Curve25519 {
// top 5 bits of the highest limb of the bottom half.
carry = (x[NUM_LIMBS_255BIT - 1] >> 21) * 19;
x[NUM_LIMBS_255BIT - 1] &= 0x001FFFFF;
for (index = 0; index < NUM_LIMBS_255BIT; ++index) {
for (int index = 0; index < NUM_LIMBS_255BIT; ++index) {
carry += x[index];
result[index] = carry & 0x03FFFFFF;
carry >>= 26;
@@ -436,14 +460,11 @@ public final class Curve25519 {
* @param x The number to reduce, and the result.
*/
private void reduceQuick(final int[] x) {
int index;
int carry;
// Perform a trial subtraction of (2^255 - 19) from "x" which is
// equivalent to adding 19 and subtracting 2^255. We add 19 here;
// the subtraction of 2^255 occurs in the next step.
carry = 19;
for (index = 0; index < NUM_LIMBS_255BIT; ++index) {
int carry = 19;
for (int index = 0; index < NUM_LIMBS_255BIT; ++index) {
carry += x[index];
t2[index] = carry & 0x03FFFFFF;
carry >>= 26;
@@ -457,7 +478,7 @@ public final class Curve25519 {
final int mask = -((t2[NUM_LIMBS_255BIT - 1] >> 21) & 0x01);
final int nmask = ~mask;
t2[NUM_LIMBS_255BIT - 1] &= 0x001FFFFF;
for (index = 0; index < NUM_LIMBS_255BIT; ++index)
for (int index = 0; index < NUM_LIMBS_255BIT; ++index)
x[index] = (x[index] & nmask) | (t2[index] & mask);
}
@@ -470,36 +491,4 @@ public final class Curve25519 {
private void square(final int[] result, final int[] x) {
mul(result, x, x);
}
/**
* Subtracts two numbers modulo 2^255 - 19.
*
* @param result The result.
* @param x The first number to subtract.
* @param y The second number to subtract.
*/
private static void sub(final int[] result, final int[] x, final int[] y) {
int index;
int borrow;
// Subtract y from x to generate the intermediate result.
borrow = 0;
for (index = 0; index < NUM_LIMBS_255BIT; ++index) {
borrow = x[index] - y[index] - ((borrow >> 26) & 0x01);
result[index] = borrow & 0x03FFFFFF;
}
// If we had a borrow, then the result has gone negative and we
// have to add 2^255 - 19 to the result to make it positive again.
// The top bits of "borrow" will be all 1's if there is a borrow
// or it will be all 0's if there was no borrow. Easiest is to
// conditionally subtract 19 and then mask off the high bits.
borrow = result[0] - ((-((borrow >> 26) & 0x01)) & 19);
result[0] = borrow & 0x03FFFFFF;
for (index = 1; index < NUM_LIMBS_255BIT; ++index) {
borrow = result[index] - ((borrow >> 26) & 0x01);
result[index] = borrow & 0x03FFFFFF;
}
result[NUM_LIMBS_255BIT - 1] &= 0x001FFFFF;
}
}
@@ -1,10 +1,9 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package com.wireguard.android.util;
package com.wireguard.util;
/**
* Interface for objects that have a identifying key of the given type.
@@ -1,10 +1,9 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package com.wireguard.android.util;
package com.wireguard.util;
import java.util.Collection;
import java.util.List;
@@ -1,10 +1,9 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package com.wireguard.android.util;
package com.wireguard.util;
import java.util.Collection;
import java.util.Comparator;
+1 -1
View File
@@ -7,7 +7,7 @@ allprojects {
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'com.android.tools.build:gradle:3.1.3'
}
repositories {
google()
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip