From 3512dd8de571c8183a7e7476db30a928573d8442 Mon Sep 17 00:00:00 2001
From: Arne Schwabe <arne@rfc2549.org>
Date: Tue, 1 May 2012 15:33:00 +0200
Subject: Support strange certificate + passsword authentication types

---
 AndroidManifest.xml                         |  4 +-
 openvpn/Makefile.am                         |  1 +
 openvpn/README.polarssl                     |  4 +-
 openvpn/config.h                            |  6 +-
 openvpn/configure.ac                        | 38 ++++++++-----
 openvpn/doc/openvpn.8                       | 14 +++++
 openvpn/include/openvpn-plugin.h            |  8 +++
 openvpn/src/compat/Makefile.am              |  1 +
 openvpn/src/openvpn/basic.h                 | 13 -----
 openvpn/src/openvpn/crypto_polarssl.c       | 67 ++++++++++++++++++-----
 openvpn/src/openvpn/crypto_polarssl.h       | 21 +++++++
 openvpn/src/openvpn/init.c                  |  8 ++-
 openvpn/src/openvpn/jniglue.c               |  7 ---
 openvpn/src/openvpn/manage.c                | 11 ++--
 openvpn/src/openvpn/options.c               | 31 +++++++++--
 openvpn/src/openvpn/options.h               |  3 +
 openvpn/src/openvpn/packet_id.c             | 16 ++++--
 openvpn/src/openvpn/ssl.c                   |  5 ++
 openvpn/src/openvpn/ssl_backend.h           | 10 ++++
 openvpn/src/openvpn/ssl_polarssl.c          | 38 +++++++++----
 openvpn/src/openvpn/ssl_polarssl.h          |  2 -
 openvpn/src/openvpn/syshead.h               |  6 ++
 openvpn/src/openvpn/tun.c                   | 24 +-------
 openvpn/src/openvpnserv/openvpnserv.c       |  6 +-
 res/values/arrays.xml                       |  5 +-
 res/values/strings.xml                      |  1 +
 src/de/blinkt/openvpn/LaunchVPN.java        |  8 ++-
 src/de/blinkt/openvpn/Settings_Basic.java   |  8 +++
 src/de/blinkt/openvpn/Settings_Obscure.java |  2 +
 src/de/blinkt/openvpn/VpnProfile.java       | 85 ++++++++++++++++++++---------
 todo.txt                                    |  1 +
 31 files changed, 312 insertions(+), 142 deletions(-)
 create mode 100644 todo.txt

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5b4bdef8..fe250a8e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -17,8 +17,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="de.blinkt.openvpn"
-    android:versionCode="14"
-    android:versionName="0.4.6" >
+    android:versionCode="15"
+    android:versionName="0.4.7" >
 
     <uses-permission android:name="android.permission.INTERNET" />
 
diff --git a/openvpn/Makefile.am b/openvpn/Makefile.am
index 68aa0a87..ab3e3d2e 100644
--- a/openvpn/Makefile.am
+++ b/openvpn/Makefile.am
@@ -52,6 +52,7 @@ dist_doc_DATA = \
 
 dist_noinst_DATA = \
 	.gitignore \
+	.gitattributes \
 	PORTS \
 	README.IPv6 TODO.IPv6 \
 	README.polarssl \
diff --git a/openvpn/README.polarssl b/openvpn/README.polarssl
index 77a95750..ab7c2d78 100644
--- a/openvpn/README.polarssl
+++ b/openvpn/README.polarssl
@@ -3,11 +3,11 @@ instructions:
 
 To Build and Install,
 
-	./configure --with-ssl-type=polarssl
+	./configure --with-crypto-library=polarssl
 	make
 	make install
 
-This version depends on at least PolarSSL v0.99.
+This version depends on at least PolarSSL v1.1.
 
 *************************************************************************
 
diff --git a/openvpn/config.h b/openvpn/config.h
index 3e713081..3dfeffc2 100644
--- a/openvpn/config.h
+++ b/openvpn/config.h
@@ -450,13 +450,13 @@
 #define PACKAGE_NAME "OpenVPN"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "OpenVPN 2.1.4"
+#define PACKAGE_STRING "OpenVPN 2.3_alpha1"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "openvpn"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "2.1.4"
+#define PACKAGE_VERSION "2.3_alpha1"
 
 /* Define to the necessary symbol if this constant uses a non-standard name on
    your system. */
@@ -490,7 +490,7 @@
 #define TAP_WIN32_MIN_MINOR 1
 
 /* A string representing our target */
-#define TARGET_ALIAS "i686-pc-linux-gnu"
+#define TARGET_ALIAS "arm-linux-androideabi"
 
 /* Are we running on Mac OS X? */
 /* #undef TARGET_DARWIN */
