summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2017-11-26 23:41:50 -0500
committerArne Schwabe <arne@rfc2549.org>2017-11-26 23:51:44 -0500
commit7b0af007a717c72d957ed413bb91ae17da9343a1 (patch)
treeac5a67f74bf75f5d4cc6fc9808e1f25fff1b7f5b
parentbfc020a66bad76966b37f1a2be7887c0d9a6dc91 (diff)
New NDK and OpenSSL Speed test
-rw-r--r--gradle/wrapper/gradle-wrapper.properties9
-rw-r--r--main/jni/Android.mk4
-rw-r--r--main/jni/Application.mk2
-rw-r--r--main/jni/jbcrypto.cpp3
-rw-r--r--main/jni/sslspeed.c309
m---------main/openssl0
m---------main/openvpn0
-rw-r--r--main/src/main/AndroidManifest.xml62
-rw-r--r--main/src/main/java/android/support/v4n/view/ViewPager.java12
-rw-r--r--main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java192
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java7
-rw-r--r--main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java5
-rw-r--r--main/src/main/res/layout/openssl_speed.xml40
-rw-r--r--main/src/main/res/layout/speedviewitem.xml54
-rwxr-xr-xmain/src/main/res/values/strings.xml8
-rw-r--r--main/src/main/res/values/untranslatable.xml6
-rw-r--r--main/src/main/res/xml/general_settings.xml4
17 files changed, 660 insertions, 57 deletions
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index b217b6d7..c188c8b0 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,11 +1,6 @@
-#
-# Copyright (c) 2012-2017 Arne Schwabe
-# Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
-#
-
-#Wed Apr 05 16:08:37 CEST 2017
+#Fri Nov 24 12:34:12 EST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-4.4-20171031235950+0000-all.zip
diff --git a/main/jni/Android.mk b/main/jni/Android.mk
index 828bb8da..ae45c10d 100644
--- a/main/jni/Android.mk
+++ b/main/jni/Android.mk
@@ -52,8 +52,10 @@ LOCAL_PATH := $(JNI_DIR)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog -lz
LOCAL_CFLAGS = -DTARGET_ARCH_ABI=\"${TARGET_ARCH_ABI}\"
-LOCAL_SRC_FILES:= jniglue.c scan_ifs.c
+LOCAL_SRC_FILES:= jniglue.c scan_ifs.c sslspeed.c
+LOCAL_C_INCLUDES := openssl/include openssl/crypto openssl openssl/crypto/include
LOCAL_MODULE = opvpnutil
+LOCAL_STATIC_LIBRARIES := libssl_static libcrypto_static
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
diff --git a/main/jni/Application.mk b/main/jni/Application.mk
index 838c2eba..7033ee93 100644
--- a/main/jni/Application.mk
+++ b/main/jni/Application.mk
@@ -2,7 +2,7 @@ ifeq ($(USE_SHORT_COMMANDS),1)
APP_SHORT_COMMANDS := true
endif
-APP_ABI := arm64-v8a armeabi armeabi-v7a x86 x86_64
+APP_ABI := arm64-v8a armeabi-v7a x86 x86_64
APP_PLATFORM := android-14
#APP_STL:=stlport_static
diff --git a/main/jni/jbcrypto.cpp b/main/jni/jbcrypto.cpp
index 810a3bc7..c61ef14f 100644
--- a/main/jni/jbcrypto.cpp
+++ b/main/jni/jbcrypto.cpp
@@ -20,7 +20,8 @@
#include <internal/evp_int.h>
extern "C" {
-jbyteArray Java_de_blinkt_openvpn_core_NativeUtils_rsasign(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef);
+ jbyteArray Java_de_blinkt_openvpn_core_NativeUtils_rsasign(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef);
+ int jniThrowException(JNIEnv* env, const char* className, const char* msg);
}
int jniThrowException(JNIEnv* env, const char* className, const char* msg) {
diff --git a/main/jni/sslspeed.c b/main/jni/sslspeed.c
new file mode 100644
index 00000000..0ce9ede2
--- /dev/null
+++ b/main/jni/sslspeed.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The ECDH and ECDSA speed test software is originally written by
+ * Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+
+// Modified by Arne Schwabe to give a simple openssl evp speed java api
+
+#include <jni.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <linux/if.h>
+#include <android/log.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "jniglue.h"
+#include <android/log.h>
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/async.h>
+
+
+/* This file just contains code thrown together until it works */
+
+
+#undef SECONDS
+#define SECONDS 3
+#define PRIME_SECONDS 10
+#define RSA_SECONDS 10
+#define DSA_SECONDS 10
+#define ECDSA_SECONDS 10
+#define ECDH_SECONDS 10
+
+
+typedef struct loopargs_st {
+ unsigned char *buf;
+ unsigned char *buf2;
+ unsigned char *buf_malloc;
+ unsigned char *buf2_malloc;
+ unsigned int siglen;
+ EVP_CIPHER_CTX *ctx;
+ HMAC_CTX *hctx;
+} loopargs_t;
+
+#undef BUFSIZE
+#define BUFSIZE (1024*16+1)
+#define MAX_MISALIGNMENT 63
+
+
+#define MAX_BLOCK_SIZE 128
+static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
+
+#define SIZE_NUM 6
+static const int lengths[SIZE_NUM] = {
+ 16, 64, 256, 1024, 8 * 1024, 16 * 1024
+};
+
+static int testnum;
+
+# define COND(unused_cond) (run && count<0x7fffffff)
+
+static volatile int run = 0;
+
+#ifdef SIGALRM
+# if defined(__STDC__) || defined(sgi) || defined(_AIX)
+# define SIGRETTYPE void
+# else
+# define SIGRETTYPE int
+# endif
+
+
+#define START 0
+#define STOP 1
+#define TM_START 0
+#define TM_STOP 1
+
+# include <sys/times.h>
+
+static int usertime = 1;
+
+double app_tminterval(int stop, int usertime)
+{
+ double ret = 0;
+ struct tms rus;
+ clock_t now = times(&rus);
+ static clock_t tmstart;
+
+ if (usertime)
+ now = rus.tms_utime;
+
+ if (stop == TM_START)
+ tmstart = now;
+ else {
+ long int tck = sysconf(_SC_CLK_TCK);
+ ret = (now - tmstart) / (double)tck;
+ }
+
+ return (ret);
+}
+
+
+
+
+static double Time_F(int s)
+{
+ double ret = app_tminterval(s, usertime);
+ if (s == STOP)
+ alarm(0);
+ return ret;
+}
+
+#endif
+
+
+static long save_count = 0;
+static int decrypt = 0;
+static int EVP_Update_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **)args;
+ unsigned char *buf = tempargs->buf;
+ EVP_CIPHER_CTX *ctx = tempargs->ctx;
+ int outl, count;
+
+ if (decrypt)
+ for (count = 0; COND(nb_iter); count++)
+ EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
+ else
+ for (count = 0; COND(nb_iter); count++)
+ EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
+ if (decrypt)
+ EVP_DecryptFinal_ex(ctx, buf, &outl);
+ else
+ EVP_EncryptFinal_ex(ctx, buf, &outl);
+ return count;
+}
+
+static const EVP_MD *evp_md = NULL;
+static int EVP_Digest_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **)args;
+ unsigned char *buf = tempargs->buf;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ int count;
+
+ for (count = 0; COND(nb_iter); count++) {
+ if (!EVP_Digest(buf, lengths[testnum], md, NULL, evp_md, NULL))
+ return -1;
+ }
+ return count;
+}
+
+
+static int run_benchmark(int async_jobs,
+ int (*loop_function)(void *), loopargs_t *loopargs)
+{
+ int job_op_count = 0;
+ int total_op_count = 0;
+ int num_inprogress = 0;
+ int error = 0, i = 0, ret = 0;
+ OSSL_ASYNC_FD job_fd = 0;
+ size_t num_job_fds = 0;
+
+ run = 1;
+
+ if (async_jobs == 0) {
+ return loop_function((void *)&loopargs);
+ }
+ return 1234567;
+}
+
+
+static void* stop_run(void* arg)
+{
+ __android_log_write(ANDROID_LOG_DEBUG,"openvpn", "stop run thread started");
+ sleep(3);
+ run=0;
+ __android_log_write(ANDROID_LOG_DEBUG,"openvpn", "stop run thread stopped");
+ return NULL;
+}
+
+ jdoubleArray Java_de_blinkt_openvpn_core_NativeUtils_getOpenSSLSpeed(JNIEnv* env, jclass thiz, jstring algorithm, jint testnumber)
+{
+ static const unsigned char key16[16] = {
+ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+ 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
+ };
+ const EVP_CIPHER *evp_cipher = NULL;
+
+ const char* alg = (*env)->GetStringUTFChars( env, algorithm , NULL ) ;
+
+ evp_cipher = EVP_get_cipherbyname(alg);
+ if (evp_cipher == NULL)
+ evp_md = EVP_get_digestbyname(alg);
+ if (evp_cipher == NULL && evp_md == NULL) {
+ // BIO_printf(bio_err, "%s: %s is an unknown cipher or digest\n", prog, opt_arg());
+ //jniThrowException(env, "java/security/NoSuchAlgorithmException", "Algorithm not found");
+ return NULL;
+ }
+
+
+ const char* name;
+
+ loopargs_t *loopargs = NULL;
+ int loopargs_len = 1;
+ int async_jobs=0;
+ loopargs = malloc(loopargs_len * sizeof(loopargs_t));
+ memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
+
+
+ jdoubleArray ret = (*env)->NewDoubleArray(env, 3);
+
+ if (testnum < 0 || testnum >= SIZE_NUM)
+ return NULL;
+
+ testnum = testnumber;
+
+
+ for (int i = 0; i < loopargs_len; i++) {
+ int misalign=0;
+ loopargs[i].buf_malloc = malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1);
+ loopargs[i].buf2_malloc = malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1);
+ /* Align the start of buffers on a 64 byte boundary */
+ loopargs[i].buf = loopargs[i].buf_malloc + misalign;
+ loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
+ }
+
+
+ int count;
+ float d;
+ if (evp_cipher) {
+ name = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
+ /*
+ * -O3 -fschedule-insns messes up an optimization here!
+ * names[D_EVP] somehow becomes NULL
+ */
+
+
+ for (int k = 0; k < loopargs_len; k++) {
+ loopargs[k].ctx = EVP_CIPHER_CTX_new();
+ if (decrypt)
+ EVP_DecryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
+ else
+ EVP_EncryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
+ EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
+ }
+
+ Time_F(START);
+ pthread_t timer_thread;
+
+ if (pthread_create(&timer_thread, NULL, stop_run, NULL))
+ return NULL;
+
+ count = run_benchmark(async_jobs, EVP_Update_loop, loopargs);
+ d = Time_F(STOP);
+ for (int k = 0; k < loopargs_len; k++) {
+ EVP_CIPHER_CTX_free(loopargs[k].ctx);
+ }
+ }
+ if (evp_md) {
+ name = OBJ_nid2ln(EVP_MD_type(evp_md));
+ // print_message(names[D_EVP], save_count, lengths[testnum]);
+
+ pthread_t timer_thread;
+ if (pthread_create(&timer_thread, NULL, stop_run, NULL))
+ return NULL;
+
+ Time_F(START);
+ count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs);
+ d = Time_F(STOP);
+ }
+
+ // Save results in hacky way
+ double results[] = {(double) lengths[testnum], (double) count, d};
+
+
+ (*env)->SetDoubleArrayRegion(env, ret, 0, 3, results);
+ // print_result(D_EVP, testnum, count, d);
+
+
+ return ret;
+}
diff --git a/main/openssl b/main/openssl
-Subproject 8b837cde90aa660dbbe9075c40a508e21f1aba1
+Subproject e6d693e846f38eb43a06b1c464d534bf39be80d
diff --git a/main/openvpn b/main/openvpn
-Subproject 9fa0b9a7e1240170f964bbca6a3d4f608b6325b
+Subproject 61ec1d3207a058b29eb8c463550dc5958cf0e38
diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml
index 925d7945..e57cf096 100644
--- a/main/src/main/AndroidManifest.xml
+++ b/main/src/main/AndroidManifest.xml
@@ -1,10 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2012-2016 Arne Schwabe
~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
- -->
-
+-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="de.blinkt.openvpn">
@@ -16,6 +13,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> -->
+
<!-- <uses-permission android:name="com.android.vending.BILLING" /> -->
<uses-feature
@@ -27,8 +25,8 @@
<application
android:name=".core.ICSOpenVPNApplication"
- android:appCategory="productivity"
android:allowBackup="true"
+ android:appCategory="productivity"
android:banner="@mipmap/banner_tv"
android:icon="@mipmap/ic_launcher"
android:label="@string/app"
@@ -39,7 +37,6 @@
android:name=".activities.VPNPreferences"
android:exported="false"
android:windowSoftInputMode="stateHidden" />
-
<activity
android:name=".activities.DisconnectVPN"
android:autoRemoveFromRecents="true"
@@ -47,7 +44,6 @@
android:noHistory="true"
android:taskAffinity=".DisconnectVPN"
android:theme="@style/blinkt.dialog" />
-
<activity
android:name=".activities.LogWindow"
android:allowTaskReparenting="true"
@@ -68,39 +64,36 @@
<service
android:name=".core.OpenVPNService"
- android:process=":openvpn"
- android:permission="android.permission.BIND_VPN_SERVICE" >
+ android:permission="android.permission.BIND_VPN_SERVICE"
+ android:process=":openvpn">
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
-
</service>
-
<service
android:name=".api.ExternalOpenVPNService"
android:process=":openvpn"
tools:ignore="ExportedService">
-
<intent-filter>
<action android:name="de.blinkt.openvpn.api.IOpenVPNAPIService" />
</intent-filter>
</service>
-
- <service android:name=".core.OpenVPNStatusService"
- android:process=":openvpn"
- android:exported="false" />
-
-
+ <service
+ android:name=".core.OpenVPNStatusService"
+ android:exported="false"
+ android:process=":openvpn" />
<service
android:name=".OpenVPNTileService"
- android:value="true"
- android:label="@string/qs_title"
android:icon="@drawable/ic_quick"
- android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+ android:label="@string/qs_title"
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
+ android:value="true">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
- <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
+
+ <meta-data
+ android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="false" />
</service>
@@ -119,7 +112,6 @@
<intent-filter android:priority="999">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
-
</intent-filter>
</receiver>
@@ -130,7 +122,8 @@
android:taskAffinity=".ConfigConverter"
android:uiOptions="splitActionBarWhenNarrow"
tools:ignore="ExportedActivity">
- <intent-filter android:label="@string/import_config"
+ <intent-filter
+ android:label="@string/import_config"
tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
@@ -139,7 +132,8 @@
<data android:mimeType="application/x-openvpn-profile" />
</intent-filter>
- <intent-filter android:label="@string/import_config"
+ <intent-filter
+ android:label="@string/import_config"
tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
@@ -181,8 +175,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
-
-
<activity
android:name=".api.Intents"
android:autoRemoveFromRecents="true"
@@ -197,8 +189,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
-
-
<activity
android:name=".activities.CreateShortcuts"
android:excludeFromRecents="true"
@@ -207,6 +197,7 @@
android:theme="@android:style/Theme.DeviceDefault.Light.DialogWhenLarge">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
+
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
@@ -218,7 +209,6 @@
android:grantUriPermissions="true"
tools:ignore="ExportedContentProvider" />
-
<!--
<receiver android:name="core.GetRestrictionReceiver">
<intent-filter>
@@ -226,6 +216,14 @@
</intent-filter>
</receiver>
-->
+ <activity
+ android:name=".activities.OpenSSLSpeed"
+ android:label="@string/title_activity_open_sslspeed"
+ android:parentActivityName=".activities.MainActivity">
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value="de.blinkt.openvpn.activities.MainActivity" />
+ </activity>
</application>
-</manifest>
+</manifest> \ No newline at end of file
diff --git a/main/src/main/java/android/support/v4n/view/ViewPager.java b/main/src/main/java/android/support/v4n/view/ViewPager.java
index 4e44bd99..53daa70d 100644
--- a/main/src/main/java/android/support/v4n/view/ViewPager.java
+++ b/main/src/main/java/android/support/v4n/view/ViewPager.java
@@ -33,7 +33,6 @@ import android.support.annotation.DrawableRes;
import android.support.v4.os.ParcelableCompat;
import android.support.v4.os.ParcelableCompatCreatorCallbacks;
import android.support.v4.view.AccessibilityDelegateCompat;
-import android.support.v4.view.KeyEventCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.VelocityTrackerCompat;
import android.support.v4.view.ViewCompat;
@@ -2508,17 +2507,6 @@ public class ViewPager extends ViewGroup {
case KeyEvent.KEYCODE_DPAD_RIGHT:
handled = arrowScroll(FOCUS_RIGHT);
break;
- case KeyEvent.KEYCODE_TAB:
- if (Build.VERSION.SDK_INT >= 11) {
- // The focus finder had a bug handling FOCUS_FORWARD and FOCUS_BACKWARD
- // before Android 3.0. Ignore the tab key on those devices.
- if (KeyEventCompat.hasNoModifiers(event)) {
- handled = arrowScroll(FOCUS_FORWARD);
- } else if (KeyEventCompat.hasModifiers(event, KeyEvent.META_SHIFT_ON)) {
- handled = arrowScroll(FOCUS_BACKWARD);
- }
- }
- break;
}
}
return handled;
diff --git a/main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java b/main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java
new file mode 100644
index 00000000..e10778f1
--- /dev/null
+++ b/main/src/main/java/de/blinkt/openvpn/activities/OpenSSLSpeed.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012-2017 Arne Schwabe
+ * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ */
+
+package de.blinkt.openvpn.activities;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.app.Activity;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import de.blinkt.openvpn.R;
+import de.blinkt.openvpn.core.NativeUtils;
+import de.blinkt.openvpn.core.OpenVPNService;
+
+public class OpenSSLSpeed extends Activity {
+
+ private static SpeeedTest runTestAlgorithms;
+ private EditText mCipher;
+ private SpeedArrayAdapter mAdapter;
+ private ListView mListView;
+
+
+ static class SpeedArrayAdapter extends ArrayAdapter<SpeedResult> {
+
+ private final Context mContext;
+ private final LayoutInflater mInflater;
+
+ public SpeedArrayAdapter(@NonNull Context context) {
+ super(context, 0);
+ mContext = context;
+ mInflater = LayoutInflater.from(context);
+
+ }
+
+ class ViewHolder {
+ TextView ciphername;
+ TextView blocksize;
+ TextView blocksInTime;
+ TextView speed;
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, @Nullable View view, @NonNull ViewGroup parent) {
+ SpeedResult res = getItem(position);
+ if (view == null) {
+ view = mInflater.inflate(R.layout.speedviewitem, parent, false);
+ ViewHolder holder = new ViewHolder();
+ holder.ciphername = view.findViewById(R.id.ciphername);
+ holder.speed = view.findViewById(R.id.speed);
+ holder.blocksize = view.findViewById(R.id.blocksize);
+ holder.blocksInTime = view.findViewById(R.id.blocksintime);
+ view.setTag(holder);
+ }
+
+ ViewHolder holder = (ViewHolder) view.getTag();
+
+ double total = res.count * res.length;
+ String size = OpenVPNService.humanReadableByteCount((long) res.length, false, mContext.getResources());
+
+ holder.blocksize.setText(size);
+ holder.ciphername.setText(res.algorithm);
+
+ if (res.failed) {
+ holder.blocksInTime.setText(R.string.openssl_error);
+ holder.speed.setText("-");
+ } else if (res.running) {
+ holder.blocksInTime.setText(R.string.running_test);
+ holder.speed.setText("-");
+ } else {
+ String totalBytes = OpenVPNService.humanReadableByteCount((long) total, false, mContext.getResources());
+ // TODO: Fix localisation here
+ String blockPerSec = OpenVPNService.humanReadableByteCount((long) (total / res.time), false, mContext.getResources()) + "/s";
+ holder.speed.setText(blockPerSec);
+ holder.blocksInTime.setText(String.format(Locale.ENGLISH, "%d blocks (%s) in %2.1fs", (long) res.count, totalBytes, res.time));
+ }
+
+ return view;
+
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.openssl_speed);
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ findViewById(R.id.testSpecific).setOnClickListener((view) -> {
+ runAlgorithms(mCipher.getText().toString());
+ });
+ mCipher = (EditText) findViewById(R.id.ciphername);
+
+ mListView = findViewById(R.id.results);
+
+ mAdapter = new SpeedArrayAdapter(this);
+ mListView.setAdapter(mAdapter);
+
+ }
+
+ private void runAlgorithms(String algorithms) {
+ if (runTestAlgorithms != null)
+ runTestAlgorithms.cancel(true);
+ runTestAlgorithms = new SpeeedTest();
+ runTestAlgorithms.execute(algorithms.split(" "));
+ }
+
+
+ static class SpeedResult {
+ String algorithm;
+ boolean failed = false;
+
+ double count;
+ double time;
+ int length;
+ public boolean running=true;
+
+ SpeedResult(String algorithm) {
+ this.algorithm = algorithm;
+ }
+ }
+
+
+ private class SpeeedTest extends AsyncTask<String, SpeedResult, SpeedResult[]> {
+
+
+ private boolean mCancel = false;
+
+ @Override
+ protected SpeedResult[] doInBackground(String... strings) {
+ Vector<SpeedResult> mResult = new Vector<>();
+
+ for (String algorithm : strings) {
+
+ for (int i = 0; i < NativeUtils.openSSLlengths.length && !mCancel; i++) {
+ SpeedResult result = new SpeedResult(algorithm);
+ result.length = NativeUtils.openSSLlengths[i];
+ mResult.add(result);
+ publishProgress(result);
+ double[] resi = NativeUtils.getOpenSSLSpeed(algorithm, i);
+ if (resi == null) {
+ result.failed = true;
+ } else {
+ result.count = resi[1];
+ result.time = resi[2];
+ }
+ result.running = false;
+ publishProgress(result);
+ }
+ }
+
+ return mResult.toArray(new SpeedResult[mResult.size()]);
+
+ }
+
+ @Override
+ protected void onProgressUpdate(SpeedResult... values) {
+ for (SpeedResult r : values) {
+ if (r.running)
+ mAdapter.add(r);
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ protected void onPostExecute(SpeedResult[] speedResult) {
+
+ }
+
+ @Override
+ protected void onCancelled(SpeedResult[] speedResults) {
+ mCancel = true;
+ }
+ }
+
+
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
index ea003d41..70c7455a 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
@@ -18,6 +18,13 @@ public class NativeUtils {
public static native String getNativeAPI();
+
+ public final static int[] openSSLlengths = {
+ 16, 64, 256, 1024, 8 * 1024, 16 * 1024
+ };
+
+ public static native double[] getOpenSSLSpeed(String algorithm, int testnum);
+
static {
System.loadLibrary("opvpnutil");
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN)
diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java b/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java
index 700095d7..ef49c656 100644
--- a/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java
+++ b/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java
@@ -12,6 +12,7 @@ import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -28,6 +29,7 @@ import android.preference.PreferenceManager;
import de.blinkt.openvpn.BuildConfig;
import de.blinkt.openvpn.R;
import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.activities.OpenSSLSpeed;
import de.blinkt.openvpn.api.ExternalAppDatabase;
import de.blinkt.openvpn.core.ProfileManager;
@@ -66,6 +68,7 @@ public class GeneralSettings extends PreferenceFragment implements OnPreferenceC
Preference clearapi = findPreference("clearapi");
clearapi.setOnPreferenceClickListener(this);
+ findPreference("osslspeed").setOnPreferenceClickListener(this);
if(devHacks.getPreferenceCount()==0)
getPreferenceScreen().removePreference(devHacks);
@@ -168,6 +171,8 @@ public class GeneralSettings extends PreferenceFragment implements OnPreferenceC
builder.setNegativeButton(android.R.string.cancel, null);
builder.setMessage(getString(R.string.clearappsdialog,getExtAppList("\n")));
builder.show();
+ } else if (preference.getKey().equals("osslspeed")) {
+ startActivity(new Intent(getActivity(), OpenSSLSpeed.class));
}
return true;
diff --git a/main/src/main/res/layout/openssl_speed.xml b/main/src/main/res/layout/openssl_speed.xml
new file mode 100644
index 00000000..c23d3567
--- /dev/null
+++ b/main/src/main/res/layout/openssl_speed.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (c) 2012-2017 Arne Schwabe
+ ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+
+
+ <EditText
+ android:id="@+id/ciphername"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:ems="10"
+ android:text="@string/default_cipherlist_test"
+ android:hint="@string/openssl_cipher_name"
+ android:inputType="textPersonName" />
+
+ <Button
+ android:id="@+id/testSpecific"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/test_algoirhtms" />
+ </LinearLayout>
+
+ <ListView
+ android:id="@+id/results"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
diff --git a/main/src/main/res/layout/speedviewitem.xml b/main/src/main/res/layout/speedviewitem.xml
new file mode 100644
index 00000000..06a760ec
--- /dev/null
+++ b/main/src/main/res/layout/speedviewitem.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (c) 2012-2017 Arne Schwabe
+ ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
+ -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/ciphername"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="end"
+ android:minWidth="100sp"
+ android:textAlignment="textEnd"
+ tools:text="aes-256-gcm" />
+
+ <TextView
+ android:id="@+id/blocksize"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/ciphername"
+ android:gravity="end"
+ android:minWidth="100sp"
+ android:textAlignment="textEnd"
+ tools:text="1024 kB" />
+
+
+ <TextView
+ android:id="@+id/blocksintime"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20sp"
+ android:layout_marginStart="20sp"
+ android:layout_toEndOf="@id/ciphername"
+ android:layout_toRightOf="@id/ciphername"
+ tools:text="12345 blocks in 5s" />
+
+ <TextView
+ android:id="@+id/speed"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/blocksintime"
+ android:layout_marginLeft="20dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginTop="2sp"
+ android:layout_toEndOf="@id/ciphername"
+ android:layout_toRightOf="@id/ciphername"
+ tools:text="772 MB/s" />
+
+
+</RelativeLayout>
diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml
index 79c84223..67248dae 100755
--- a/main/src/main/res/values/strings.xml
+++ b/main/src/main/res/values/strings.xml
@@ -446,5 +446,13 @@
<string name="channel_name_status">Connection status change</string>
<string name="channel_description_status">Status changes of the OpenVPN connection (Connecting, authenticating,…)</string>
<string name="weakmd_title">Weak (MD5) hashes in certificate signature (SSL_CTX_use_certificate md too weak)</string>
+ <string name="title_activity_open_sslspeed">OpenSSL Speed Test</string>
+ <string name="testcommon">Test commonly used algorithms</string>
+ <string name="testspecific">Test common algorithm</string>
+ <string name="openssl_cipher_name">OpenSSL cipher names</string>
+ <string name="osslspeedtest">OpenSSL Crypto Speed test</string>
+ <string name="openssl_error">OpenSSL returned an error</string>
+ <string name="running_test">Running test…</string>
+ <string name="test_algoirhtms">Test selected algorithms</string>
</resources>
diff --git a/main/src/main/res/values/untranslatable.xml b/main/src/main/res/values/untranslatable.xml
index 8e6f2c75..f8f0cc96 100644
--- a/main/src/main/res/values/untranslatable.xml
+++ b/main/src/main/res/values/untranslatable.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2012-2016 Arne Schwabe
~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
-->
@@ -43,11 +42,12 @@
<item>-1</item>
</string-array>
<string name="crash_toast_text">OpenVPN for Android crashed, crash reported</string>
-
+
<!-- These strings should not be visible to the user -->
<string name="state_user_vpn_permission" translatable="false">Waiting for user permission to use VPN API</string>
<string name="state_user_vpn_password" translatable="false">Waiting for user VPN password</string>
<string name="state_user_vpn_password_cancelled" translatable="false">VPN password input dialog cancelled</string>
<string name="state_user_vpn_permission_cancelled" translatable="false">VPN API permission dialog cancelled</string>
+ <string name="default_cipherlist_test" translatable="false">aes-256-gcm bf-cbc sha1</string>
</resources>
diff --git a/main/src/main/res/xml/general_settings.xml b/main/src/main/res/xml/general_settings.xml
index f53e6d5b..3b8ba4f5 100644
--- a/main/src/main/res/xml/general_settings.xml
+++ b/main/src/main/res/xml/general_settings.xml
@@ -59,6 +59,10 @@
android:summary="@string/screenoff_summary"
android:title="@string/screenoff_title"/>
+ <Preference
+ android:key="osslspeed"
+ android:persistent="false"
+ android:title="@string/osslspeedtest" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/device_specific" android:key="device_hacks">