diff options
author | Arne Schwabe <arne@rfc2549.org> | 2012-05-01 15:33:00 +0200 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2012-05-01 15:33:00 +0200 |
commit | 3d54881bc78b893ab286681338dd7b9b69d871b3 (patch) | |
tree | a6e8e13bc598a4762c96312800451ddf0a8306e6 | |
parent | 61deb1b6598f2816125525c8621b08e047172768 (diff) |
Support strange certificate + passsword authentication types
31 files changed, 312 insertions, 142 deletions
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}]] @@ -412,38 +416,32 @@ AC_CHECK_TYPES( [[${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 |