diff --git a/openvpn/configure.ac b/openvpn/configure.ac
index e962323f..399b4e78 100644
--- a/openvpn/configure.ac
+++ b/openvpn/configure.ac
@@ -168,6 +168,7 @@ AC_ARG_ENABLE(
 AC_ARG_ENABLE(
 	[password-save],
 	[AS_HELP_STRING([--enable-password-save], [allow --askpass and --auth-user-pass passwords to be read from a file @<:@default=yes@:>@])],
+	,
 	[enable_password_save="no"]
 )
 
@@ -354,7 +355,7 @@ AX_EMPTY_ARRAY
 AC_CHECK_SIZEOF([unsigned int])
 AC_CHECK_SIZEOF([unsigned long])
 AC_CHECK_HEADERS([ \
-	stdio.h stdarg.h limits.h \
+	stdio.h stdarg.h stdbool.h limits.h \
 	time.h errno.h fcntl.h io.h direct.h \
 	ctype.h sys/types.h sys/socket.h \
 	signal.h unistd.h dlfcn.h \
@@ -363,7 +364,7 @@ AC_CHECK_HEADERS([ \
 	windows.h winsock2.h ws2tcpip.h \
 ])
 AC_CHECK_HEADERS([ \
-	sys/time.h sys/un.h sys/ioctl.h sys/stat.h \
+	sys/time.h sys/ioctl.h sys/stat.h \
 	sys/mman.h sys/file.h \
 	unistd.h signal.h libgen.h stropts.h \
 	syslog.h pwd.h grp.h \
@@ -396,10 +397,13 @@ SOCKET_INCLUDES="
 #ifdef HAVE_NETINET_IN_SYSTM_H
 #include <netinet/in_systm.h>
 #endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
 "
 
 AC_CHECK_HEADERS(
-	[net/if.h netinet/ip.h netinet/if_ether.h resolv.h],
+	[net/if.h netinet/ip.h netinet/if_ether.h resolv.h sys/un.h],
 	,
 	,
 	[[${SOCKET_INCLUDES}]]
@@ -411,39 +415,33 @@ AC_CHECK_TYPES(
 	[AC_DEFINE([in_addr_t], [uint32_t], [Workaround missing in_addr_t])],
 	[[${SOCKET_INCLUDES}]]
 )
-AC_CHECK_TYPE(
-	[struct tun_pi],
-	[AC_DEFINE(HAVE_TUN_PI, 1, [struct tun_pi needed for IPv6 support])],
-	,
-	[[${SOCKET_INCLUDES}]]
-)
 AC_CHECK_TYPE(
 	[struct iphdr],
-	[AC_DEFINE(HAVE_IPHDR, 1, [struct iphdr needed for IPv6 support])],
+	[AC_DEFINE([HAVE_IPHDR], [1], [struct iphdr needed for IPv6 support])],
 	,
 	[[${SOCKET_INCLUDES}]]
 )
 AC_CHECK_TYPE(
 	[struct sock_extended_err],
-	[AC_DEFINE(HAVE_SOCK_EXTENDED_ERR, 1, [struct sock_extended_err needed for extended socket error support])],
+	[AC_DEFINE([HAVE_SOCK_EXTENDED_ERR], [1], [struct sock_extended_err needed for extended socket error support])],
 	,
 	[[${SOCKET_INCLUDES}]]
 )
 AC_CHECK_TYPE(
 	[struct msghdr],
-	[AC_DEFINE(HAVE_MSGHDR, 1, [struct msghdr needed for extended socket error support])],
+	[AC_DEFINE([HAVE_MSGHDR], [1], [struct msghdr needed for extended socket error support])],
 	,
 	[[${SOCKET_INCLUDES}]]
 )
 AC_CHECK_TYPE(
 	[struct cmsghdr],
-	[AC_DEFINE(HAVE_CMSGHDR, 1, [struct cmsghdr needed for extended socket error support])],
+	[AC_DEFINE([HAVE_CMSGHDR], [1], [struct cmsghdr needed for extended socket error support])],
 	,
 	[[${SOCKET_INCLUDES}]]
 )
 AC_CHECK_TYPE(
 	[struct in_pktinfo],
-	[AC_DEFINE(HAVE_IN_PKTINFO, 1, [struct in_pktinfo needed for IP_PKTINFO support])],
+	[AC_DEFINE([HAVE_IN_PKTINFO], [1], [struct in_pktinfo needed for IP_PKTINFO support])],
 	,
 	[[${SOCKET_INCLUDES}]]
 )
@@ -595,6 +593,16 @@ AC_CHECK_HEADERS(
 	],
 	[have_tap_header="yes"]
 )
+AC_CHECK_DECLS(
+	[TUNSETPERSIST],
+	[AC_DEFINE([ENABLE_FEATURE_TUN_PERSIST], [1], [We have persist tun capability])],
+	,
+	[[
+		#ifdef HAVE_LINUX_IF_TUN_H
+		#include <linux/if_tun.h>
+		#endif
+	]]
+)
 CFLAGS="${old_CFLAGS}"
 test "${have_tap_header}" = "yes" || AC_MSG_ERROR([no tap header could be found])
 
@@ -821,7 +829,7 @@ case "${with_crypto_library}" in
 	polarssl)
 		have_crypto_crypto="${have_polarssl_crypto}"
 		have_crypto_ssl="${have_polarssl_ssl}"
-		CRYPTO_CRYPTO_CFLAGS="${POLARSSL_CRYPTO_CFLAGS}"
+		CRYPTO_CRYPTO_CFLAGS="${POLARSSL_CFLAGS}"
 		CRYPTO_CRYPTO_LIBS="${POLARSSL_LIBS}"
 		AC_DEFINE([ENABLE_CRYPTO_POLARSSL], [1], [Use PolarSSL library])
 		;;
diff --git a/openvpn/doc/openvpn.8 b/openvpn/doc/openvpn.8
index 53d6bdb2..ee46de62 100644
--- a/openvpn/doc/openvpn.8
+++ b/openvpn/doc/openvpn.8
@@ -3846,6 +3846,20 @@ space-saving optimization that uses the unique identifier for
 datagram replay protection as the IV.
 .\"*********************************************************
 .TP
+.B \-\-use-prediction-resistance
+Enable prediction resistance on PolarSSL's RNG.
+
+Enabling prediction resistance causes the RNG to reseed in each
+call for random. Reseeding this often can quickly deplete the kernel
+entropy pool.
+
+If you need this option, please consider running a daemon that adds
+entropy to the kernel pool.
+
+Note that this option only works with PolarSSL versions greater
+than 1.1.
+.\"*********************************************************
+.TP
 .B \-\-test-crypto
 Do a self-test of OpenVPN's crypto options by encrypting and
 decrypting test packets using the data channel encryption options
diff --git a/openvpn/include/openvpn-plugin.h b/openvpn/include/openvpn-plugin.h
index f82f61fa..1c80eec3 100644
--- a/openvpn/include/openvpn-plugin.h
+++ b/openvpn/include/openvpn-plugin.h
@@ -43,6 +43,10 @@ typedef X509 openvpn_x509_cert_t;
 #endif
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Plug-in types.  These types correspond to the set of script callbacks
  * supported by OpenVPN.
@@ -724,4 +728,8 @@ OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_op
 OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v1)
      (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* OPENVPN_PLUGIN_H_ */
diff --git a/openvpn/src/compat/Makefile.am b/openvpn/src/compat/Makefile.am
index 5ee35f72..7ad44525 100644
--- a/openvpn/src/compat/Makefile.am
+++ b/openvpn/src/compat/Makefile.am
@@ -20,6 +20,7 @@ noinst_LTLIBRARIES = libcompat.la
 
 libcompat_la_SOURCES = \
 	compat.h \
+	compat-stdbool.h \
 	compat-dirname.c \
 	compat-basename.c \
 	compat-gettimeofday.c \
diff --git a/openvpn/src/openvpn/basic.h b/openvpn/src/openvpn/basic.h
index 7c13e221..298cf103 100644
--- a/openvpn/src/openvpn/basic.h
+++ b/openvpn/src/openvpn/basic.h
@@ -25,19 +25,6 @@
 #ifndef BASIC_H
 #define BASIC_H
 
-/* bool definitions */
-#ifndef bool
-#define bool int
-#endif
-
-#ifndef true
-#define true 1
-#endif
-
-#ifndef false
-#define false 0
-#endif
-
 #define BOOL_CAST(x) ((x) ? (true) : (false))
 
 /* size of an array */
diff --git a/openvpn/src/openvpn/crypto_polarssl.c b/openvpn/src/openvpn/crypto_polarssl.c
index 0e6728c8..3978a3c6 100644
--- a/openvpn/src/openvpn/crypto_polarssl.c
+++ b/openvpn/src/openvpn/crypto_polarssl.c
@@ -42,12 +42,16 @@
 #include "buffer.h"
 #include "integer.h"
 #include "crypto_backend.h"
+#include "otime.h"
+#include "misc.h"
 
 #include <polarssl/des.h>
 #include <polarssl/md5.h>
 #include <polarssl/cipher.h>
 #include <polarssl/havege.h>
 
+#include <polarssl/entropy.h>
+
 /*
  *
  * Hardware engine support. Allows loading/unloading of engines.
@@ -149,7 +153,6 @@ show_available_engines ()
       "available\n");
 }
 
-
 /*
  *
  * Random number functions, used in cases where we want
@@ -159,29 +162,65 @@ show_available_engines ()
  *
  */
 
-int
-rand_bytes (uint8_t *output, int len)
+/*
+ * Initialise the given ctr_drbg context, using a personalisation string and an
+ * entropy gathering function.
+ */
+ctr_drbg_context * rand_ctx_get()
 {
-  static havege_state hs = {0};
-  static bool hs_initialised = false;
-  const int int_size = sizeof(int);
+  static entropy_context ec = {0};
+  static ctr_drbg_context cd_ctx = {0};
+  static bool rand_initialised = false;
 
-  if (!hs_initialised)
+  if (!rand_initialised)
     {
-      /* Initialise PolarSSL RNG */
-      havege_init(&hs);
-      hs_initialised = true;
-    }
+      struct gc_arena gc = gc_new();
+      struct buffer pers_string = alloc_buf_gc(100, &gc);
+
+      /*
+       * Personalisation string, should be as unique as possible (see NIST
+       * 800-90 section 8.7.1). We have very little information at this stage.
+       * Include Program Name, memory address of the context and PID.
+       */
+      buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc));
+
+      /* Initialise PolarSSL RNG, and built-in entropy sources */
+      entropy_init(&ec);
+
+      if (0 != ctr_drbg_init(&cd_ctx, entropy_func, &ec, BPTR(&pers_string), BLEN(&pers_string)))
+        msg (M_FATAL, "Failed to initialize random generator");
+
+      gc_free(&gc);
+      rand_initialised = true;
+  }
+
+  return &cd_ctx;
+}
+
+#ifdef ENABLE_PREDICTION_RESISTANCE
+void rand_ctx_enable_prediction_resistance()
+{
+  ctr_drbg_context *cd_ctx = rand_ctx_get();
+
+  ctr_drbg_set_prediction_resistance(cd_ctx, 1);
+}
+#endif /* ENABLE_PREDICTION_RESISTANCE */
+
+int
+rand_bytes (uint8_t *output, int len)
+{
+  ctr_drbg_context *rng_ctx = rand_ctx_get();
 
   while (len > 0)
     {
-      const int blen 	= min_int (len, int_size);
-      const int rand_int 	= havege_rand(&hs);
+      const size_t blen = min_int (len, CTR_DRBG_MAX_REQUEST);
+      if (0 != ctr_drbg_random(rng_ctx, output, blen))
+	return 0;
 
-      memcpy (output, &rand_int, blen);
       output += blen;
       len -= blen;
     }
+
   return 1;
 }
 
diff --git a/openvpn/src/openvpn/crypto_polarssl.h b/openvpn/src/openvpn/crypto_polarssl.h
index 358483a9..bfabb91b 100644
--- a/openvpn/src/openvpn/crypto_polarssl.h
+++ b/openvpn/src/openvpn/crypto_polarssl.h
@@ -30,8 +30,10 @@
 #ifndef CRYPTO_POLARSSL_H_
 #define CRYPTO_POLARSSL_H_
 
+#include <polarssl/version.h>
 #include <polarssl/cipher.h>
 #include <polarssl/md.h>
+#include <polarssl/ctr_drbg.h>
 
 /** Generic cipher key type %context. */
 typedef cipher_info_t cipher_kt_t;
@@ -71,4 +73,23 @@ typedef md_context_t hmac_ctx_t;
 #define SHA_DIGEST_LENGTH 	20
 #define DES_KEY_LENGTH 8
 
+/**
+ * Returns a singleton instance of the PolarSSL random number generator.
+ *
+ * For PolarSSL 1.1+, this is the CTR_DRBG random number generator. If it
+ * hasn't been initialised yet, the RNG will be initialised using the default
+ * entropy sources. Aside from the default platform entropy sources, an
+ * additional entropy source, the HAVEGE random number generator will also be
+ * added. During initialisation, a personalisation string will be added based
+ * on the time, the PID, and a pointer to the random context.
+ */
+ctr_drbg_context * rand_ctx_get();
+
+#ifdef ENABLE_PREDICTION_RESISTANCE
+/**
+ * Enable prediction resistance on the random number generator.
+ */
+void rand_ctx_enable_prediction_resistance();
+#endif
+
 #endif /* CRYPTO_POLARSSL_H_ */
diff --git a/openvpn/src/openvpn/init.c b/openvpn/src/openvpn/init.c
index 88d621a4..cc94b818 100644
--- a/openvpn/src/openvpn/init.c
+++ b/openvpn/src/openvpn/init.c
@@ -954,7 +954,7 @@ do_genkey (const struct options * options)
 bool
 do_persist_tuntap (const struct options *options)
 {
-#ifdef TUNSETPERSIST
+#ifdef ENABLE_FEATURE_TUN_PERSIST
   if (options->persist_config)
     {
       /* sanity check on options for --mktun or --rmtun */
@@ -2016,6 +2016,12 @@ init_crypto_pre (struct context *c, const unsigned int flags)
 
   if (c->options.mute_replay_warnings)
     c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS;
+
+#ifdef ENABLE_PREDICTION_RESISTANCE
+  if (c->options.use_prediction_resistance)
+    rand_ctx_enable_prediction_resistance();
+#endif
+
 }
 
 /*
diff --git a/openvpn/src/openvpn/jniglue.c b/openvpn/src/openvpn/jniglue.c
index 686092bc..c0fff12b 100644
--- a/openvpn/src/openvpn/jniglue.c
+++ b/openvpn/src/openvpn/jniglue.c
@@ -129,13 +129,6 @@ void android_openvpn_log(int level,const char* prefix,const char* prefix_sep,con
     
 }
 
-
-unsigned char android_protect_socket(int sockfd) {
-    jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "protectSocket", 
-                                                            "(I)Z");
-    return (*openvpnjenv)->CallStaticBooleanMethod(openvpnjenv,openvpnclass,aMethodID,sockfd);
-
-}
 int android_open_tun () {
     jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "openTunDevice", 
                                                             "()I");
diff --git a/openvpn/src/openvpn/manage.c b/openvpn/src/openvpn/manage.c
index 1a6c0869..1dddd41d 100644
--- a/openvpn/src/openvpn/manage.c
+++ b/openvpn/src/openvpn/manage.c
@@ -1479,14 +1479,13 @@ man_new_connection_post (struct management *man, const char *description)
 #if UNIX_SOCK_SUPPORT
   if (man->settings.flags & MF_UNIX_SOCK)
     {
-        msg (D_MANAGEMENT, "MANAGEMENT(unix): %s %s",
-             description,
-             sockaddr_unix_name (&man->settings.local_unix, "NULL"));
- 
+      msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
+	   description,
+	   sockaddr_unix_name (&man->settings.local_unix, "NULL"));
     }
   else
 #endif
-    msg (D_MANAGEMENT, "MANAGEMENT(tcp): %s %s",
+    msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
 	 description,
 	 print_sockaddr (&man->settings.local, &gc));
 
@@ -2691,7 +2690,6 @@ management_socket_set (struct management *man,
 void
 management_io (struct management *man)
 {
-    msg(D_MANAGEMENT,"M I/O State %d in",man->connection.state);
   switch (man->connection.state)
     {
     case MS_LISTEN:
@@ -2708,7 +2706,6 @@ management_io (struct management *man)
     default:
       ASSERT (0);
     }
-    msg(D_MANAGEMENT,"M I/O State %d out",man->connection.state);
 }
 
 #endif
diff --git a/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c
index b74e559b..c48d7be9 100644
--- a/openvpn/src/openvpn/options.c
+++ b/openvpn/src/openvpn/options.c
@@ -545,6 +545,10 @@ static const char usage_message[] =
   "                  using file.\n"
   "--test-crypto   : Run a self-test of crypto features enabled.\n"
   "                  For debugging only.\n"
+#ifdef ENABLE_PREDICTION_RESISTANCE
+  "--use-prediction-resistance: Enable prediction resistance on the random\n"
+  "                             number generator.\n"
+#endif
 #ifdef ENABLE_SSL
   "\n"
   "TLS Key Negotiation Options:\n"
@@ -560,7 +564,6 @@ static const char usage_message[] =
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
   " and CRLs).\n"
 #else /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
-#error WTF!
   ").\n"
   "                  WARNING: no support of CRL available with this version.\n"
 #endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */
@@ -726,7 +729,7 @@ static const char usage_message[] =
   "                  for use with the --secret option.\n"
   "--secret file   : Write key to file.\n"
 #endif				/* ENABLE_CRYPTO */
-#ifdef TUNSETPERSIST
+#ifdef ENABLE_FEATURE_TUN_PERSIST
   "\n"
   "Tun/tap config mode (available with linux 2.4+):\n"
   "--mktun         : Create a persistent tunnel.\n"
@@ -792,7 +795,7 @@ init_options (struct options *o, const bool init_gc)
   o->management_echo_buffer_size = 100;
   o->management_state_buffer_size = 100;
 #endif
-#ifdef TUNSETPERSIST
+#ifdef ENABLE_FEATURE_TUN_PERSIST
   o->persist_mode = 1;
 #endif
 #ifndef WIN32
@@ -838,6 +841,9 @@ init_options (struct options *o, const bool init_gc)
   o->replay_time = DEFAULT_TIME_BACKTRACK;
   o->use_iv = true;
   o->key_direction = KEY_DIRECTION_BIDIRECTIONAL;
+#ifdef ENABLE_PREDICTION_RESISTANCE
+  o->use_prediction_resistance = false;
+#endif
 #ifdef ENABLE_SSL
   o->key_method = 2;
   o->tls_timeout = 2;
@@ -1423,7 +1429,7 @@ show_settings (const struct options *o)
   
   SHOW_INT (mode);
 
-#ifdef TUNSETPERSIST
+#ifdef ENABLE_FEATURE_TUN_PERSIST
   SHOW_BOOL (persist_config);
   SHOW_INT (persist_mode);
 #endif
@@ -1584,6 +1590,9 @@ show_settings (const struct options *o)
   SHOW_STR (packet_id_file);
   SHOW_BOOL (use_iv);
   SHOW_BOOL (test_crypto);
+#ifdef ENABLE_PREDICTION_RESISTANCE
+  SHOW_BOOL (use_prediction_resistance);
+#endif
 
 #ifdef ENABLE_SSL
   SHOW_BOOL (tls_server);
@@ -3021,6 +3030,11 @@ options_string (const struct options *o,
 	  buf_printf (&out, ",no-replay");
 	if (!o->use_iv)
 	  buf_printf (&out, ",no-iv");
+
+#ifdef ENABLE_PREDICTION_RESISTANCE
+        if (o->use_prediction_resistance)
+          buf_printf (&out, ",use-prediction-resistance");
+#endif
       }
 
 #ifdef ENABLE_SSL
@@ -6423,6 +6437,13 @@ add_option (struct options *options,
       options->keysize = keysize;
     }
 #endif
+#ifdef ENABLE_PREDICTION_RESISTANCE
+  else if (streq (p[0], "use-prediction-resistance"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->use_prediction_resistance = true;
+    }
+#endif
 #ifdef ENABLE_SSL
   else if (streq (p[0], "show-tls"))
     {
@@ -6795,7 +6816,7 @@ add_option (struct options *options,
       options->pkcs11_id_management = true;
     }
 #endif
-#ifdef TUNSETPERSIST
+#ifdef ENABLE_FEATURE_TUN_PERSIST
   else if (streq (p[0], "rmtun"))
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
diff --git a/openvpn/src/openvpn/options.h b/openvpn/src/openvpn/options.h
index 9e78d00b..1be3dfaf 100644
--- a/openvpn/src/openvpn/options.h
+++ b/openvpn/src/openvpn/options.h
@@ -520,6 +520,9 @@ struct options
   const char *packet_id_file;
   bool use_iv;
   bool test_crypto;
+#ifdef ENABLE_PREDICTION_RESISTANCE
+  bool use_prediction_resistance;
+#endif
 
 #ifdef ENABLE_SSL
   /* TLS (control channel) parms */
diff --git a/openvpn/src/openvpn/packet_id.c b/openvpn/src/openvpn/packet_id.c
index 0102129f..baa49664 100644
--- a/openvpn/src/openvpn/packet_id.c
+++ b/openvpn/src/openvpn/packet_id.c
@@ -501,7 +501,7 @@ packet_id_debug_print (int msglevel,
 
   buf_printf (&out, "%s [%d]", message, value);
   buf_printf (&out, " [%s-%d] [", p->name, p->unit);
-  for (i = 0; i < sl->x_size; ++i)
+  for (i = 0; sl != NULL && i < sl->x_size; ++i)
     {
       char c;
       time_t v;
@@ -538,11 +538,15 @@ packet_id_debug_print (int msglevel,
 	      p->time_backtrack,
 	      p->max_backtrack_stat,
 	      (int)p->initialized);
-  buf_printf (&out, " sl=[%d,%d,%d,%d]",
-	      sl->x_head,
-	      sl->x_size,
-	      sl->x_cap,
-	      sl->x_sizeof);
+  if (sl != NULL)
+    {
+	  buf_printf (&out, " sl=[%d,%d,%d,%d]",
+		      sl->x_head,
+		      sl->x_size,
+		      sl->x_cap,
+		      sl->x_sizeof);
+    }
+
 
   msg (msglevel, "%s", BSTR(&out));
   gc_free (&gc);
diff --git a/openvpn/src/openvpn/ssl.c b/openvpn/src/openvpn/ssl.c
index 537fc12f..9f570b9d 100644
--- a/openvpn/src/openvpn/ssl.c
+++ b/openvpn/src/openvpn/ssl.c
@@ -391,6 +391,11 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
       tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);
     }
 
+#ifdef ENABLE_CRYPTO_POLARSSL
+  /* Personalise the random by mixing in the certificate */
+  tls_ctx_personalise_random (new_ctx);
+#endif
+
   tls_clear_error ();
   return;
 
diff --git a/openvpn/src/openvpn/ssl_backend.h b/openvpn/src/openvpn/ssl_backend.h
index 5ea6a06b..f3e69dd3 100644
--- a/openvpn/src/openvpn/ssl_backend.h
+++ b/openvpn/src/openvpn/ssl_backend.h
@@ -272,6 +272,16 @@ void tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs
 #endif
     );
 
+#ifdef ENABLE_CRYPTO_POLARSSL
+/**
+ * Add a personalisation string to the PolarSSL RNG, based on the certificate
+ * loaded into the given context.
+ *
+ * @param ctx			TLS context to use
+ */
+void tls_ctx_personalise_random(struct tls_root_ctx *ctx);
+#endif
+
 /* **************************************
  *
  * Key-state specific functions
diff --git a/openvpn/src/openvpn/ssl_polarssl.c b/openvpn/src/openvpn/ssl_polarssl.c
index d4d85c8e..fc8fa6e9 100644
--- a/openvpn/src/openvpn/ssl_polarssl.c
+++ b/openvpn/src/openvpn/ssl_polarssl.c
@@ -44,6 +44,9 @@
 #include "manage.h"
 #include "ssl_common.h"
 
+#include <polarssl/sha2.h>
+#include <polarssl/havege.h>
+
 #include "ssl_verify_polarssl.h"
 #include <polarssl/pem.h>
 
@@ -85,9 +88,6 @@ tls_ctx_server_new(struct tls_root_ctx *ctx)
   ASSERT(NULL != ctx);
   CLEAR(*ctx);
 
-  ALLOC_OBJ_CLEAR(ctx->hs, havege_state);
-  havege_init(ctx->hs);
-
   ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context);
   ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context);
 
@@ -103,12 +103,8 @@ void
 tls_ctx_client_new(struct tls_root_ctx *ctx)
 {
   ASSERT(NULL != ctx);
-
   CLEAR(*ctx);
 
-  ALLOC_OBJ_CLEAR(ctx->hs, havege_state);
-  havege_init(ctx->hs);
-
   ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context);
   ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context);
 
@@ -143,8 +139,6 @@ tls_ctx_free(struct tls_root_ctx *ctx)
       }
 #endif
 
-      free(ctx->hs);
-
       if (ctx->allowed_ciphers)
 	free(ctx->allowed_ciphers);
 
@@ -504,6 +498,28 @@ static void my_debug( void *ctx, int level, const char *str )
     }
 }
 
+/*
+ * Further personalise the RNG using a hash of the public key
+ */
+void tls_ctx_personalise_random(struct tls_root_ctx *ctx)
+{
+  static char old_sha256_hash[32] = {0};
+  char sha256_hash[32] = {0};
+  ctr_drbg_context *cd_ctx = rand_ctx_get();
+
+  if (NULL != ctx->crt_chain)
+    {
+      x509_cert *cert = ctx->crt_chain;
+
+      sha2(cert->tbs.p, cert->tbs.len, sha256_hash, false);
+      if ( 0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash)))
+	{
+	  ctr_drbg_update(cd_ctx, sha256_hash, 32);
+	  memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash));
+	}
+    }
+}
+
 void key_state_ssl_init(struct key_state_ssl *ks_ssl,
     const struct tls_root_ctx *ssl_ctx, bool is_server, void *session)
 {
@@ -517,7 +533,9 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
       /* Initialise SSL context */
       ssl_set_dbg (ks_ssl->ctx, my_debug, NULL);
       ssl_set_endpoint (ks_ssl->ctx, ssl_ctx->endpoint);
-      ssl_set_rng (ks_ssl->ctx, havege_rand, ssl_ctx->hs);
+
+      ssl_set_rng (ks_ssl->ctx, ctr_drbg_random, rand_ctx_get());
+
       ALLOC_OBJ_CLEAR (ks_ssl->ssn, ssl_session);
       ssl_set_session (ks_ssl->ctx, 0, 0, ks_ssl->ssn );
       if (ssl_ctx->allowed_ciphers)
diff --git a/openvpn/src/openvpn/ssl_polarssl.h b/openvpn/src/openvpn/ssl_polarssl.h
index e6149b60..2b02a6fd 100644
--- a/openvpn/src/openvpn/ssl_polarssl.h
+++ b/openvpn/src/openvpn/ssl_polarssl.h
@@ -30,7 +30,6 @@
 #ifndef SSL_POLARSSL_H_
 #define SSL_POLARSSL_H_
 
-#include <polarssl/havege.h>
 #include <polarssl/ssl.h>
 #include "config.h"
 
@@ -63,7 +62,6 @@ struct tls_root_ctx {
 
     int endpoint; 		/**< Whether or not this is a server or a client */
 
-    havege_state *hs;		/**< HAVEGE random number state */
     dhm_context *dhm_ctx;	/**< Diffie-Helmann-Merkle context */
     x509_cert *crt_chain;	/**< Local Certificate chain */
     x509_cert *ca_chain;	/**< CA chain for remote verification */
diff --git a/openvpn/src/openvpn/syshead.h b/openvpn/src/openvpn/syshead.h
index 56a54290..8ce40f7e 100644
--- a/openvpn/src/openvpn/syshead.h
+++ b/openvpn/src/openvpn/syshead.h
@@ -26,6 +26,7 @@
 #define SYSHEAD_H
 
 #include "compat.h"
+#include "compat-stdbool.h"
 
 /* branch prediction hints */
 #if defined(__GNUC__)
@@ -538,6 +539,11 @@ socket_defined (const socket_descriptor_t sd)
 #define MANAGMENT_EXTERNAL_KEY
 #endif
 
+/* Enable PolarSSL RNG prediction resistance support */
+#ifdef ENABLE_CRYPTO_POLARSSL
+#define ENABLE_PREDICTION_RESISTANCE
+#endif /* ENABLE_CRYPTO_POLARSSL */
+
 /*
  * MANAGEMENT_IN_EXTRA allows the management interface to
  * read multi-line inputs from clients.
diff --git a/openvpn/src/openvpn/tun.c b/openvpn/src/openvpn/tun.c
index ae372e48..7aa8627d 100644
--- a/openvpn/src/openvpn/tun.c
+++ b/openvpn/src/openvpn/tun.c
@@ -1397,15 +1397,6 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
 #error header file linux/sockios.h required
 #endif
 
-
-#if defined(HAVE_TUN_PI) && defined(HAVE_IPHDR) && defined(HAVE_IOVEC) && defined(ETH_P_IPV6) && defined(ETH_P_IP) && defined(HAVE_READV) && defined(HAVE_WRITEV)
-#define LINUX_IPV6 1
-/* #warning IPv6 ON */
-#else
-#define LINUX_IPV6 0
-/* #warning IPv6 OFF */
-#endif
-
 #if !PEDANTIC
 
 void
@@ -1413,13 +1404,6 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
 {
   struct ifreq ifr;
 
-  /* warn if a very old linux version is used & --tun-ipv6 set
-   */
-#if LINUX_IPV6 == 0
-  if ( tt->ipv6 )
-    msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
-#endif
-
   /*
    * We handle --dev null specially, we do not open /dev/null for this.
    */
@@ -1543,7 +1527,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
 #endif /* HAVE_LINUX_IF_TUN_H */
 #endif /* TARGET_ANDROID */
 
-#ifdef TUNSETPERSIST
+#ifdef ENABLE_FEATURE_TUN_PERSIST
 
 /*
  * This can be removed in future
@@ -1593,7 +1577,7 @@ tuncfg (const char *dev, const char *dev_type, const char *dev_node, int persist
   msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
 }
 
-#endif /* TUNSETPERSIST */
+#endif /* ENABLE_FEATURE_TUN_PERSIST */
 
 void
 close_tun (struct tuntap *tt)
@@ -1649,7 +1633,6 @@ close_tun (struct tuntap *tt)
 int
 write_tun (struct tuntap* tt, uint8_t *buf, int len)
 {
-#if LINUX_IPV6
   if (tt->ipv6)
     {
       struct tun_pi pi;
@@ -1675,14 +1658,12 @@ write_tun (struct tuntap* tt, uint8_t *buf, int len)
       return(ret - sizeof(pi));
     }
   else
-#endif
     return write (tt->fd, buf, len);
 }
 
 int
 read_tun (struct tuntap* tt, uint8_t *buf, int len)
 {
-#if LINUX_IPV6
   if (tt->ipv6)
     {
       struct iovec vect[2];
@@ -1698,7 +1679,6 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
       return(ret - sizeof(pi));
     }
   else
-#endif
     return read (tt->fd, buf, len);
 }
 
diff --git a/openvpn/src/openvpnserv/openvpnserv.c b/openvpn/src/openvpnserv/openvpnserv.c
index a9a9441e..56f5a025 100755
--- a/openvpn/src/openvpnserv/openvpnserv.c
+++ b/openvpn/src/openvpnserv/openvpnserv.c
@@ -87,9 +87,9 @@ static HANDLE exit_event = NULL;
 /*
  * Message handling
  */
-#define M_INFO    (0)                                  // informational
-#define M_SYSERR  (MSG_FLAGS_ERROR|MSG_FLAGS_SYS_CODE) // error + system code
-#define M_ERR     (MSG_FLAGS_ERROR)                    // error
+#define M_INFO    (0)                                  /* informational */
+#define M_SYSERR  (MSG_FLAGS_ERROR|MSG_FLAGS_SYS_CODE) /* error + system code */
+#define M_ERR     (MSG_FLAGS_ERROR)                    /* error */
 
 /* write error to event log */
 #define MSG(flags, ...) \
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 98f244bc..3dd0cbb4 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1,12 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-
+	<!--  Keep the order the same as the TYPE_ constants in VPNProfile -->
     <string-array name="vpn_types">
         <item>Certificates</item>
         <item>PKCS12 File</item>
         <item>Android Certficate</item>
         <item>Username/Password</item>
         <item>Static Keys</item>
+        <item>User/PW + Certificates</item>
+        <item>User/PW + PKCS12 </item>
+        <item>User/PW + Android</item>
     </string-array>
     <string-array name="vpn_entry_types">
         <item>certs</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 28863ab9..c8e2b1e1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -117,4 +117,5 @@
     <string name="clear_log">clear log</string>
     <string name="title_cancel">Cancel Confirmation</string>
     <string name="cancel_connection_query">Disconnect the connected VPN/cancel the connection attempt?</string>
+    <string name="remove_vpn">Remove VPN</string>
 </resources>
diff --git a/src/de/blinkt/openvpn/LaunchVPN.java b/src/de/blinkt/openvpn/LaunchVPN.java
index 2bd647f9..caeedc09 100644
--- a/src/de/blinkt/openvpn/LaunchVPN.java
+++ b/src/de/blinkt/openvpn/LaunchVPN.java
@@ -203,7 +203,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
 		 
 	}
 	
-	private void askForPW(String type) {
+	private void askForPW(final String type) {
 
 		final EditText entry = new EditText(this);
 		entry.setSingleLine();
@@ -219,7 +219,11 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
 			@Override
 			public void onClick(DialogInterface dialog, int which) {
 				String pw = entry.getText().toString();
-				mSelectedProfile.mTransientPW = pw;
+				if(type.equals("Password")) {
+					mSelectedProfile.mTransientPW = pw;
+				} else {
+					mSelectedProfile.mTransientPCKS12PW = pw;
+				}
 				onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null);
 
 			}
diff --git a/src/de/blinkt/openvpn/Settings_Basic.java b/src/de/blinkt/openvpn/Settings_Basic.java
index 35e86792..7eb224a8 100644
--- a/src/de/blinkt/openvpn/Settings_Basic.java
+++ b/src/de/blinkt/openvpn/Settings_Basic.java
@@ -173,18 +173,26 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On
 		mView.findViewById(R.id.statickeys).setVisibility(View.GONE);
 		mView.findViewById(R.id.keystore).setVisibility(View.GONE);
 		mView.findViewById(R.id.cacert).setVisibility(View.GONE);
+		mView.findViewById(R.id.userpassword).setVisibility(View.GONE);
 
+		// Fallthroughs are by desing
 		switch(type) {
+		case VpnProfile.TYPE_USERPASS_CERTIFICATES:
+			mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
 		case VpnProfile.TYPE_CERTIFICATES:
 			mView.findViewById(R.id.certs).setVisibility(View.VISIBLE);
 			mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE);
 			break;
+		case VpnProfile.TYPE_USERPASS_PKCS12:
+			mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
 		case VpnProfile.TYPE_PKCS12:
 			mView.findViewById(R.id.pkcs12).setVisibility(View.VISIBLE);
 			break;
 		case VpnProfile.TYPE_STATICKEYS:
 			mView.findViewById(R.id.statickeys).setVisibility(View.VISIBLE);
 			break;
+		case VpnProfile.TYPE_USERPASS_KEYSTORE:
+			mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
 		case VpnProfile.TYPE_KEYSTORE:
 			mView.findViewById(R.id.keystore).setVisibility(View.VISIBLE);
 			break;
diff --git a/src/de/blinkt/openvpn/Settings_Obscure.java b/src/de/blinkt/openvpn/Settings_Obscure.java
index 02a433fb..d7bce9ad 100644
--- a/src/de/blinkt/openvpn/Settings_Obscure.java
+++ b/src/de/blinkt/openvpn/Settings_Obscure.java
@@ -67,6 +67,8 @@ public class Settings_Obscure extends PreferenceFragment implements OnPreference
 	public boolean onPreferenceChange(Preference preference, Object newValue) {
 		if(preference==mLogverbosity) {
 			mLogverbosity.setDefaultValue(newValue);
+			// Does not refresh otherwise
+			mLogverbosity.setSummary("%s");
 		}
 			
 		return true;
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java
index 11f2fffa..04b5927f 100644
--- a/src/de/blinkt/openvpn/VpnProfile.java
+++ b/src/de/blinkt/openvpn/VpnProfile.java
@@ -35,10 +35,20 @@ public class VpnProfile implements  Serializable{
 	static final int TYPE_KEYSTORE=2;
 	public static final int TYPE_USERPASS = 3;
 	public static final int TYPE_STATICKEYS = 4;
+	public static final int TYPE_USERPASS_CERTIFICATES = 5;
+	public static final int TYPE_USERPASS_PKCS12 = 6;
+	public static final int TYPE_USERPASS_KEYSTORE = 7;
+	
+	
+	
+	
+
 
 	private static final String OVPNCONFIGFILE = "android.conf";
 
 	protected transient String mTransientPW=null;
+	protected transient String mTransientPCKS12PW=null;
+
 	private static transient String mTempPKCS12Password;
 
 
@@ -141,6 +151,7 @@ public class VpnProfile implements  Serializable{
 
 	static final String OVPNCONFIGPKCS12 = "android.pkcs12";
 
+
 	public VpnProfile(String name) {
 		mUuid = UUID.randomUUID();
 		mName = name;
@@ -210,7 +221,11 @@ public class VpnProfile implements  Serializable{
 
 
 
+
 		switch(mAuthenticationType) {
+		case VpnProfile.TYPE_USERPASS_CERTIFICATES:
+			cfg+="auth-user-pass\n";
+			cfg+="management-query-passwords\n";
 		case VpnProfile.TYPE_CERTIFICATES:
 			// Ca
 			cfg+="ca ";
@@ -225,6 +240,8 @@ public class VpnProfile implements  Serializable{
 			cfg+=mClientCertFilename;
 			cfg+="\n";
 			break;
+		case VpnProfile.TYPE_USERPASS_PKCS12:
+			cfg+="auth-user-pass\n";
 		case VpnProfile.TYPE_PKCS12:
 			cfg+="pkcs12 ";
 			cfg+=mPKCS12Filename;
@@ -232,6 +249,8 @@ public class VpnProfile implements  Serializable{
 			cfg+="management-query-passwords\n";
 			break;
 
+		case VpnProfile.TYPE_USERPASS_KEYSTORE:
+			cfg+="auth-user-pass\n";
 		case VpnProfile.TYPE_KEYSTORE:
 			cfg+="pkcs12 ";
 			cfg+=cacheDir.getAbsolutePath() + "/" + OVPNCONFIGPKCS12;
@@ -239,13 +258,9 @@ public class VpnProfile implements  Serializable{
 			cfg+="management-query-passwords\n";
 			break;
 		case VpnProfile.TYPE_USERPASS:
-			cfg+="ca " + mCaFilename + "\n";
 			cfg+="auth-user-pass\n";
 			cfg+="management-query-passwords\n";
-			break;
-
-
-
+			cfg+="ca " + mCaFilename +"\n";
 		}
 
 		if(mUseLzo) {
@@ -298,26 +313,26 @@ public class VpnProfile implements  Serializable{
 		}
 		if(mExpectTLSCert)
 			cfg += "remote-cert-tls server\n";
-		
-		
-		
-		
+
+
+
+
 		// Obscure Settings dialog
 		if(mUseRandomHostname)
 			cfg += "#my favorite options :)\nremote-random-hostname\n";
-		
+
 		if(mUseFloat)
 			cfg+= "float\n";
-		
+
 		if(mUseCustomConfig) {
 			cfg += "# Custom configuration options\n";
 			cfg += "# You are on your on own here :)\n";
 			cfg += mCustomConfigOptions;
 			cfg += "\n";
-					
+
 		}
-			
-		
+
+
 
 		return cfg;
 	}
@@ -388,7 +403,7 @@ public class VpnProfile implements  Serializable{
 
 		Intent intent = new Intent(context,OpenVpnService.class);
 
-		if(mAuthenticationType == VpnProfile.TYPE_KEYSTORE) {
+		if(mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) {
 			savePKCS12(context);
 		}
 
@@ -457,7 +472,7 @@ public class VpnProfile implements  Serializable{
 	}
 	//! Return an error if somethign is wrong
 	int checkProfile() {
-		if(mAuthenticationType==TYPE_KEYSTORE && mAlias==null) 
+		if((mAuthenticationType==TYPE_KEYSTORE || mAuthenticationType==TYPE_USERPASS_KEYSTORE) && mAlias==null) 
 			return R.string.no_keystore_cert_selected;
 
 		if(!mUsePull) {
@@ -473,39 +488,55 @@ public class VpnProfile implements  Serializable{
 
 	}
 
-	//! Openvpn asks for a "Private Key", this can be pkcs12 pw or private key pw
+	//! Openvpn asks for a "Private Key", this should be pkcs12 key
 	//
 	public String getPasswordPrivateKey() {
-		if(mTransientPW!=null) {
-			String pwcopy = mTransientPW;
-			mTransientPW=null;
+		if(mTransientPCKS12PW!=null) {
+			String pwcopy = mTransientPCKS12PW;
+			mTransientPCKS12PW=null;
 			return pwcopy;
 		}
 		switch (mAuthenticationType) {
 		case TYPE_KEYSTORE:
+		case TYPE_USERPASS_KEYSTORE:
 			return getTemporaryPKCS12Password();
 
 		case TYPE_PKCS12:
+		case TYPE_USERPASS_PKCS12:
 			return mPKCS12Password;
 
+
 		case TYPE_USERPASS:
 		case TYPE_STATICKEYS:
 		case TYPE_CERTIFICATES:
+		case TYPE_USERPASS_CERTIFICATES:
 		default:
 			return null;
 		}
 	}
+	private boolean isUserPWAuth() {
+		switch(mAuthenticationType) {
+		case TYPE_USERPASS:
+		case TYPE_USERPASS_CERTIFICATES:
+		case TYPE_USERPASS_KEYSTORE:
+		case TYPE_USERPASS_PKCS12:
+			return true;
+		default:
+			return false;
+
+		}
+	}
 
 	public String needUserPWInput() {
-		if(mTransientPW!=null)
-			return null;
-		if(mAuthenticationType == TYPE_PKCS12 &&
+		if((mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12)&&
 				(mPKCS12Password.equals("") || mPKCS12Password == null)) {
-			return "PKCS12 File Password";
+			if(mTransientPCKS12PW==null)
+				return "PKCS12 File Encryption Key";
 		}
-		if(mAuthenticationType == TYPE_USERPASS &&
-				(mPassword.equals("") || mPassword == null)) {
-			return "Password";
+		if(isUserPWAuth() && (mPassword.equals("") || mPassword == null)) {
+			if(mTransientPW==null)
+				return "Password";
+			
 		}
 		return null;
 	}
diff --git a/todo.txt b/todo.txt
new file mode 100644
index 00000000..a15bf1f5
--- /dev/null
+++ b/todo.txt
@@ -0,0 +1 @@
+- VPN List as ListFragment with Context Menu
\ No newline at end of file
-- 
cgit v1.2.3