diff options
48 files changed, 643 insertions, 457 deletions
| diff --git a/main/openvpn/Makefile.am b/main/openvpn/Makefile.am index 1a30aa5a..66d9f23a 100644 --- a/main/openvpn/Makefile.am +++ b/main/openvpn/Makefile.am @@ -41,7 +41,7 @@ MAINTAINERCLEANFILES = \  	$(srcdir)/config.guess $(srcdir)/config.sub  CLEANFILES = \ -	config-version.h +	config-version.h tests/t_client.sh  EXTRA_DIST = \  	contrib \ diff --git a/main/openvpn/README.ec b/main/openvpn/README.ec new file mode 100644 index 00000000..bea3ce19 --- /dev/null +++ b/main/openvpn/README.ec @@ -0,0 +1,37 @@ +Since 2.4.0, OpenVPN has official support for elliptic curve crypto. Elliptic +curves are an alternative to RSA for asymmetric encryption. + +Elliptic curve crypto ('ECC') can be used for the ('TLS') control channel only +in OpenVPN; the data channel (encrypting the actual network traffic) uses +symmetric encryption. ECC can be used in TLS for authentication (ECDSA) and key +exchange (ECDH). + +Note: ECC is available in OpenSSL builds of OpenVPN only. ECC for PolarSSL +builds will follow soon. + +Key exchange (ECDH) +------------------- +OpenVPN 2.4.0 and newer automatically initialize ECDH parameters. When ECDSA is +used for authentication, the curve used for the server certificate will be used +for ECDH too. When autodetection fails (e.g. when using RSA certificates) +OpenVPN falls back to the secp384r1 curve. + +An administrator can force an OpenVPN server to use a specific curve using the +--ecdh-curve <curvename> option with one of the curves listed as available by +the --show-curves option. Clients will use the same curve as selected by the +server. + +Note that not all curves listed by --show-curves are available for use with TLS; +in that case connecting will fail with a 'no shared cipher' TLS error. + +Authentication (ECDSA) +---------------------- +Since OpenVPN 2.4.0, using ECDSA certificates works 'out of the box'. Which +specific curves and cipher suites are available depends on your version and +configuration of the crypto library. The crypto library will automatically +select a cipher suite for the TLS control channel. + +Support for generating an ECDSA certificate chain is available in EasyRSA (in +spite of it's name) since EasyRSA 3.0. The parameters you're looking for are +'--use-algo=ec' and '--curve=<curve_name>'. See the EasyRSA documentation for +more details on generating ECDSA certificates. diff --git a/main/openvpn/config-msvc.h b/main/openvpn/config-msvc.h index 99c00f9f..9a95ae65 100644 --- a/main/openvpn/config-msvc.h +++ b/main/openvpn/config-msvc.h @@ -89,7 +89,10 @@  #define strncasecmp strnicmp  #define strcasecmp _stricmp  #define snprintf _snprintf + +#if _MSC_VER < 1800  #define strtoull strtoul +#endif  #define in_addr_t uint32_t  #define ssize_t SSIZE_T diff --git a/main/openvpn/config-version.h b/main/openvpn/config-version.h index 81c6a94c..3e0e1c21 100644 --- a/main/openvpn/config-version.h +++ b/main/openvpn/config-version.h @@ -1,2 +1,2 @@ -#define CONFIGURE_GIT_REVISION "icsopenvpn_612-a611f0041a0e3548" +#define CONFIGURE_GIT_REVISION "icsopenvpn_613-37a1cca2c345af66"  #define CONFIGURE_GIT_FLAGS "" diff --git a/main/openvpn/configure.ac b/main/openvpn/configure.ac index 7e94280d..70c0c8b5 100644 --- a/main/openvpn/configure.ac +++ b/main/openvpn/configure.ac @@ -121,20 +121,6 @@ AC_ARG_ENABLE(  )  AC_ARG_ENABLE( -	[socks], -	[AS_HELP_STRING([--disable-socks], [disable Socks support @<:@default=yes@:>@])], -	, -	[enable_socks="yes"] -) - -AC_ARG_ENABLE( -	[http-proxy], -	[AS_HELP_STRING([--disable-http-proxy], [disable HTTP proxy support @<:@default=yes@:>@])], -	, -	[enable_http_proxy="yes"] -) - -AC_ARG_ENABLE(  	[fragment],  	[AS_HELP_STRING([--disable-fragment], [disable internal fragmentation support (--fragment) @<:@default=yes@:>@])],  	, @@ -794,6 +780,8 @@ if test "${have_openssl_crypto}" = "yes"; then  fi  if test "${have_openssl_ssl}" = "yes"; then +    saved_CPPFLAGS="${CPPFLAGS}" +    CPPFLAGS="${CPPFLAGS} ${OPENSSL_CRYPTO_CFLAGS}"      AC_MSG_CHECKING([for SSL_OP_NO_TICKET flag in OpenSSL])      AC_EGREP_CPP(have_ssl_op_no_ticket, [      #include <openssl/ssl.h> @@ -806,6 +794,7 @@ if test "${have_openssl_ssl}" = "yes"; then          AC_MSG_RESULT([no])          AC_ERROR([OpenVPN 2.4+ requires SSL_OP_NO_TICKET in OpenSSL])      ]) +    CPPFLAGS="${saved_CPPFLAGS}"  fi  AC_ARG_VAR([POLARSSL_CFLAGS], [C compiler flags for polarssl]) @@ -841,13 +830,13 @@ if test "${with_crypto_library}" = "polarssl" ; then  #include <polarssl/version.h>  			]],  			[[ -#if POLARSSL_VERSION_NUMBER < 0x01020A00 || POLARSSL_VERSION_NUMBER >= 0x01030000 +#if POLARSSL_VERSION_NUMBER < 0x01030300 || POLARSSL_VERSION_NUMBER >= 0x01040000  #error invalid version  #endif  			]]  		)],  		[AC_MSG_RESULT([ok])], -		[AC_MSG_ERROR([PolarSSL 1.2.x required and must be 1.2.10 or later])] +		[AC_MSG_ERROR([PolarSSL 1.3.x required and must be 1.3.3 or later])]  	)  	polarssl_with_pkcs11="no" @@ -1033,8 +1022,6 @@ test "${ac_cv_header_sys_uio_h}" = "yes" && AC_DEFINE([HAVE_IOVEC], [1], [struct  test "${enable_multi}" = "yes" && AC_DEFINE([ENABLE_CLIENT_SERVER], [1], [Enable client/server capability])  test "${enable_server}" = "no" && AC_DEFINE([ENABLE_CLIENT_ONLY], [1], [Enable client capability only])  test "${enable_management}" = "yes" && AC_DEFINE([ENABLE_MANAGEMENT], [1], [Enable management server capability]) -test "${enable_socks}" = "yes" && AC_DEFINE([ENABLE_SOCKS], [1], [Enable Socks proxy support]) -test "${enable_http_proxy}" = "yes" && AC_DEFINE([ENABLE_HTTP_PROXY], [1], [Enable HTTP proxy support])  test "${enable_multihome}" = "yes" && AC_DEFINE([ENABLE_MULTIHOME], [1], [Enable multi-homed UDP server capability])  test "${enable_debug}" = "yes" && AC_DEFINE([ENABLE_DEBUG], [1], [Enable debugging support])  test "${enable_small}" = "yes" && AC_DEFINE([ENABLE_SMALL], [1], [Enable smaller executable size]) diff --git a/main/openvpn/doc/openvpn.8 b/main/openvpn/doc/openvpn.8 index 3a58317d..b7d6a3d7 100644 --- a/main/openvpn/doc/openvpn.8 +++ b/main/openvpn/doc/openvpn.8 @@ -4246,6 +4246,13 @@ included with the OpenVPN distribution.  Diffie Hellman parameters  may be considered public.  .\"*********************************************************  .TP +.B \-\-ecdh-curve name +Specify the curve to use for elliptic curve Diffie Hellman. Available +curves can be listed with +.B \-\-show-curves +. The specified curve will only be used for ECDH TLS-ciphers. +.\"********************************************************* +.TP  .B \-\-cert file  Local peer's signed certificate in .pem format \-\- must be signed  by a certificate authority whose certificate is in @@ -5027,6 +5034,13 @@ lowest.  Show currently available hardware-based crypto acceleration  engines supported by the OpenSSL library.  .\"********************************************************* +.TP +.B \-\-show-curves +(Standalone) +Show all available elliptic curves to use with the +.B \-\-ecdh-curve +option. +.\"*********************************************************  .SS Generate a random key:  Used only for non-TLS static key encryption mode.  .\"********************************************************* diff --git a/main/openvpn/include/openvpn-plugin.h b/main/openvpn/include/openvpn-plugin.h index 03da92ab..5f2d4079 100644 --- a/main/openvpn/include/openvpn-plugin.h +++ b/main/openvpn/include/openvpn-plugin.h @@ -29,10 +29,10 @@  #ifdef ENABLE_SSL  #ifdef ENABLE_CRYPTO_POLARSSL -#include <polarssl/x509.h> +#include <polarssl/x509_crt.h>  #ifndef __OPENVPN_X509_CERT_T_DECLARED  #define __OPENVPN_X509_CERT_T_DECLARED -typedef x509_cert openvpn_x509_cert_t; +typedef x509_crt openvpn_x509_cert_t;  #endif  #else  #include <openssl/x509.h> diff --git a/main/openvpn/sample/sample-keys/README b/main/openvpn/sample/sample-keys/README index 1cd473a1..9f4f9187 100644 --- a/main/openvpn/sample/sample-keys/README +++ b/main/openvpn/sample/sample-keys/README @@ -1,7 +1,6 @@ -Sample RSA keys. +Sample RSA and EC keys. -See the examples section of the man page -for usage examples. +See the examples section of the man page for usage examples.  NOTE: THESE KEYS ARE FOR TESTING PURPOSES ONLY.        DON'T USE THEM FOR ANY REAL WORK BECAUSE @@ -12,3 +11,4 @@ client.{crt,key} -- sample client key/cert  server.{crt,key} -- sample server key/cert (nsCertType=server)  pass.{crt,key}   -- sample client key/cert with password-encrypted key                      password = "password" +ec-*.{crt,key}   -- sample elliptic curve variants of the above diff --git a/main/openvpn/sample/sample-keys/ec-ca.crt b/main/openvpn/sample/sample-keys/ec-ca.crt new file mode 100644 index 00000000..e190801d --- /dev/null +++ b/main/openvpn/sample/sample-keys/ec-ca.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4jCCAWmgAwIBAgIJALGEGB2g6cAXMAoGCCqGSM49BAMCMBUxEzARBgNVBAMT +CkVDLVRlc3QgQ0EwHhcNMTQwMTE4MTYwMTUzWhcNMjQwMTE2MTYwMTUzWjAVMRMw +EQYDVQQDEwpFQy1UZXN0IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE2S4AZT7j +ZlPG/CXpT12CzCNSySyKmJt+fWyW/wzbRulVJpGHXRHpZZj2VNOUE72kqGUeshh6 +Um1o7lHGDSAkHOJpeW5FtryiKhwFc+4dsOCLTNLVFXQsEtY3gY14Uquio4GEMIGB +MB0GA1UdDgQWBBS0mkFcuCZ8SLWZRAD/8LpBQcgGPDBFBgNVHSMEPjA8gBS0mkFc +uCZ8SLWZRAD/8LpBQcgGPKEZpBcwFTETMBEGA1UEAxMKRUMtVGVzdCBDQYIJALGE +GB2g6cAXMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA2cA +MGQCMHWlVTi0xNZstR8ZNH+7z0WlyIXyZe23ne3EXkO0thZLdv86kpxFMPW/llB+ +RMRKuQIweN97n7FQy5DTenr91U98KDFJ5Av4mDFRL1mkXiu3W1//4XD8yEYDQTRz +/GARuOLL +-----END CERTIFICATE----- diff --git a/main/openvpn/sample/sample-keys/ec-ca.key b/main/openvpn/sample/sample-keys/ec-ca.key new file mode 100644 index 00000000..51a72e1a --- /dev/null +++ b/main/openvpn/sample/sample-keys/ec-ca.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDASU6X/mh2m2PayviL3 +teoml5soyIUcZfwZpVn6oNtnrLcAbIRsAJbM4xyGVp77G/6hZANiAATZLgBlPuNm +U8b8JelPXYLMI1LJLIqYm359bJb/DNtG6VUmkYddEellmPZU05QTvaSoZR6yGHpS +bWjuUcYNICQc4ml5bkW2vKIqHAVz7h2w4ItM0tUVdCwS1jeBjXhSq6I= +-----END PRIVATE KEY----- diff --git a/main/openvpn/sample/sample-keys/ec-client.crt b/main/openvpn/sample/sample-keys/ec-client.crt new file mode 100644 index 00000000..b797b022 --- /dev/null +++ b/main/openvpn/sample/sample-keys/ec-client.crt @@ -0,0 +1,61 @@ +Certificate: +    Data: +        Version: 3 (0x2) +        Serial Number: 2 (0x2) +    Signature Algorithm: ecdsa-with-SHA256 +        Issuer: CN=EC-Test CA +        Validity +            Not Before: Jan 18 16:02:37 2014 GMT +            Not After : Jan 16 16:02:37 2024 GMT +        Subject: CN=ec-client +        Subject Public Key Info: +            Public Key Algorithm: id-ecPublicKey +                Public-Key: (384 bit) +                pub: +                    04:40:d9:b9:a2:44:1b:01:39:2c:14:ee:aa:70:6b: +                    31:98:28:44:c9:61:bc:b7:0b:b5:53:49:c2:c0:0a: +                    43:b0:08:50:cd:80:2f:5d:a4:89:f1:ff:7d:11:78: +                    f5:0c:b2:86:e2:59:f8:17:76:1b:22:f2:23:67:e7: +                    55:90:ea:ce:0a:aa:da:05:f4:85:19:c9:ed:ae:6d: +                    a3:ad:56:7a:f6:33:c6:cf:bb:c7:39:fa:e4:d3:67: +                    df:f0:b8:4a:88:57:98 +                ASN1 OID: secp384r1 +        X509v3 extensions: +            X509v3 Basic Constraints: +                CA:FALSE +            X509v3 Subject Key Identifier: +                D8:E2:35:7B:CA:66:71:6B:D8:5B:F5:12:13:82:2D:ED:CD:E5:ED:7F +            X509v3 Authority Key Identifier: +                keyid:B4:9A:41:5C:B8:26:7C:48:B5:99:44:00:FF:F0:BA:41:41:C8:06:3C +                DirName:/CN=EC-Test CA +                serial:B1:84:18:1D:A0:E9:C0:17 + +            X509v3 Extended Key Usage: +                TLS Web Client Authentication +            X509v3 Key Usage: +                Digital Signature +            Netscape Comment: +                Easy-RSA Generated Certificate +            Netscape Cert Type: +                SSL Client +    Signature Algorithm: ecdsa-with-SHA256 +         30:64:02:30:41:8b:1a:fd:97:a8:bb:7c:d0:eb:1c:a2:ba:c0: +         ac:2f:6d:80:07:5b:5c:ef:55:59:1a:92:56:66:94:ce:49:6a: +         a9:57:49:b2:41:73:64:7e:01:ac:31:3a:7c:2a:bf:a5:02:30: +         2b:c4:a6:b1:0c:03:82:e3:e4:03:39:fb:19:d7:76:21:1b:7e: +         7f:aa:22:5d:90:a4:e1:2e:cd:ca:92:0f:b6:3f:80:dc:26:d2: +         09:34:8c:d1:61:bb:9d:ac:6d:8f:68:f0 +-----BEGIN CERTIFICATE----- +MIICLTCCAbSgAwIBAgIBAjAKBggqhkjOPQQDAjAVMRMwEQYDVQQDEwpFQy1UZXN0 +IENBMB4XDTE0MDExODE2MDIzN1oXDTI0MDExNjE2MDIzN1owFDESMBAGA1UEAxMJ +ZWMtY2xpZW50MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEQNm5okQbATksFO6qcGsx +mChEyWG8twu1U0nCwApDsAhQzYAvXaSJ8f99EXj1DLKG4ln4F3YbIvIjZ+dVkOrO +CqraBfSFGcntrm2jrVZ69jPGz7vHOfrk02ff8LhKiFeYo4HYMIHVMAkGA1UdEwQC +MAAwHQYDVR0OBBYEFNjiNXvKZnFr2Fv1EhOCLe3N5e1/MEUGA1UdIwQ+MDyAFLSa +QVy4JnxItZlEAP/wukFByAY8oRmkFzAVMRMwEQYDVQQDEwpFQy1UZXN0IENBggkA +sYQYHaDpwBcwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMC0GCWCG +SAGG+EIBDQQgFh5FYXN5LVJTQSBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwEQYJYIZI +AYb4QgEBBAQDAgeAMAoGCCqGSM49BAMCA2cAMGQCMEGLGv2XqLt80OscorrArC9t +gAdbXO9VWRqSVmaUzklqqVdJskFzZH4BrDE6fCq/pQIwK8SmsQwDguPkAzn7Gdd2 +IRt+f6oiXZCk4S7NypIPtj+A3CbSCTSM0WG7naxtj2jw +-----END CERTIFICATE----- diff --git a/main/openvpn/sample/sample-keys/ec-client.key b/main/openvpn/sample/sample-keys/ec-client.key new file mode 100644 index 00000000..60636ed2 --- /dev/null +++ b/main/openvpn/sample/sample-keys/ec-client.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDD9Agj8nr/8sIr0XHky +mcn1oMb3vqOh2axFBaIvmOHYmqs11SIH1tKYelkNYy9zHTChZANiAARA2bmiRBsB +OSwU7qpwazGYKETJYby3C7VTScLACkOwCFDNgC9dpInx/30RePUMsobiWfgXdhsi +8iNn51WQ6s4KqtoF9IUZye2ubaOtVnr2M8bPu8c5+uTTZ9/wuEqIV5g= +-----END PRIVATE KEY----- diff --git a/main/openvpn/sample/sample-keys/ec-server.crt b/main/openvpn/sample/sample-keys/ec-server.crt new file mode 100644 index 00000000..99994729 --- /dev/null +++ b/main/openvpn/sample/sample-keys/ec-server.crt @@ -0,0 +1,61 @@ +Certificate: +    Data: +        Version: 3 (0x2) +        Serial Number: 1 (0x1) +    Signature Algorithm: ecdsa-with-SHA256 +        Issuer: CN=EC-Test CA +        Validity +            Not Before: Jan 18 16:02:31 2014 GMT +            Not After : Jan 16 16:02:31 2024 GMT +        Subject: CN=ec-server +        Subject Public Key Info: +            Public Key Algorithm: id-ecPublicKey +                Public-Key: (384 bit) +                pub: +                    04:bd:8c:3a:af:2e:2f:2e:de:cf:d2:39:8d:b9:a6: +                    13:96:80:6d:b5:b2:ee:97:62:3b:a2:32:38:77:1e: +                    fb:2a:ef:86:4b:d0:9e:4b:55:e0:9b:07:f9:64:2f: +                    6b:a7:17:fd:65:dd:50:3f:1c:fa:fa:2f:39:2e:97: +                    d4:86:e5:4e:5a:d2:50:0b:f4:d7:08:62:67:53:44: +                    62:e3:25:f2:fa:36:84:87:1d:03:e3:e9:9d:d9:66: +                    51:dd:b4:c4:db:0b:05 +                ASN1 OID: secp384r1 +        X509v3 extensions: +            X509v3 Basic Constraints: +                CA:FALSE +            X509v3 Subject Key Identifier: +                EA:DF:7E:A3:D4:61:73:D7:01:AF:6E:0A:38:8D:33:D0:BD:24:4B:E1 +            X509v3 Authority Key Identifier: +                keyid:B4:9A:41:5C:B8:26:7C:48:B5:99:44:00:FF:F0:BA:41:41:C8:06:3C +                DirName:/CN=EC-Test CA +                serial:B1:84:18:1D:A0:E9:C0:17 + +            X509v3 Extended Key Usage: +                TLS Web Server Authentication +            X509v3 Key Usage: +                Digital Signature, Key Encipherment +            Netscape Comment: +                Easy-RSA Generated Certificate +            Netscape Cert Type: +                SSL Server +    Signature Algorithm: ecdsa-with-SHA256 +         30:64:02:30:20:39:12:92:cc:a2:ca:45:b9:1a:8f:e0:c1:e7: +         b7:4a:79:4d:07:07:81:72:08:b4:d4:7b:46:53:d7:72:32:d0: +         d7:3e:e8:88:2b:c9:ba:8b:d5:94:4f:41:6c:d0:2e:a4:02:30: +         75:ff:c3:8a:c1:f5:79:1c:1a:08:16:31:c2:c1:6e:d4:33:dc: +         9f:04:0f:90:94:d9:75:c1:6d:71:28:62:cc:f6:89:7c:91:86: +         a4:96:45:34:a0:8d:92:7e:dd:e3:da:4d +-----BEGIN CERTIFICATE----- +MIICLTCCAbSgAwIBAgIBATAKBggqhkjOPQQDAjAVMRMwEQYDVQQDEwpFQy1UZXN0 +IENBMB4XDTE0MDExODE2MDIzMVoXDTI0MDExNjE2MDIzMVowFDESMBAGA1UEAxMJ +ZWMtc2VydmVyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEvYw6ry4vLt7P0jmNuaYT +loBttbLul2I7ojI4dx77Ku+GS9CeS1Xgmwf5ZC9rpxf9Zd1QPxz6+i85LpfUhuVO +WtJQC/TXCGJnU0Ri4yXy+jaEhx0D4+md2WZR3bTE2wsFo4HYMIHVMAkGA1UdEwQC +MAAwHQYDVR0OBBYEFOrffqPUYXPXAa9uCjiNM9C9JEvhMEUGA1UdIwQ+MDyAFLSa +QVy4JnxItZlEAP/wukFByAY8oRmkFzAVMRMwEQYDVQQDEwpFQy1UZXN0IENBggkA +sYQYHaDpwBcwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMC0GCWCG +SAGG+EIBDQQgFh5FYXN5LVJTQSBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwEQYJYIZI +AYb4QgEBBAQDAgZAMAoGCCqGSM49BAMCA2cAMGQCMCA5EpLMospFuRqP4MHnt0p5 +TQcHgXIItNR7RlPXcjLQ1z7oiCvJuovVlE9BbNAupAIwdf/DisH1eRwaCBYxwsFu +1DPcnwQPkJTZdcFtcShizPaJfJGGpJZFNKCNkn7d49pN +-----END CERTIFICATE----- diff --git a/main/openvpn/sample/sample-keys/ec-server.key b/main/openvpn/sample/sample-keys/ec-server.key new file mode 100644 index 00000000..bb3cdf1a --- /dev/null +++ b/main/openvpn/sample/sample-keys/ec-server.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDD8bQlwrFrXHPmem0bt +cBcU6nYfaZQbPdIDAB7edOOyevvzYH0qMtbaW95iSZLMRVWhZANiAAS9jDqvLi8u +3s/SOY25phOWgG21su6XYjuiMjh3Hvsq74ZL0J5LVeCbB/lkL2unF/1l3VA/HPr6 +Lzkul9SG5U5a0lAL9NcIYmdTRGLjJfL6NoSHHQPj6Z3ZZlHdtMTbCwU= +-----END PRIVATE KEY----- diff --git a/main/openvpn/sample/sample-plugins/defer/build b/main/openvpn/sample/sample-plugins/defer/build index 0612c080..ba41a39f 100755 --- a/main/openvpn/sample/sample-plugins/defer/build +++ b/main/openvpn/sample/sample-plugins/defer/build @@ -12,4 +12,4 @@ CC="${CC:-gcc}"  CFLAGS="${CFLAGS:--O2 -Wall -g}"  $CC $CPPFLAGS $CFLAGS -fPIC -c $1.c && \ -$CC $CFLAGS -fPIC -shared ${LDFLAS} -Wl,-soname,$1.so -o $1.so $1.o -lc +$CC $CFLAGS -fPIC -shared ${LDFLAGS} -Wl,-soname,$1.so -o $1.so $1.o -lc diff --git a/main/openvpn/src/openvpn/base64.c b/main/openvpn/src/openvpn/base64.c index bb89aae3..6dc8479f 100644 --- a/main/openvpn/src/openvpn/base64.c +++ b/main/openvpn/src/openvpn/base64.c @@ -39,8 +39,6 @@  #include "syshead.h" -#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY) -  #include "base64.h"  #include "memdbg.h" @@ -163,7 +161,3 @@ openvpn_base64_decode(const char *str, void *data, int size)      }      return q - (unsigned char *) data;  } - -#else -static void dummy(void) {} -#endif /* ENABLE_HTTP_PROXY, ENABLE_PKCS11, ENABLE_CLIENT_CR */ diff --git a/main/openvpn/src/openvpn/base64.h b/main/openvpn/src/openvpn/base64.h index 28a9677c..92a195aa 100644 --- a/main/openvpn/src/openvpn/base64.h +++ b/main/openvpn/src/openvpn/base64.h @@ -34,11 +34,7 @@  #ifndef _BASE64_H_  #define _BASE64_H_ -#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY) -  int openvpn_base64_encode(const void *data, int size, char **str);  int openvpn_base64_decode(const char *str, void *data, int size);  #endif - -#endif diff --git a/main/openvpn/src/openvpn/buffer.c b/main/openvpn/src/openvpn/buffer.c index 36611415..46f874b2 100644 --- a/main/openvpn/src/openvpn/buffer.c +++ b/main/openvpn/src/openvpn/buffer.c @@ -976,9 +976,6 @@ valign4 (const struct buffer *buf, const char *file, const int line)  /*   * struct buffer_list   */ - -#ifdef ENABLE_BUFFER_LIST -  struct buffer_list *  buffer_list_new (const int max_size)  { @@ -1154,5 +1151,3 @@ buffer_list_file (const char *fn, int max_line_len)      }    return bl;  } - -#endif diff --git a/main/openvpn/src/openvpn/buffer.h b/main/openvpn/src/openvpn/buffer.h index 19fa1fa2..7469da63 100644 --- a/main/openvpn/src/openvpn/buffer.h +++ b/main/openvpn/src/openvpn/buffer.h @@ -904,9 +904,6 @@ check_malloc_return (void *p)  /*   * Manage lists of buffers   */ - -#ifdef ENABLE_BUFFER_LIST -  struct buffer_entry  {    struct buffer buf; @@ -936,7 +933,4 @@ void buffer_list_pop (struct buffer_list *ol);  void buffer_list_aggregate (struct buffer_list *bl, const size_t max);  struct buffer_list *buffer_list_file (const char *fn, int max_line_len); - -#endif -  #endif /* BUFFER_H */ diff --git a/main/openvpn/src/openvpn/crypto_polarssl.c b/main/openvpn/src/openvpn/crypto_polarssl.c index 1f27d6ca..7dc8aa5b 100644 --- a/main/openvpn/src/openvpn/crypto_polarssl.c +++ b/main/openvpn/src/openvpn/crypto_polarssl.c @@ -466,7 +466,12 @@ int cipher_ctx_mode (const cipher_context_t *ctx)  int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)  { -  return 0 == cipher_reset(ctx, iv_buf); +  int retval = cipher_reset(ctx); + +  if (0 == retval) +    retval = cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size); + +  return 0 == retval;  }  int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len, diff --git a/main/openvpn/src/openvpn/forward.c b/main/openvpn/src/openvpn/forward.c index 43e2d3d1..f78f5f0a 100644 --- a/main/openvpn/src/openvpn/forward.c +++ b/main/openvpn/src/openvpn/forward.c @@ -610,8 +610,6 @@ check_timeout_random_component (struct context *c)      tv_add (&c->c2.timeval, &c->c2.timeout_random_component);  } -#ifdef ENABLE_SOCKS -  /*   * Handle addition and removal of the 10-byte Socks5 header   * in UDP packets. @@ -649,7 +647,6 @@ link_socket_write_post_size_adjust (int *size,  	*size = 0;      }  } -#endif  /*   * Output: c->c2.buf @@ -718,10 +715,8 @@ read_incoming_link (struct context *c)    /* check recvfrom status */    check_status (status, "read", c->c2.link_socket, NULL); -#ifdef ENABLE_SOCKS    /* Remove socks header if applicable */    socks_postprocess_incoming_link (c); -#endif    perf_pop ();  } @@ -1132,23 +1127,18 @@ process_outgoing_link (struct context *c)  	  /* Packet send complexified by possible Socks5 usage */  	  {  	    struct link_socket_actual *to_addr = c->c2.to_link_addr; -#ifdef ENABLE_SOCKS  	    int size_delta = 0; -#endif -#ifdef ENABLE_SOCKS  	    /* If Socks5 over UDP, prepend header */  	    socks_preprocess_outgoing_link (c, &to_addr, &size_delta); -#endif +  	    /* Send packet */  	    size = link_socket_write (c->c2.link_socket,  				      &c->c2.to_link,  				      to_addr); -#ifdef ENABLE_SOCKS  	    /* Undo effect of prepend */  	    link_socket_write_post_size_adjust (&size, size_delta, &c->c2.to_link); -#endif  	  }  	  if (size > 0) diff --git a/main/openvpn/src/openvpn/init.c b/main/openvpn/src/openvpn/init.c index 4e79bfcf..425c077b 100644 --- a/main/openvpn/src/openvpn/init.c +++ b/main/openvpn/src/openvpn/init.c @@ -127,9 +127,6 @@ management_callback_proxy_cmd (void *arg, const char **p)      {        if (streq (p[1], "HTTP"))          { -#ifndef ENABLE_HTTP_PROXY -          msg (M_WARN, "HTTP proxy support is not available"); -#else            struct http_proxy_options *ho;            if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT )              { @@ -142,17 +139,12 @@ management_callback_proxy_cmd (void *arg, const char **p)            ho->retry = true;            ho->auth_retry = (p[4] && streq (p[4], "nct") ? PAR_NCT : PAR_ALL);            ret = true; -#endif          }        else if (streq (p[1], "SOCKS"))          { -#ifndef ENABLE_SOCKS -          msg (M_WARN, "SOCKS proxy support is not available"); -#else            ce->socks_proxy_server = string_alloc (p[2], gc);            ce->socks_proxy_port = p[3];            ret = true; -#endif          }      }    else @@ -440,41 +432,30 @@ init_query_passwords (struct context *c)   * Initialize/Uninitialize HTTP or SOCKS proxy   */ -#ifdef GENERAL_PROXY_SUPPORT -  static void  uninit_proxy_dowork (struct context *c)  { -#ifdef ENABLE_HTTP_PROXY    if (c->c1.http_proxy_owned && c->c1.http_proxy)      {        http_proxy_close (c->c1.http_proxy);        c->c1.http_proxy = NULL;        c->c1.http_proxy_owned = false;      } -#endif -#ifdef ENABLE_SOCKS    if (c->c1.socks_proxy_owned && c->c1.socks_proxy)      {        socks_proxy_close (c->c1.socks_proxy);        c->c1.socks_proxy = NULL;        c->c1.socks_proxy_owned = false;      } -#endif  }  static void  init_proxy_dowork (struct context *c)  { -#ifdef ENABLE_HTTP_PROXY    bool did_http = false; -#else -  const bool did_http = false; -#endif    uninit_proxy_dowork (c); -#ifdef ENABLE_HTTP_PROXY    if (c->options.ce.http_proxy_options)      {        /* Possible HTTP proxy user/pass input */ @@ -485,10 +466,8 @@ init_proxy_dowork (struct context *c)  	  c->c1.http_proxy_owned = true;  	}      } -#endif -#ifdef ENABLE_SOCKS -  if (!did_http && c->options.ce.socks_proxy_server) +    if (!did_http && c->options.ce.socks_proxy_server)      {        c->c1.socks_proxy = socks_proxy_new (c->options.ce.socks_proxy_server,  					   c->options.ce.socks_proxy_port, @@ -499,7 +478,6 @@ init_proxy_dowork (struct context *c)  	  c->c1.socks_proxy_owned = true;  	}      } -#endif  }  static void @@ -514,20 +492,6 @@ uninit_proxy (struct context *c)     uninit_proxy_dowork (c);  } -#else - -static inline void -init_proxy (struct context *c, const int scope) -{ -} - -static inline void -uninit_proxy (struct context *c) -{ -} - -#endif -  void  context_init_1 (struct context *c)  { @@ -871,7 +835,7 @@ print_openssl_info (const struct options *options)  #ifdef ENABLE_CRYPTO    if (options->show_ciphers || options->show_digests || options->show_engines  #ifdef ENABLE_SSL -      || options->show_tls_ciphers +      || options->show_tls_ciphers || options->show_curves  #endif      )      { @@ -884,6 +848,8 @@ print_openssl_info (const struct options *options)  #ifdef ENABLE_SSL        if (options->show_tls_ciphers)  	show_available_tls_ciphers (options->cipher_list); +      if (options->show_curves) +	show_available_curves();  #endif        return true;      } @@ -1860,14 +1826,10 @@ socket_restart_pause (struct context *c)    bool proxy = false;    int sec = 2; -#ifdef ENABLE_HTTP_PROXY    if (c->options.ce.http_proxy_options)      proxy = true; -#endif -#ifdef ENABLE_SOCKS    if (c->options.ce.socks_proxy_server)      proxy = true; -#endif    switch (c->options.ce.proto)      { @@ -2419,13 +2381,11 @@ do_init_frame (struct context *c)      }  #endif /* USE_COMP */ -#ifdef ENABLE_SOCKS    /*     * Adjust frame size for UDP Socks support.     */    if (c->options.ce.socks_proxy_server)      socks_adjust_frame_parameters (&c->c2.frame, c->options.ce.proto); -#endif    /*     * Adjust frame size based on the --tun-mtu-extra parameter. @@ -2697,12 +2657,8 @@ do_init_socket_1 (struct context *c, const int mode)  			   c->options.ce.bind_ipv6_only,  			   mode,  			   c->c2.accept_from, -#ifdef ENABLE_HTTP_PROXY  			   c->c1.http_proxy, -#endif -#ifdef ENABLE_SOCKS  			   c->c1.socks_proxy, -#endif  #ifdef ENABLE_DEBUG  			   c->options.gremlin,  #endif diff --git a/main/openvpn/src/openvpn/openvpn.c b/main/openvpn/src/openvpn/openvpn.c index c0f2a9a2..94d0167e 100644 --- a/main/openvpn/src/openvpn/openvpn.c +++ b/main/openvpn/src/openvpn/openvpn.c @@ -224,6 +224,7 @@ openvpn_main (int argc, char *argv[])  	  /* print version number */  	  msg (M_INFO, "%s", title_string); +	  show_library_versions(M_INFO);  	  /* misc stuff */  	  pre_setup (&c.options); diff --git a/main/openvpn/src/openvpn/openvpn.h b/main/openvpn/src/openvpn/openvpn.h index 4f9c4d11..eab8cd5b 100644 --- a/main/openvpn/src/openvpn/openvpn.h +++ b/main/openvpn/src/openvpn/openvpn.h @@ -188,17 +188,13 @@ struct context_1    struct status_output *status_output;    bool status_output_owned; -#ifdef ENABLE_HTTP_PROXY    /* HTTP proxy object */    struct http_proxy_info *http_proxy;    bool http_proxy_owned; -#endif -#ifdef ENABLE_SOCKS    /* SOCKS proxy object */    struct socks_proxy_info *socks_proxy;    bool socks_proxy_owned; -#endif  #if P2MP diff --git a/main/openvpn/src/openvpn/options.c b/main/openvpn/src/openvpn/options.c index b5fbb13e..f0e94770 100644 --- a/main/openvpn/src/openvpn/options.c +++ b/main/openvpn/src/openvpn/options.c @@ -139,7 +139,6 @@ static const char usage_message[] =    "                    between connection retries (default=%d).\n"    "--connect-timeout n : For --proto tcp-client, connection timeout (in seconds).\n"    "--connect-retry-max n : Maximum connection attempt retries, default infinite.\n" -#ifdef ENABLE_HTTP_PROXY    "--http-proxy s p [up] [auth] : Connect to remote host\n"    "                  through an HTTP proxy at address s and port p.\n"    "                  If proxy authentication is required,\n" @@ -155,15 +154,12 @@ static const char usage_message[] =    "                                  Repeat to set multiple options.\n"    "                  VERSION version (default=1.0)\n"    "                  AGENT user-agent\n" -#endif -#ifdef ENABLE_SOCKS    "--socks-proxy s [p] [up] : Connect to remote host through a Socks5 proxy at\n"    "                  address s and port p (default port = 1080).\n"    "                  If proxy authentication is required,\n"    "                  up is a file containing username/password on 2 lines, or\n"    "                  'stdin' to prompt for console.\n"    "--socks-proxy-retry : Retry indefinitely on Socks proxy errors.\n" -#endif    "--resolv-retry n: If hostname resolve fails for --remote, retry\n"    "                  resolve for n seconds before failing (disabled by default).\n"    "                  Set n=\"infinite\" to retry indefinitely.\n" @@ -176,12 +172,8 @@ static const char usage_message[] =    "--rport port    : TCP/UDP port # for remote (default=%s).\n"    "--bind          : Bind to local address and port. (This is the default unless\n"    "                  --proto tcp-client" -#ifdef ENABLE_HTTP_PROXY                     " or --http-proxy" -#endif -#ifdef ENABLE_SOCKS                     " or --socks-proxy" -#endif                     " is used).\n"    "--nobind        : Do not bind to local address and port.\n"    "--dev tunX|tapX : tun/tap device (X can be omitted for dynamic device.\n" @@ -852,6 +844,7 @@ init_options (struct options *o, const bool init_gc)    o->renegotiate_seconds = 3600;    o->handshake_window = 60;    o->transition_window = 3600; +  o->ecdh_curve = NULL;  #ifdef ENABLE_X509ALTUSERNAME    o->x509_username_field = X509_USERNAME_FIELD_DEFAULT;  #endif @@ -908,20 +901,16 @@ setenv_connection_entry (struct env_set *es,    setenv_str_i (es, "remote", e->remote, i);    setenv_str_i (es, "remote_port", e->remote_port, i); -#ifdef ENABLE_HTTP_PROXY    if (e->http_proxy_options)      {        setenv_str_i (es, "http_proxy_server", e->http_proxy_options->server, i);        setenv_str_i (es, "http_proxy_port", e->http_proxy_options->port, i);      } -#endif -#ifdef ENABLE_SOCKS    if (e->socks_proxy_server)      {        setenv_str_i (es, "socks_proxy_server", e->socks_proxy_server, i);        setenv_str_i (es, "socks_proxy_port", e->socks_proxy_port, i);      } -#endif  }  void @@ -1286,7 +1275,7 @@ option_iroute_ipv6 (struct options *o,  #endif /* P2MP_SERVER */  #endif /* P2MP */ -#if defined(ENABLE_HTTP_PROXY) && !defined(ENABLE_SMALL) +#ifndef ENABLE_SMALL  static void  show_http_proxy_options (const struct http_proxy_options *o)  { @@ -1361,15 +1350,11 @@ show_connection_entry (const struct connection_entry *o)    SHOW_INT (connect_retry_seconds);    SHOW_INT (connect_timeout); -#ifdef ENABLE_HTTP_PROXY    if (o->http_proxy_options)      show_http_proxy_options (o->http_proxy_options); -#endif -#ifdef ENABLE_SOCKS    SHOW_STR (socks_proxy_server);    SHOW_STR (socks_proxy_port);    SHOW_BOOL (socks_proxy_retry); -#endif    SHOW_INT (tun_mtu);    SHOW_BOOL (tun_mtu_defined);    SHOW_INT (link_mtu); @@ -1687,7 +1672,7 @@ show_settings (const struct options *o)  #undef SHOW_INT  #undef SHOW_BOOL -#if HTTP_PROXY_OVERRIDE +#ifdef ENABLE_MANAGEMENT  static struct http_proxy_options *  parse_http_proxy_override (const char *server, @@ -1976,22 +1961,16 @@ options_postprocess_verify_ce (const struct options *options, const struct conne    if (!ce->remote && ce->proto == PROTO_TCP_CLIENT)      msg (M_USAGE, "--remote MUST be used in TCP Client mode"); -#ifdef ENABLE_HTTP_PROXY    if ((ce->http_proxy_options) && ce->proto != PROTO_TCP_CLIENT)      msg (M_USAGE, "--http-proxy MUST be used in TCP Client mode (i.e. --proto tcp-client)");    if ((ce->http_proxy_options) && !ce->http_proxy_options->server)      msg (M_USAGE, "--http-proxy not specified but other http proxy options present"); -#endif -#if defined(ENABLE_HTTP_PROXY) && defined(ENABLE_SOCKS)    if (ce->http_proxy_options && ce->socks_proxy_server)      msg (M_USAGE, "--http-proxy can not be used together with --socks-proxy"); -#endif -#ifdef ENABLE_SOCKS    if (ce->socks_proxy_server && ce->proto == PROTO_TCP_SERVER)      msg (M_USAGE, "--socks-proxy can not be used in TCP Server mode"); -#endif    if (ce->proto == PROTO_TCP_SERVER && (options->connection_list->len > 1))      msg (M_USAGE, "TCP server mode allows at most one --remote address"); @@ -2025,14 +2004,10 @@ options_postprocess_verify_ce (const struct options *options, const struct conne  	msg (M_USAGE, "--remote cannot be used with --mode server");        if (!ce->bind_local)  	msg (M_USAGE, "--nobind cannot be used with --mode server"); -#ifdef ENABLE_HTTP_PROXY        if (ce->http_proxy_options)  	msg (M_USAGE, "--http-proxy cannot be used with --mode server"); -#endif -#ifdef ENABLE_SOCKS        if (ce->socks_proxy_server)  	msg (M_USAGE, "--socks-proxy cannot be used with --mode server"); -#endif        /* <connection> blocks force to have a remote embedded, so we check for the         * --remote and bail out if it  is present */         if (options->connection_list->len >1 || @@ -2374,10 +2349,8 @@ options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce)    if (ce->proto == PROTO_TCP_CLIENT && !ce->local && !ce->local_port_defined && !ce->bind_defined)      ce->bind_local = false; -#ifdef ENABLE_SOCKS    if (ce->proto == PROTO_UDP && ce->socks_proxy_server && !ce->local && !ce->local_port_defined && !ce->bind_defined)      ce->bind_local = false; -#endif    if (!ce->bind_local)      ce->local_port = NULL; @@ -2526,7 +2499,7 @@ options_postprocess_mutate (struct options *o)    for (i = 0; i < o->connection_list->len; ++i)  	options_postprocess_mutate_ce (o, o->connection_list->array[i]); -#if HTTP_PROXY_OVERRIDE +#if ENABLE_MANAGEMENT    if (o->http_proxy_override)  	options_postprocess_http_proxy_override(o);  #endif @@ -3427,10 +3400,28 @@ usage_small (void)    openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */  } +void +show_library_versions(const unsigned int flags) +{ +  msg (flags, "library versions: %s%s%s", +#ifdef ENABLE_SSL +			get_ssl_library_version(), +#else +			"", +#endif +#ifdef ENABLE_LZO +			", LZO ", lzo_version_string() +#else +			"", "" +#endif +	); +} +  static void  usage_version (void)  {    msg (M_INFO|M_NOPREFIX, "%s", title_string); +  show_library_versions( M_INFO|M_NOPREFIX );    msg (M_INFO|M_NOPREFIX, "Originally developed by James Yonan");    msg (M_INFO|M_NOPREFIX, "Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>");  #ifndef ENABLE_SMALL @@ -4477,7 +4468,7 @@ add_option (struct options *options,        options->ignore_unknown_option[i] = NULL;      } -#if HTTP_PROXY_OVERRIDE +#if ENABLE_MANAGEMENT    else if (streq (p[0], "http-proxy-override") && p[1] && p[2])      {        VERIFY_PERMISSION (OPT_P_GENERAL); @@ -4989,7 +4980,6 @@ add_option (struct options *options,  	}        options->proto_force = proto_force;      } -#ifdef ENABLE_HTTP_PROXY    else if (streq (p[0], "http-proxy") && p[1])      {        struct http_proxy_options *ho; @@ -5096,8 +5086,6 @@ add_option (struct options *options,  	  msg (msglevel, "Bad http-proxy-option or missing parameter: '%s'", p[1]);  	}      } -#endif -#ifdef ENABLE_SOCKS    else if (streq (p[0], "socks-proxy") && p[1])      {        VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION); @@ -5118,7 +5106,6 @@ add_option (struct options *options,        VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);        options->ce.socks_proxy_retry = true;      } -#endif    else if (streq (p[0], "keepalive") && p[1] && p[2])      {        VERIFY_PERMISSION (OPT_P_GENERAL); @@ -6488,6 +6475,16 @@ add_option (struct options *options,        VERIFY_PERMISSION (OPT_P_GENERAL);        options->show_tls_ciphers = true;      } +  else if (streq (p[0], "show-curves")) +    { +      VERIFY_PERMISSION (OPT_P_GENERAL); +      options->show_curves = true; +    } +  else if (streq (p[0], "ecdh-curve") && p[1]) +    { +      VERIFY_PERMISSION (OPT_P_CRYPTO); +      options->ecdh_curve= p[1]; +    }    else if (streq (p[0], "tls-server"))      {        VERIFY_PERMISSION (OPT_P_GENERAL); diff --git a/main/openvpn/src/openvpn/options.h b/main/openvpn/src/openvpn/options.h index 7bc8d1f0..06874ccd 100644 --- a/main/openvpn/src/openvpn/options.h +++ b/main/openvpn/src/openvpn/options.h @@ -98,15 +98,11 @@ struct connection_entry    int connect_retry_seconds;    int connect_timeout;    bool connect_timeout_defined; -#ifdef ENABLE_HTTP_PROXY    struct http_proxy_options *http_proxy_options; -#endif   -#ifdef ENABLE_SOCKS    const char *socks_proxy_server;    const char *socks_proxy_port;    const char *socks_proxy_authfile;    bool socks_proxy_retry; -#endif    int tun_mtu;           /* MTU of tun device */    bool tun_mtu_defined;  /* true if user overriding parm with command line option */ @@ -199,6 +195,7 @@ struct options    bool show_engines;  #ifdef ENABLE_SSL    bool show_tls_ciphers; +  bool show_curves;  #endif    bool genkey;  #endif @@ -214,7 +211,7 @@ struct options    /* Counts the number of unsuccessful connection attempts */    unsigned int unsuccessful_attempts; -#if HTTP_PROXY_OVERRIDE +#if ENABLE_MANAGEMENT    struct http_proxy_options *http_proxy_override;  #endif @@ -508,6 +505,7 @@ struct options    const char *priv_key_file;    const char *pkcs12_file;    const char *cipher_list; +  const char *ecdh_curve;    const char *tls_verify;    int verify_x509_type;    const char *verify_x509_name; diff --git a/main/openvpn/src/openvpn/pkcs11_polarssl.c b/main/openvpn/src/openvpn/pkcs11_polarssl.c index 03b2bab5..be4e9737 100644 --- a/main/openvpn/src/openvpn/pkcs11_polarssl.c +++ b/main/openvpn/src/openvpn/pkcs11_polarssl.c @@ -40,6 +40,7 @@  #include "errlevel.h"  #include "pkcs11_backend.h"  #include <polarssl/pkcs11.h> +#include <polarssl/x509.h>  int  pkcs11_init_tls_session(pkcs11h_certificate_t certificate, @@ -78,14 +79,14 @@ pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc)    char *ret = NULL;    char dn[1024] = {0}; -  x509_cert polar_cert = {0}; +  x509_crt polar_cert = {0};    if (pkcs11_x509_cert_init(&polar_cert, cert)) {        msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");        goto cleanup;    } -  if (-1 == x509parse_dn_gets (dn, sizeof(dn), &polar_cert.subject)) { +  if (-1 == x509_dn_gets (dn, sizeof(dn), &polar_cert.subject)) {        msg (M_FATAL, "PKCS#11: PolarSSL cannot parse subject");        goto cleanup;    } @@ -93,7 +94,7 @@ pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc)    ret = string_alloc(dn, gc);  cleanup: -  x509_free(&polar_cert); +  x509_crt_free(&polar_cert);    return ret;  } @@ -104,14 +105,14 @@ pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial,  {    int ret = 1; -  x509_cert polar_cert = {0}; +  x509_crt polar_cert = {0};    if (pkcs11_x509_cert_init(&polar_cert, cert)) {        msg (M_FATAL, "PKCS#11: Cannot retrieve PolarSSL certificate object");        goto cleanup;    } -  if (-1 == x509parse_serial_gets (serial, serial_len, &polar_cert.serial)) { +  if (-1 == x509_serial_gets (serial, serial_len, &polar_cert.serial)) {        msg (M_FATAL, "PKCS#11: PolarSSL cannot parse serial");        goto cleanup;    } @@ -119,7 +120,7 @@ pkcs11_certificate_serial (pkcs11h_certificate_t cert, char *serial,    ret = 0;  cleanup: -  x509_free(&polar_cert); +  x509_crt_free(&polar_cert);    return ret;  } diff --git a/main/openvpn/src/openvpn/proxy.c b/main/openvpn/src/openvpn/proxy.c index f7f06487..2568e191 100644 --- a/main/openvpn/src/openvpn/proxy.c +++ b/main/openvpn/src/openvpn/proxy.c @@ -42,8 +42,6 @@  #include "ntlm.h"  #include "memdbg.h" -#ifdef ENABLE_HTTP_PROXY -  #define UP_TYPE_PROXY        "HTTP Proxy"  struct http_proxy_options * @@ -945,8 +943,3 @@ establish_http_proxy_passthru (struct http_proxy_info *p,    gc_free (&gc);    return ret;  } - -#else -static void dummy(void) {} -#endif /* ENABLE_HTTP_PROXY */ - diff --git a/main/openvpn/src/openvpn/proxy.h b/main/openvpn/src/openvpn/proxy.h index 0e7a6dfb..4715940c 100644 --- a/main/openvpn/src/openvpn/proxy.h +++ b/main/openvpn/src/openvpn/proxy.h @@ -28,8 +28,6 @@  #include "buffer.h"  #include "misc.h" -#ifdef ENABLE_HTTP_PROXY -  /* HTTP CONNECT authentication methods */  #define HTTP_AUTH_NONE   0  #define HTTP_AUTH_BASIC  1 @@ -94,6 +92,4 @@ bool establish_http_proxy_passthru (struct http_proxy_info *p,  uint8_t *make_base64_string2 (const uint8_t *str, int str_len, struct gc_arena *gc);  uint8_t *make_base64_string (const uint8_t *str, struct gc_arena *gc); -#endif /* ENABLE_HTTP_PROXY */ -  #endif /* PROXY_H */ diff --git a/main/openvpn/src/openvpn/push.c b/main/openvpn/src/openvpn/push.c index 26f59987..92e3abbb 100644 --- a/main/openvpn/src/openvpn/push.c +++ b/main/openvpn/src/openvpn/push.c @@ -67,6 +67,7 @@ receive_auth_failed (struct context *c, const struct buffer *buffer)  	  ASSERT (0);  	}        c->sig->signal_text = "auth-failure"; +#ifdef ENABLE_MANAGEMENT        if (management)  	{  	  const char *reason = NULL; @@ -75,6 +76,7 @@ receive_auth_failed (struct context *c, const struct buffer *buffer)  	    reason = BSTR (&buf);  	  management_auth_failure (management, UP_TYPE_AUTH, reason);  	} else +#endif  	{  #ifdef ENABLE_CLIENT_CR  	  struct buffer buf = *buffer; diff --git a/main/openvpn/src/openvpn/route.c b/main/openvpn/src/openvpn/route.c index e4224e19..7ea791b8 100644 --- a/main/openvpn/src/openvpn/route.c +++ b/main/openvpn/src/openvpn/route.c @@ -2011,10 +2011,16 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne      argv_printf_cat (&argv, "METRIC %d", r->metric);  #endif +  /* Windows XP to 7 "just delete" routes, wherever they came from, but +   * in Windows 8(.1?), if you create them with "store=active", this is +   * how you should delete them as well (pointed out by Cedric Tabary) +   */ +  argv_printf_cat( &argv, " store=active" ); +    argv_msg (D_ROUTE, &argv);    netcmd_semaphore_lock (); -  openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed"); +  openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete ipv6 command failed");    netcmd_semaphore_release ();  #elif defined (TARGET_SOLARIS) @@ -2170,7 +2176,7 @@ test_routes (const struct route_list *rl, const struct tuntap *tt)        if (rl)  	{ -	  struct route *r; +	  struct route_ipv4 *r;  	  for (r = rl->routes, len = 0; r; r = r->next, ++len)  	    test_route_helper (&ret, &count, &good, &ambig, adapters, r->gateway); diff --git a/main/openvpn/src/openvpn/socket.c b/main/openvpn/src/openvpn/socket.c index b769171c..6f822e7d 100644 --- a/main/openvpn/src/openvpn/socket.c +++ b/main/openvpn/src/openvpn/socket.c @@ -775,7 +775,6 @@ create_socket_tcp (struct addrinfo* addrinfo)    ASSERT (addrinfo);    ASSERT (addrinfo->ai_socktype == SOCK_STREAM); -  ASSERT (addrinfo->ai_protocol == IPPROTO_TCP);    if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0)      msg (M_ERR, "Cannot create TCP socket"); @@ -800,7 +799,6 @@ create_socket_udp (struct addrinfo* addrinfo, const unsigned int flags)    ASSERT (addrinfo);    ASSERT (addrinfo->ai_socktype == SOCK_DGRAM); -  ASSERT (addrinfo->ai_protocol == IPPROTO_UDP);    if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0)      msg (M_ERR, "UDP: Cannot create UDP/UDP6 socket"); @@ -843,12 +841,10 @@ static void bind_local (struct link_socket *sock, const sa_family_t ai_family)      /* bind to local address/port */      if (sock->bind_local)        { -#ifdef ENABLE_SOCKS          if (sock->socks_proxy && sock->info.proto == PROTO_UDP)              socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local,  			 ai_family, "SOCKS", false);          else -#endif              socket_bind (sock->sd, sock->info.lsa->bind_local,  			 ai_family,                           "TCP/UDP", sock->info.bind_ipv6_only); @@ -858,12 +854,11 @@ static void bind_local (struct link_socket *sock, const sa_family_t ai_family)  static void  create_socket (struct link_socket* sock, struct addrinfo* addr)  { -  if (addr->ai_protocol == IPPROTO_UDP) +  if (addr->ai_protocol == IPPROTO_UDP || addr->ai_socktype == SOCK_DGRAM)      {        sock->sd = create_socket_udp (addr, sock->sockflags);        sock->sockflags |= SF_GETADDRINFO_DGRAM; -#ifdef ENABLE_SOCKS        /* Assume that control socket and data socket to the socks proxy         * are using the same IP family */        if (sock->socks_proxy) @@ -876,9 +871,8 @@ create_socket (struct link_socket* sock, struct addrinfo* addr)  	  addrinfo_tmp.ai_protocol = IPPROTO_TCP;  	  sock->ctrl_sd = create_socket_tcp (&addrinfo_tmp);  	} -#endif      } -  else if (addr->ai_protocol == IPPROTO_TCP) +  else if (addr->ai_protocol == IPPROTO_TCP || addr->ai_socktype == SOCK_STREAM)      {        sock->sd = create_socket_tcp (addr);      } @@ -917,15 +911,16 @@ static void protect_fd_nonlocal (int fd, const struct sockaddr* addr)   */  static void  socket_do_listen (socket_descriptor_t sd, -		  const struct sockaddr *local, +		  const struct addrinfo *local,  		  bool do_listen,  		  bool do_set_nonblock)  {    struct gc_arena gc = gc_new ();    if (do_listen)      { +      ASSERT(local);        msg (M_INFO, "Listening for incoming TCP connection on %s",  -	   print_sockaddr (local, &gc)); +	   print_sockaddr (local->ai_addr, &gc));        if (listen (sd, 1))  	msg (M_ERR, "TCP: listen() failed");      } @@ -1018,7 +1013,7 @@ socket_listen_accept (socket_descriptor_t sd,    int new_sd = SOCKET_UNDEFINED;    CLEAR (*act); -  socket_do_listen (sd, local->ai_addr, do_listen, true); +  socket_do_listen (sd, local, do_listen, true);    while (true)      { @@ -1053,7 +1048,7 @@ socket_listen_accept (socket_descriptor_t sd,        if (socket_defined (new_sd))  	{ -          struct addrinfo* ai; +          struct addrinfo* ai = NULL;            if(remote_dynamic)                openvpn_getaddrinfo(0, remote_dynamic, NULL, 1, NULL,                                      remote_verify.addr.sa.sa_family, &ai); @@ -1495,9 +1490,7 @@ link_socket_new (void)    ALLOC_OBJ_CLEAR (sock, struct link_socket);    sock->sd = SOCKET_UNDEFINED; -#ifdef ENABLE_SOCKS    sock->ctrl_sd = SOCKET_UNDEFINED; -#endif    return sock;  } @@ -1513,12 +1506,8 @@ link_socket_init_phase1 (struct link_socket *sock,  			 bool bind_ipv6_only,  			 int mode,  			 const struct link_socket *accept_from, -#ifdef ENABLE_HTTP_PROXY  			 struct http_proxy_info *http_proxy, -#endif -#ifdef ENABLE_SOCKS  			 struct socks_proxy_info *socks_proxy, -#endif  #ifdef ENABLE_DEBUG  			 int gremlin,  #endif @@ -1543,15 +1532,8 @@ link_socket_init_phase1 (struct link_socket *sock,    sock->remote_host = remote_host;    sock->remote_port = remote_port;    sock->dns_cache = dns_cache; - -#ifdef ENABLE_HTTP_PROXY    sock->http_proxy = http_proxy; -#endif - -#ifdef ENABLE_SOCKS    sock->socks_proxy = socks_proxy; -#endif -    sock->bind_local = bind_local;    sock->inetd = inetd;    sock->resolve_retry_seconds = resolve_retry_seconds; @@ -1587,7 +1569,6 @@ link_socket_init_phase1 (struct link_socket *sock,    if (false)      ; -#ifdef ENABLE_HTTP_PROXY    /* are we running in HTTP proxy mode? */    else if (sock->http_proxy)      { @@ -1602,8 +1583,6 @@ link_socket_init_phase1 (struct link_socket *sock,        sock->proxy_dest_host = remote_host;        sock->proxy_dest_port = remote_port;      } -#endif -#ifdef ENABLE_SOCKS    /* or in Socks proxy mode? */    else if (sock->socks_proxy)      { @@ -1617,7 +1596,6 @@ link_socket_init_phase1 (struct link_socket *sock,        sock->proxy_dest_host = remote_host;        sock->proxy_dest_port = remote_port;      } -#endif    else      {        sock->remote_host = remote_host; @@ -1703,10 +1681,8 @@ phase2_set_socket_flags (struct link_socket* sock)       scripts don't have access to it */    set_cloexec (sock->sd); -#ifdef ENABLE_SOCKS    if (socket_defined (sock->ctrl_sd))      set_cloexec (sock->ctrl_sd); -#endif    /* set Path MTU discovery options on the socket */    set_mtu_discover_type (sock->sd, sock->mtu_discover_type); @@ -1775,7 +1751,7 @@ phase2_tcp_server (struct link_socket *sock, const char *remote_dynamic,        break;      case LS_MODE_TCP_LISTEN:        socket_do_listen (sock->sd, -			sock->info.lsa->bind_local->ai_addr, +			sock->info.lsa->bind_local,  			true,  			false);        break; @@ -1799,13 +1775,8 @@ phase2_tcp_server (struct link_socket *sock, const char *remote_dynamic,  static void  phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)  { -#ifdef GENERAL_PROXY_SUPPORT    bool proxy_retry = false; -#else -  const bool proxy_retry = false; -#endif    do { -    ASSERT (sock->info.lsa->current_remote->ai_protocol == IPPROTO_TCP);      socket_connect (&sock->sd,                     sock->info.lsa->current_remote->ai_addr,                     sock->connect_timeout, @@ -1816,7 +1787,6 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)      if (false)        ; -#ifdef ENABLE_HTTP_PROXY      else if (sock->http_proxy)        {  	proxy_retry = establish_http_proxy_passthru (sock->http_proxy, @@ -1826,8 +1796,6 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)  						     &sock->stream_buf.residual,  						     &sig_info->signal_received);        } -#endif -#ifdef ENABLE_SOCKS      else if (sock->socks_proxy)        {  	establish_socks_proxy_passthru (sock->socks_proxy, @@ -1836,7 +1804,6 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)  					sock->proxy_dest_port,  					&sig_info->signal_received);        } -#endif      if (proxy_retry)        {  	openvpn_close_socket (sock->sd); @@ -1847,7 +1814,6 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)  } -#ifdef ENABLE_SOCKS  static void  phase2_socks_client (struct link_socket *sock, struct signal_info *sig_info)  { @@ -1881,7 +1847,6 @@ phase2_socks_client (struct link_socket *sock, struct signal_info *sig_info)      resolve_remote (sock, 1, NULL, &sig_info->signal_received);  } -#endif  /* finalize socket initialization */  void @@ -1967,11 +1932,9 @@ link_socket_init_phase2 (struct link_socket *sock,  	  phase2_tcp_client (sock, sig_info);  	} -#ifdef ENABLE_SOCKS        else if (sock->info.proto == PROTO_UDP && sock->socks_proxy)  	{  	  phase2_socks_client (sock, sig_info); -#endif  	}  #ifdef TARGET_ANDROID        if (sock->sd != -1) @@ -2024,14 +1987,12 @@ link_socket_close (struct link_socket *sock)  #endif  	} -#ifdef ENABLE_SOCKS        if (socket_defined (sock->ctrl_sd))  	{  	  if (openvpn_close_socket (sock->ctrl_sd))  	    msg (M_WARN | M_ERRNO, "TCP/UDP: Close Socket (ctrl_sd) failed");  	  sock->ctrl_sd = SOCKET_UNDEFINED;  	} -#endif        stream_buf_close (&sock->stream_buf);        free_buf (&sock->stream_buf_data); diff --git a/main/openvpn/src/openvpn/socket.h b/main/openvpn/src/openvpn/socket.h index f27e9a9a..8e157c67 100644 --- a/main/openvpn/src/openvpn/socket.h +++ b/main/openvpn/src/openvpn/socket.h @@ -172,10 +172,7 @@ struct link_socket    struct link_socket_info info;    socket_descriptor_t sd; - -#ifdef ENABLE_SOCKS    socket_descriptor_t ctrl_sd;  /* only used for UDP over Socks */ -#endif  #ifdef WIN32    struct overlapped_io reads; @@ -228,22 +225,16 @@ struct link_socket    struct buffer stream_buf_data;    bool stream_reset; -#ifdef ENABLE_HTTP_PROXY    /* HTTP proxy */    struct http_proxy_info *http_proxy; -#endif -#ifdef ENABLE_SOCKS    /* Socks proxy */    struct socks_proxy_info *socks_proxy;    struct link_socket_actual socks_relay; /* Socks UDP relay address */ -#endif -#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS)    /* The OpenVPN server we will use the proxy to connect to */    const char *proxy_dest_host;    const char *proxy_dest_port; -#endif  #if PASSTOS_CAPABILITY    /* used to get/set TOS. */ @@ -321,12 +312,8 @@ link_socket_init_phase1 (struct link_socket *sock,  			 bool bind_ipv6_only,  			 int mode,  			 const struct link_socket *accept_from, -#ifdef ENABLE_HTTP_PROXY  			 struct http_proxy_info *http_proxy, -#endif -#ifdef ENABLE_SOCKS  			 struct socks_proxy_info *socks_proxy, -#endif  #ifdef ENABLE_DEBUG  			 int gremlin,  #endif @@ -524,7 +511,7 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *  #define GETADDR_PASSIVE               (1<<10)  #define GETADDR_DATAGRAM              (1<<11) -#define GETADDR_CACHE_MASK		GETADDR_DATAGRAM|GETADDR_PASSIVE +#define GETADDR_CACHE_MASK		(GETADDR_DATAGRAM|GETADDR_PASSIVE)  in_addr_t getaddr (unsigned int flags,  		   const char *hostname, diff --git a/main/openvpn/src/openvpn/socks.c b/main/openvpn/src/openvpn/socks.c index 1551da84..72bdf550 100644 --- a/main/openvpn/src/openvpn/socks.c +++ b/main/openvpn/src/openvpn/socks.c @@ -38,8 +38,6 @@  #include "syshead.h" -#ifdef ENABLE_SOCKS -  #include "common.h"  #include "misc.h"  #include "win32.h" @@ -189,10 +187,15 @@ socks_handshake (struct socks_proxy_info *p,    char buf[2];    int len = 0;    const int timeout_sec = 5; +  ssize_t size; -  /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */ -  const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL); -  if (size != 4) +  /* VER = 5, NMETHODS = 1, METHODS = [0 (no auth)] */ +  char method_sel[3] = { 0x05, 0x01, 0x00 }; +  if (p->authfile[0]) +      method_sel[2] = 0x02; /* METHODS = [2 (plain login)] */ + +  size = send (sd, method_sel, sizeof (method_sel), MSG_NOSIGNAL); +  if (size != sizeof (method_sel))      {        msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write failed on send()");        return false; @@ -252,6 +255,13 @@ socks_handshake (struct socks_proxy_info *p,        return false;      } +  /* validate that the auth method returned is the one sent */ +  if (buf[1] != method_sel[2]) +    { +      msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned unexpected auth"); +      return false; +    } +    /* select the appropriate authentication method */    switch (buf[1])      { @@ -562,7 +572,3 @@ socks_process_outgoing_udp (struct buffer *buf,    return 10;  } - -#else -static void dummy(void) {} -#endif /* ENABLE_SOCKS */ diff --git a/main/openvpn/src/openvpn/socks.h b/main/openvpn/src/openvpn/socks.h index 30b957d7..2475261f 100644 --- a/main/openvpn/src/openvpn/socks.h +++ b/main/openvpn/src/openvpn/socks.h @@ -30,8 +30,6 @@  #ifndef SOCKS_H  #define SOCKS_H -#ifdef ENABLE_SOCKS -  #include "buffer.h"  struct openvpn_sockaddr; @@ -74,4 +72,3 @@ int socks_process_outgoing_udp (struct buffer *buf,  				const struct link_socket_actual *to);  #endif -#endif diff --git a/main/openvpn/src/openvpn/ssl.c b/main/openvpn/src/openvpn/ssl.c index d4acc0fc..9bcb2acb 100644 --- a/main/openvpn/src/openvpn/ssl.c +++ b/main/openvpn/src/openvpn/ssl.c @@ -555,6 +555,10 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)        tls_ctx_load_extra_certs(new_ctx, options->extra_certs_file, options->extra_certs_file_inline);      } +  /* Once keys and cert are loaded, load ECDH parameters */ +  if (options->tls_server) +    tls_ctx_load_ecdh_params(new_ctx, options->ecdh_curve); +    /* Allowable ciphers */    tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); @@ -1835,6 +1839,7 @@ push_peer_info(struct buffer *buf, struct tls_session *session)  	  get_default_gateway (&rgi);  	  if (rgi.flags & RGI_HWADDR_DEFINED)  	    buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (rgi.hwaddr, 6, 0, 1, ":", &gc)); +	  buf_printf (&out, "IV_SSL=%s\n", get_ssl_library_version() );          }        /* push env vars that begin with UV_ and IV_GUI_VER */ diff --git a/main/openvpn/src/openvpn/ssl_backend.h b/main/openvpn/src/openvpn/ssl_backend.h index a6fc3bdb..37a458cc 100644 --- a/main/openvpn/src/openvpn/ssl_backend.h +++ b/main/openvpn/src/openvpn/ssl_backend.h @@ -186,6 +186,16 @@ void tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file,      const char *dh_file_inline);  /** + * Load Elliptic Curve Parameters, and load them into the library-specific + * TLS context. + * + * @param ctx          TLS context to use + * @param curve_name   The name of the elliptic curve to load. + */ +void tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name +    ); + +/**   * Load PKCS #12 file for key, cert and (optionally) CA certs, and add to   * library-specific TLS context.   * @@ -461,9 +471,20 @@ void print_details (struct key_state_ssl * ks_ssl, const char *prefix);  void show_available_tls_ciphers (const char *tls_ciphers);  /* + * Show the available elliptic curves in the crypto library + */ +void show_available_curves (void); + +/*   * The OpenSSL library has a notion of preference in TLS ciphers.  Higher   * preference == more secure. Return the highest preference cipher.   */  void get_highest_preference_tls_cipher (char *buf, int size); +/** + * return a pointer to a static memory area containing the + * name and version number of the SSL library in use + */ +char * get_ssl_library_version(void); +  #endif /* SSL_BACKEND_H_ */ diff --git a/main/openvpn/src/openvpn/ssl_openssl.c b/main/openvpn/src/openvpn/ssl_openssl.c index 0b63e260..5ab34151 100644 --- a/main/openvpn/src/openvpn/ssl_openssl.c +++ b/main/openvpn/src/openvpn/ssl_openssl.c @@ -56,6 +56,7 @@  #include <openssl/pkcs12.h>  #include <openssl/x509.h>  #include <openssl/crypto.h> +#include <openssl/ec.h>  /*   * Allocate space in SSL objects in which to store a struct tls_session @@ -329,6 +330,73 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,    DH_free (dh);  } +void +tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name +    ) +{ +  int nid = NID_undef; +  EC_KEY *ecdh = NULL; +  const char *sname = NULL; + +  /* Generate a new ECDH key for each SSL session (for non-ephemeral ECDH) */ +  SSL_CTX_set_options(ctx->ctx, SSL_OP_SINGLE_ECDH_USE); +#if OPENSSL_VERSION_NUMBER >= 0x10002000L +  /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter loading */ +  if (NULL == curve_name) { +    SSL_CTX_set_ecdh_auto(ctx->ctx, 1); +    return; +  } +#endif +  /* For older OpenSSL, we'll have to do the parameter loading on our own */ +  if (curve_name != NULL) +    { +      /* Use user supplied curve if given */ +      msg (D_TLS_DEBUG, "Using user specified ECDH curve (%s)", curve_name); +      nid = OBJ_sn2nid(curve_name); +    } +  else +    { +      /* Extract curve from key */ +      EC_KEY *eckey = NULL; +      const EC_GROUP *ecgrp = NULL; +      EVP_PKEY *pkey = NULL; + +      /* Little hack to get private key ref from SSL_CTX, yay OpenSSL... */ +      SSL ssl; +      ssl.cert = ctx->ctx->cert; +      pkey = SSL_get_privatekey(&ssl); + +      msg (D_TLS_DEBUG, "Extracting ECDH curve from private key"); + +      if (pkey != NULL && (eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL && +          (ecgrp = EC_KEY_get0_group(eckey)) != NULL) +        nid = EC_GROUP_get_curve_name(ecgrp); +    } + +  /* Translate NID back to name , just for kicks */ +  sname = OBJ_nid2sn(nid); +  if (sname == NULL) sname = "(Unknown)"; + +  /* Create new EC key and set as ECDH key */ +  if (NID_undef == nid || NULL == (ecdh = EC_KEY_new_by_curve_name(nid))) +    { +      /* Creating key failed, fall back on sane default */ +      ecdh = EC_KEY_new_by_curve_name(NID_secp384r1); +      const char *source = (NULL == curve_name) ? +          "extract curve from certificate" : "use supplied curve"; +      msg (D_TLS_DEBUG_LOW, +          "Failed to %s (%s), using secp384r1 instead.", source, sname); +      sname = OBJ_nid2sn(NID_secp384r1); +    } + +  if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh)) +    msg (M_SSLERR, "SSL_CTX_set_tmp_ecdh: cannot add curve"); + +  msg (D_TLS_DEBUG_LOW, "ECDH curve %s added", sname); + +  EC_KEY_free(ecdh); +} +  int  tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,      const char *pkcs12_file_inline, @@ -1299,6 +1367,45 @@ show_available_tls_ciphers (const char *cipher_list)    SSL_CTX_free (tls_ctx.ctx);  } +/* + * Show the Elliptic curves that are available for us to use + * in the OpenSSL library. + */ +void +show_available_curves() +{ +  EC_builtin_curve *curves = NULL; +  size_t crv_len = 0; +  size_t n = 0; + +  crv_len = EC_get_builtin_curves(NULL, 0); + +  curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len)); + +  if (curves == NULL) +    msg (M_SSLERR, "Cannot create EC_builtin_curve object"); +  else +  { +    if (EC_get_builtin_curves(curves, crv_len)) +    { +      printf ("Available Elliptic curves:\n"); +      for (n = 0; n < crv_len; n++) +      { +        const char *sname; +        sname   = OBJ_nid2sn(curves[n].nid); +        if (sname == NULL) sname = ""; + +        printf("%s\n", sname); +      } +    } +    else +    { +      msg (M_SSLERR, "Cannot get list of builtin curves"); +    } +    OPENSSL_free(curves); +  } +} +  void  get_highest_preference_tls_cipher (char *buf, int size)  { @@ -1320,4 +1427,10 @@ get_highest_preference_tls_cipher (char *buf, int size)    SSL_CTX_free (ctx);  } +char * +get_ssl_library_version(void) +{ +    return SSLeay_version(SSLEAY_VERSION); +} +  #endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) */ diff --git a/main/openvpn/src/openvpn/ssl_polarssl.c b/main/openvpn/src/openvpn/ssl_polarssl.c index 9dc4e879..79c5087b 100644 --- a/main/openvpn/src/openvpn/ssl_polarssl.c +++ b/main/openvpn/src/openvpn/ssl_polarssl.c @@ -45,12 +45,12 @@  #include "manage.h"  #include "ssl_common.h" -#include <polarssl/sha2.h>  #include <polarssl/havege.h>  #include "ssl_verify_polarssl.h"  #include <polarssl/error.h>  #include <polarssl/pem.h> +#include <polarssl/sha256.h>  void  tls_init_lib() @@ -74,10 +74,10 @@ tls_ctx_server_new(struct tls_root_ctx *ctx)    CLEAR(*ctx);    ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context); -  ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context); +  ALLOC_OBJ_CLEAR(ctx->priv_key, pk_context); -  ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_cert); -  ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_cert); +  ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_crt); +  ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_crt);    ctx->endpoint = SSL_IS_SERVER; @@ -91,10 +91,10 @@ tls_ctx_client_new(struct tls_root_ctx *ctx)    CLEAR(*ctx);    ALLOC_OBJ_CLEAR(ctx->dhm_ctx, dhm_context); -  ALLOC_OBJ_CLEAR(ctx->priv_key, rsa_context); +  ALLOC_OBJ_CLEAR(ctx->priv_key, pk_context); -  ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_cert); -  ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_cert); +  ALLOC_OBJ_CLEAR(ctx->ca_chain, x509_crt); +  ALLOC_OBJ_CLEAR(ctx->crt_chain, x509_crt);    ctx->endpoint = SSL_IS_CLIENT;    ctx->initialised = true; @@ -105,13 +105,13 @@ tls_ctx_free(struct tls_root_ctx *ctx)  {    if (ctx)      { -      rsa_free(ctx->priv_key); +      pk_free(ctx->priv_key);        free(ctx->priv_key); -      x509_free(ctx->ca_chain); +      x509_crt_free(ctx->ca_chain);        free(ctx->ca_chain); -      x509_free(ctx->crt_chain); +      x509_crt_free(ctx->crt_chain);        free(ctx->crt_chain);        dhm_free(ctx->dhm_ctx); @@ -215,12 +215,12 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,  {    if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline)      { -      if (0 != x509parse_dhm(ctx->dhm_ctx, dh_file_inline, strlen(dh_file_inline))) +      if (0 != dhm_parse_dhm(ctx->dhm_ctx, dh_file_inline, strlen(dh_file_inline)))  	msg (M_FATAL, "Cannot read inline DH parameters");    }  else    { -    if (0 != x509parse_dhmfile(ctx->dhm_ctx, dh_file)) +    if (0 != dhm_parse_dhmfile(ctx->dhm_ctx, dh_file))        msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file);    } @@ -228,6 +228,13 @@ else        (counter_type) 8 * mpi_size(&ctx->dhm_ctx->P));  } +void +tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name +    ) +{ +    msg(M_WARN, "Elliptic Curves not yet supported by PolarSSL"); +} +  int  tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,      const char *pkcs12_file_inline, @@ -255,14 +262,19 @@ tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,    if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline)      { -      if (0 != x509parse_crt(ctx->crt_chain, cert_file_inline, +      if (0 != x509_crt_parse(ctx->crt_chain, cert_file_inline,  	  strlen(cert_file_inline)))          msg (M_FATAL, "Cannot load inline certificate file");      }    else      { -      if (0 != x509parse_crtfile(ctx->crt_chain, cert_file)) -	msg (M_FATAL, "Cannot load certificate file %s", cert_file); +      int retval = x509_crt_parse_file(ctx->crt_chain, cert_file); +      if (0 != retval) +	{ +	  char errstr[128]; +	  polarssl_strerror(retval, errstr, sizeof(errstr)); +	  msg (M_FATAL, "Cannot load certificate file %s (%s)", cert_file, errstr); +	}      }  } @@ -276,26 +288,27 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,    if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline)      { -      status = x509parse_key(ctx->priv_key, +      status = pk_parse_key(ctx->priv_key,  	  priv_key_file_inline, strlen(priv_key_file_inline),  	  NULL, 0); +        if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status)  	{  	  char passbuf[512] = {0};  	  pem_password_callback(passbuf, 512, 0, NULL); -	  status = x509parse_key(ctx->priv_key, +	  status = pk_parse_key(ctx->priv_key,  	      priv_key_file_inline, strlen(priv_key_file_inline),  	      (unsigned char *) passbuf, strlen(passbuf));  	}      }    else      { -      status = x509parse_keyfile(ctx->priv_key, priv_key_file, NULL); +      status = pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL);        if (POLARSSL_ERR_PEM_PASSWORD_REQUIRED == status)  	{  	  char passbuf[512] = {0};  	  pem_password_callback(passbuf, 512, 0, NULL); -	  status = x509parse_keyfile(ctx->priv_key, priv_key_file, passbuf); +	  status = pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf);  	}      }    if (0 != status) @@ -338,30 +351,48 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,    /* Most of the initialization happens in key_state_ssl_init() */    ALLOC_OBJ_CLEAR (ctx->external_key, struct external_context); -  ctx->external_key->signature_length = ctx->crt_chain->rsa.len; +  ctx->external_key->signature_length = pk_get_len(&ctx->crt_chain->pk);    return 1;  } +/** + * external_pkcs1_sign implements a PolarSSL rsa_sign_func callback, that uses + * the management interface to request an RSA signature for the supplied hash. + * + * @param ctx_voidptr   Management external key context. + * @param f_rng         (Unused) + * @param p_rng         (Unused) + * @param mode          RSA mode (should be RSA_PRIVATE). + * @param md_alg        Message digest ('hash') algorithm type. + * @param hashlen       Length of hash (overridden by length specified by md_alg + *                      if md_alg != POLARSSL_MD_NONE). + * @param hash          The digest ('hash') to sign. Should have a size + *                      matching the length of md_alg (if != POLARSSL_MD_NONE), + *                      or hashlen otherwise. + * @param sig           Buffer that returns the signature. Should be at least of + *                      size ctx->signature_length. + * + * @return 0 on success, non-zero polarssl error code on failure. + */  static inline int external_pkcs1_sign( void *ctx_voidptr,      int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, -    int hash_id, unsigned int hashlen, const unsigned char *hash, +    md_type_t md_alg, unsigned int hashlen, const unsigned char *hash,      unsigned char *sig )  {    struct external_context * const ctx = ctx_voidptr;    char *in_b64 = NULL;    char *out_b64 = NULL;    int rv; -  unsigned char * const p = sig; -  size_t asn_len; +  unsigned char *p = sig; +  size_t asn_len = 0, oid_size = 0, sig_len = 0; +  const char *oid = NULL; -  ASSERT(NULL != ctx); +  if( NULL == ctx ) +    return POLARSSL_ERR_RSA_BAD_INPUT_DATA; -  if (RSA_PRIVATE != mode) -    { -      rv = POLARSSL_ERR_RSA_BAD_INPUT_DATA; -      goto done; -    } +  if( RSA_PRIVATE != mode ) +    return POLARSSL_ERR_RSA_BAD_INPUT_DATA;    /*     * Support a wide range of hashes. TLSv1.1 and before only need SIG_RSA_RAW, @@ -369,67 +400,54 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,     *     * This code has been taken from PolarSSL pkcs11_sign(), under the GPLv2.0+.     */ -  switch( hash_id ) -  { -      case SIG_RSA_RAW: -          asn_len = 0; -          memcpy( p, hash, hashlen ); -          break; - -      case SIG_RSA_MD2: -          asn_len = OID_SIZE(ASN1_HASH_MDX); -          memcpy( p, ASN1_HASH_MDX, asn_len ); -          memcpy( p + asn_len, hash, hashlen ); -          p[13] = 2; break; - -      case SIG_RSA_MD4: -          asn_len = OID_SIZE(ASN1_HASH_MDX); -          memcpy( p, ASN1_HASH_MDX, asn_len ); -          memcpy( p + asn_len, hash, hashlen ); -          p[13] = 4; break; - -      case SIG_RSA_MD5: -          asn_len = OID_SIZE(ASN1_HASH_MDX); -          memcpy( p, ASN1_HASH_MDX, asn_len ); -          memcpy( p + asn_len, hash, hashlen ); -          p[13] = 5; break; - -      case SIG_RSA_SHA1: -          asn_len = OID_SIZE(ASN1_HASH_SHA1); -          memcpy( p, ASN1_HASH_SHA1, asn_len ); -          memcpy( p + 15, hash, hashlen ); -          break; - -      case SIG_RSA_SHA224: -          asn_len = OID_SIZE(ASN1_HASH_SHA2X); -          memcpy( p, ASN1_HASH_SHA2X, asn_len ); -          memcpy( p + asn_len, hash, hashlen ); -          p[1] += hashlen; p[14] = 4; p[18] += hashlen; break; - -      case SIG_RSA_SHA256: -          asn_len = OID_SIZE(ASN1_HASH_SHA2X); -          memcpy( p, ASN1_HASH_SHA2X, asn_len ); -          memcpy( p + asn_len, hash, hashlen ); -          p[1] += hashlen; p[14] = 1; p[18] += hashlen; break; - -      case SIG_RSA_SHA384: -          asn_len = OID_SIZE(ASN1_HASH_SHA2X); -          memcpy( p, ASN1_HASH_SHA2X, asn_len ); -          memcpy( p + asn_len, hash, hashlen ); -          p[1] += hashlen; p[14] = 2; p[18] += hashlen; break; - -      case SIG_RSA_SHA512: -          asn_len = OID_SIZE(ASN1_HASH_SHA2X); -          memcpy( p, ASN1_HASH_SHA2X, asn_len ); -          memcpy( p + asn_len, hash, hashlen ); -          p[1] += hashlen; p[14] = 3; p[18] += hashlen; break; - -  /* End of copy */ -      default: -          rv = POLARSSL_ERR_RSA_BAD_INPUT_DATA; -	  goto done; +  if( md_alg != POLARSSL_MD_NONE ) +    { +      const md_info_t *md_info = md_info_from_type( md_alg ); +      if( md_info == NULL ) +        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + +      if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) +        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + +      hashlen = md_get_size( md_info ); +      asn_len = 10 + oid_size; +    } + +  sig_len = ctx->signature_length; +  if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len ) +    return POLARSSL_ERR_RSA_BAD_INPUT_DATA; + +  if( md_alg != POLARSSL_MD_NONE ) +    { +      /* +       * DigestInfo ::= SEQUENCE { +       *   digestAlgorithm DigestAlgorithmIdentifier, +       *   digest Digest } +       * +       * DigestAlgorithmIdentifier ::= AlgorithmIdentifier +       * +       * Digest ::= OCTET STRING +       */ +      *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; +      *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); +      *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; +      *p++ = (unsigned char) ( 0x04 + oid_size ); +      *p++ = ASN1_OID; +      *p++ = oid_size & 0xFF; +      memcpy( p, oid, oid_size ); +      p += oid_size; +      *p++ = ASN1_NULL; +      *p++ = 0x00; +      *p++ = ASN1_OCTET_STRING; +      *p++ = hashlen; + +      /* Determine added ASN length */ +      asn_len = p - sig;    } +  /* Copy the hash to be signed */ +  memcpy( p, hash, hashlen ); +    /* convert 'from' to base64 */    if (openvpn_base64_encode (sig, asn_len + hashlen, &in_b64) <= 0)      { @@ -456,7 +474,7 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,    rv = 0; - done: +done:    if (in_b64)      free (in_b64);    if (out_b64) @@ -482,15 +500,20 @@ void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,    if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)      { -      if (0 != x509parse_crt(ctx->ca_chain, (unsigned char *) ca_file_inline, -          strlen(ca_file_inline))) +      if (0 != x509_crt_parse(ctx->ca_chain, (unsigned char *) ca_file_inline, +	  strlen(ca_file_inline)))  	msg (M_FATAL, "Cannot load inline CA certificates");      }    else      {        /* Load CA file for verifying peer supplied certificate */ -      if (0 != x509parse_crtfile(ctx->ca_chain, ca_file)) -	msg (M_FATAL, "Cannot load CA certificate file %s", ca_file); +      int retval = x509_crt_parse_file(ctx->ca_chain, ca_file); +      if (0 != retval) +	{ +	  char errstr[128]; +	  polarssl_strerror(retval, errstr, sizeof(errstr)); +	  msg (M_FATAL, "Cannot load CA certificate file %s (%s)", ca_file, errstr); +	}      }  } @@ -503,14 +526,14 @@ tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file    if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)      { -      if (0 != x509parse_crt(ctx->crt_chain, +      if (0 != x509_crt_parse(ctx->crt_chain,            (unsigned char *) extra_certs_file_inline, -          strlen(extra_certs_file_inline))) +	  strlen(extra_certs_file_inline)))          msg (M_FATAL, "Cannot load inline extra-certs file");      }    else      { -      if (0 != x509parse_crtfile(ctx->crt_chain, extra_certs_file)) +      if (0 != x509_crt_parse_file(ctx->crt_chain, extra_certs_file))  	msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);      }  } @@ -633,9 +656,9 @@ void tls_ctx_personalise_random(struct tls_root_ctx *ctx)    if (NULL != ctx->crt_chain)      { -      x509_cert *cert = ctx->crt_chain; +      x509_crt *cert = ctx->crt_chain; -      sha2(cert->tbs.p, cert->tbs.len, sha256_hash, false); +      sha256(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); @@ -1021,7 +1044,7 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,  void  print_details (struct key_state_ssl * ks_ssl, const char *prefix)  { -  const x509_cert *cert; +  const x509_crt *cert;    char s1[256];    char s2[256]; @@ -1034,7 +1057,7 @@ print_details (struct key_state_ssl * ks_ssl, const char *prefix)    cert = ssl_get_peer_cert(ks_ssl->ctx);    if (cert != NULL)      { -      openvpn_snprintf (s2, sizeof (s2), ", " counter_format " bit RSA", (counter_type) cert->rsa.len * 8); +      openvpn_snprintf (s2, sizeof (s2), ", %zu bit key", pk_get_size(&cert->pk));      }    msg (D_HANDSHAKE, "%s%s", s1, s2); @@ -1068,6 +1091,12 @@ show_available_tls_ciphers (const char *cipher_list)  }  void +show_available_curves (void) +{ +  printf("The PolarSSL build of OpenVPN does not support elliptic curves yet"); +} + +void  get_highest_preference_tls_cipher (char *buf, int size)  {    const char *cipher_name; @@ -1079,4 +1108,14 @@ get_highest_preference_tls_cipher (char *buf, int size)    strncpynt (buf, cipher_name, size);  } +char * +get_ssl_library_version(void) +{ +    static char polar_version[30]; +    unsigned int pv = version_get_number(); +    sprintf( polar_version, "PolarSSL %d.%d.%d", +		(pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff ); +    return polar_version; +} +  #endif /* defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) */ diff --git a/main/openvpn/src/openvpn/ssl_polarssl.h b/main/openvpn/src/openvpn/ssl_polarssl.h index fc9aa784..b80a509e 100644 --- a/main/openvpn/src/openvpn/ssl_polarssl.h +++ b/main/openvpn/src/openvpn/ssl_polarssl.h @@ -33,6 +33,7 @@  #include "syshead.h"  #include <polarssl/ssl.h> +#include <polarssl/x509_crt.h>  #if defined(ENABLE_PKCS11)  #include <polarssl/pkcs11.h> @@ -64,9 +65,9 @@ struct tls_root_ctx {      int endpoint; 		/**< Whether or not this is a server or a client */      dhm_context *dhm_ctx;	/**< Diffie-Helmann-Merkle context */ -    x509_cert *crt_chain;	/**< Local Certificate chain */ -    x509_cert *ca_chain;	/**< CA chain for remote verification */ -    rsa_context *priv_key;	/**< Local private key */ +    x509_crt *crt_chain;	/**< Local Certificate chain */ +    x509_crt *ca_chain;		/**< CA chain for remote verification */ +    pk_context *priv_key;	/**< Local private key */  #if defined(ENABLE_PKCS11)      pkcs11_context *priv_key_pkcs11;	/**< PKCS11 private key */  #endif diff --git a/main/openvpn/src/openvpn/ssl_verify.c b/main/openvpn/src/openvpn/ssl_verify.c index 765b8860..7a9a56ef 100644 --- a/main/openvpn/src/openvpn/ssl_verify.c +++ b/main/openvpn/src/openvpn/ssl_verify.c @@ -431,7 +431,7 @@ verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert    }    /* export serial number as environmental variable */ -  serial = x509_get_serial(peer_cert, &gc); +  serial = backend_x509_get_serial(peer_cert, &gc);    openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", cert_depth);    setenv_str (es, envname, serial); @@ -558,7 +558,7 @@ verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert)    int fd = -1;    struct gc_arena gc = gc_new(); -  char *serial = x509_get_serial(cert, &gc); +  char *serial = backend_x509_get_serial(cert, &gc);    if (!openvpn_snprintf(fn, sizeof(fn), "%s%c%s", crl_dir, OS_SPECIFIC_DIRSEP, serial))      { @@ -610,7 +610,7 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep    string_replace_leading (subject, '-', '_');    /* extract the username (default is CN) */ -  if (SUCCESS != x509_get_username (common_name, TLS_USERNAME_LEN, +  if (SUCCESS != backend_x509_get_username (common_name, TLS_USERNAME_LEN,        opt->x509_username_field, cert))      {        if (!cert_depth) diff --git a/main/openvpn/src/openvpn/ssl_verify_backend.h b/main/openvpn/src/openvpn/ssl_verify_backend.h index 7d2aae62..fa4369d2 100644 --- a/main/openvpn/src/openvpn/ssl_verify_backend.h +++ b/main/openvpn/src/openvpn/ssl_verify_backend.h @@ -109,7 +109,7 @@ unsigned char *x509_get_sha1_hash (openvpn_x509_cert_t *cert, struct gc_arena *g   *   * @return 		\c FAILURE, \c or SUCCESS   */ -result_t x509_get_username (char *common_name, int cn_len, +result_t backend_x509_get_username (char *common_name, int cn_len,      char * x509_username_field, openvpn_x509_cert_t *peer_cert);  /* @@ -122,7 +122,7 @@ result_t x509_get_username (char *common_name, int cn_len,   *   * @return 		The certificate's serial number.   */ -char *x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc); +char *backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc);  /*   * Save X509 fields to environment, using the naming convention: diff --git a/main/openvpn/src/openvpn/ssl_verify_openssl.c b/main/openvpn/src/openvpn/ssl_verify_openssl.c index cd2006fb..a9205f31 100644 --- a/main/openvpn/src/openvpn/ssl_verify_openssl.c +++ b/main/openvpn/src/openvpn/ssl_verify_openssl.c @@ -202,7 +202,7 @@ extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out,  }  result_t -x509_get_username (char *common_name, int cn_len, +backend_x509_get_username (char *common_name, int cn_len,      char * x509_username_field, X509 *peer_cert)  {  #ifdef ENABLE_X509ALTUSERNAME @@ -220,7 +220,7 @@ x509_get_username (char *common_name, int cn_len,  }  char * -x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) +backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)  {    ASN1_INTEGER *asn1_i;    BIGNUM *bignum; diff --git a/main/openvpn/src/openvpn/ssl_verify_polarssl.c b/main/openvpn/src/openvpn/ssl_verify_polarssl.c index e5ccd904..1b2990c7 100644 --- a/main/openvpn/src/openvpn/ssl_verify_polarssl.c +++ b/main/openvpn/src/openvpn/ssl_verify_polarssl.c @@ -38,12 +38,13 @@  #if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL)  #include "ssl_verify.h" +#include <polarssl/oid.h>  #include <polarssl/sha1.h>  #define MAX_SUBJECT_LENGTH 256  int -verify_callback (void *session_obj, x509_cert *cert, int cert_depth, +verify_callback (void *session_obj, x509_crt *cert, int cert_depth,      int *flags)  {    struct tls_session *session = (struct tls_session *) session_obj; @@ -88,8 +89,8 @@ verify_callback (void *session_obj, x509_cert *cert, int cert_depth,  #endif  result_t -x509_get_username (char *cn, int cn_len, -    char *x509_username_field, x509_cert *cert) +backend_x509_get_username (char *cn, int cn_len, +    char *x509_username_field, x509_crt *cert)  {    x509_name *name; @@ -100,7 +101,7 @@ x509_get_username (char *cn, int cn_len,    /* Find common name */    while( name != NULL )    { -      if( memcmp( name->oid.p, OID_CN, OID_SIZE(OID_CN) ) == 0) +      if( memcmp( name->oid.p, OID_AT_CN, OID_SIZE(OID_AT_CN) ) == 0)  	break;        name = name->next; @@ -123,21 +124,21 @@ x509_get_username (char *cn, int cn_len,  }  char * -x509_get_serial (x509_cert *cert, struct gc_arena *gc) +backend_x509_get_serial (x509_crt *cert, struct gc_arena *gc)  {    char *buf = NULL;    size_t len = cert->serial.len * 3 + 1;    buf = gc_malloc(len, true, gc); -  if(x509parse_serial_gets(buf, len-1, &cert->serial) < 0) +  if(x509_serial_gets(buf, len-1, &cert->serial) < 0)      buf = NULL;    return buf;  }  unsigned char * -x509_get_sha1_hash (x509_cert *cert, struct gc_arena *gc) +x509_get_sha1_hash (x509_crt *cert, struct gc_arena *gc)  {    unsigned char *sha1_hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc);    sha1(cert->tbs.p, cert->tbs.len, sha1_hash); @@ -145,14 +146,14 @@ x509_get_sha1_hash (x509_cert *cert, struct gc_arena *gc)  }  char * -x509_get_subject(x509_cert *cert, struct gc_arena *gc) +x509_get_subject(x509_crt *cert, struct gc_arena *gc)  {    char tmp_subject[MAX_SUBJECT_LENGTH] = {0};    char *subject = NULL;    int ret = 0; -  ret = x509parse_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject ); +  ret = x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject );    if (ret > 0)      {        /* Allocate the required space for the subject */ @@ -182,70 +183,28 @@ x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)    while( name != NULL )      {        char name_expand[64+8]; +      const char *shortname; -      if( name->oid.len == 2 && memcmp( name->oid.p, OID_X520, 2 ) == 0 ) +      if( 0 == oid_get_attr_short_name(&name->oid, &shortname) )  	{ -	  switch( name->oid.p[2] ) -	    { -	    case X520_COMMON_NAME: -		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_CN", -		    cert_depth); break; - -	    case X520_COUNTRY: -		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_C", -		    cert_depth); break; - -	    case X520_LOCALITY: -		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_L", -		    cert_depth); break; - -	    case X520_STATE: -		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_ST", -		    cert_depth); break; - -	    case X520_ORGANIZATION: -		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_O", -		    cert_depth); break; - -	    case X520_ORG_UNIT: -		openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_OU", -		    cert_depth); break; - -	    default: -		openvpn_snprintf (name_expand, sizeof(name_expand), -		    "X509_%d_0x%02X", cert_depth, name->oid.p[2]); -		break; -	    } +	  openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s", +	      cert_depth, shortname);  	} -	else if( name->oid.len == 8 && memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 ) -	  { -	    switch( name->oid.p[8] ) -	      { -		case PKCS9_EMAIL: -		  openvpn_snprintf (name_expand, sizeof(name_expand), -		      "X509_%d_emailAddress", cert_depth); break; - -		default: -		  openvpn_snprintf (name_expand, sizeof(name_expand), -		      "X509_%d_0x%02X", cert_depth, name->oid.p[8]); -		  break; -	      } -	  } -	else -	  { -	    openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?", -		cert_depth); -	  } - -	for( i = 0; i < name->val.len; i++ ) +      else +	{ +	  openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?", +	      cert_depth); +	} + +      for( i = 0; i < name->val.len; i++ )  	{ -	    if( i >= (int) sizeof( s ) - 1 ) -		break; +	  if( i >= (int) sizeof( s ) - 1 ) +	      break; -	    c = name->val.p[i]; -	    if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) -		 s[i] = '?'; -	    else s[i] = c; +	  c = name->val.p[i]; +	  if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) +	       s[i] = '?'; +	  else s[i] = c;  	}  	s[i] = '\0'; @@ -259,7 +218,7 @@ x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)  }  result_t -x509_verify_ns_cert_type(const x509_cert *cert, const int usage) +x509_verify_ns_cert_type(const x509_crt *cert, const int usage)  {    if (usage == NS_CERT_CHECK_NONE)      return SUCCESS; @@ -274,7 +233,7 @@ x509_verify_ns_cert_type(const x509_cert *cert, const int usage)  }  result_t -x509_verify_cert_ku (x509_cert *cert, const unsigned * const expected_ku, +x509_verify_cert_ku (x509_crt *cert, const unsigned * const expected_ku,      int expected_len)  {    result_t fFound = FAILURE; @@ -307,7 +266,7 @@ x509_verify_cert_ku (x509_cert *cert, const unsigned * const expected_ku,  }  result_t -x509_verify_cert_eku (x509_cert *cert, const char * const expected_oid) +x509_verify_cert_eku (x509_crt *cert, const char * const expected_oid)  {    result_t fFound = FAILURE; @@ -357,7 +316,7 @@ x509_verify_cert_eku (x509_cert *cert, const char * const expected_oid)  }  result_t -x509_write_pem(FILE *peercert_file, x509_cert *peercert) +x509_write_pem(FILE *peercert_file, x509_crt *peercert)  {      msg (M_WARN, "PolarSSL does not support writing peer certificate in PEM format");      return FAILURE; @@ -367,12 +326,12 @@ x509_write_pem(FILE *peercert_file, x509_cert *peercert)   * check peer cert against CRL   */  result_t -x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject) +x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject)  {    result_t retval = FAILURE;    x509_crl crl = {0}; -  if (x509parse_crlfile(&crl, crl_file) != 0) +  if (x509_crl_parse_file(&crl, crl_file) != 0)      {        msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);        goto end; @@ -387,7 +346,7 @@ x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject)        goto end;      } -  if (0 != x509parse_revoked(cert, &crl)) +  if (0 != x509_crt_revoked(cert, &crl))      {        msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED", subject);        goto end; diff --git a/main/openvpn/src/openvpn/ssl_verify_polarssl.h b/main/openvpn/src/openvpn/ssl_verify_polarssl.h index b259081f..b5157ed1 100644 --- a/main/openvpn/src/openvpn/ssl_verify_polarssl.h +++ b/main/openvpn/src/openvpn/ssl_verify_polarssl.h @@ -33,11 +33,11 @@  #include "syshead.h"  #include "misc.h"  #include "manage.h" -#include <polarssl/x509.h> +#include <polarssl/x509_crt.h>  #ifndef __OPENVPN_X509_CERT_T_DECLARED  #define __OPENVPN_X509_CERT_T_DECLARED -typedef x509_cert openvpn_x509_cert_t; +typedef x509_crt openvpn_x509_cert_t;  #endif  /** @name Function for authenticating a new connection from a remote OpenVPN peer @@ -72,7 +72,7 @@ typedef x509_cert openvpn_x509_cert_t;   *   * @return The return value is 0 unless a fatal error occurred.   */ -int verify_callback (void *session_obj, x509_cert *cert, int cert_depth, +int verify_callback (void *session_obj, x509_crt *cert, int cert_depth,      int *flags);  /** @} name Function for authenticating a new connection from a remote OpenVPN peer */ diff --git a/main/openvpn/src/openvpn/syshead.h b/main/openvpn/src/openvpn/syshead.h index 7f17bf0e..771c4fc1 100644 --- a/main/openvpn/src/openvpn/syshead.h +++ b/main/openvpn/src/openvpn/syshead.h @@ -586,11 +586,6 @@ socket_defined (const socket_descriptor_t sd)  #endif  /* - * Compile the struct buffer_list code - */ -#define ENABLE_BUFFER_LIST - -/*   * Should we include OCC (options consistency check) code?   */  #ifndef ENABLE_SMALL @@ -600,7 +595,7 @@ socket_defined (const socket_descriptor_t sd)  /*   * Should we include NTLM proxy functionality   */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_HTTP_PROXY) +#if defined(ENABLE_CRYPTO)  #define NTLM 1  #else  #define NTLM 0 @@ -609,20 +604,13 @@ socket_defined (const socket_descriptor_t sd)  /*   * Should we include proxy digest auth functionality   */ -#if defined(ENABLE_CRYPTO) && defined(ENABLE_HTTP_PROXY) +#if defined(ENABLE_CRYPTO)  #define PROXY_DIGEST_AUTH 1  #else  #define PROXY_DIGEST_AUTH 0  #endif  /* - * Should we include code common to all proxy methods? - */ -#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS) -#define GENERAL_PROXY_SUPPORT -#endif - -/*   * Do we have CryptoAPI capability?   */  #if defined(WIN32) && defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) @@ -661,15 +649,6 @@ socket_defined (const socket_descriptor_t sd)  #endif  /* - * Should we include http proxy override functionality - */ -#if defined(ENABLE_MANAGEMENT) && defined(ENABLE_HTTP_PROXY) -#define HTTP_PROXY_OVERRIDE 1 -#else -#define HTTP_PROXY_OVERRIDE 0 -#endif - -/*   * Reduce sensitivity to system clock instability   * and backtracks.   */ diff --git a/main/openvpn/src/openvpn/tun.c b/main/openvpn/src/openvpn/tun.c index 4df271d5..482f6402 100644 --- a/main/openvpn/src/openvpn/tun.c +++ b/main/openvpn/src/openvpn/tun.c @@ -5305,10 +5305,14 @@ close_tun (struct tuntap *tt)  	  /* remove route pointing to interface */  	  delete_route_connected_v6_net(tt, NULL); +	  /* "store=active" is needed in Windows 8(.1) to delete the +	   * address we added (pointed out by Cedric Tabary). +	   */ +  	  /* netsh interface ipv6 delete address \"%s\" %s */  	  ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0,  &gc);  	  argv_printf (&argv, -		    "%s%sc interface ipv6 delete address %s %s", +		    "%s%sc interface ipv6 delete address %s %s store=active",  		     get_win_sys_path(),  		     NETSH_PATH_SUFFIX,  		     tt->actual_name, diff --git a/main/openvpn/tests/t_client.sh.in b/main/openvpn/tests/t_client.sh.in index 6c9de6c3..52c5ed1a 100755 --- a/main/openvpn/tests/t_client.sh.in +++ b/main/openvpn/tests/t_client.sh.in @@ -103,7 +103,7 @@ get_ifconfig_route()  	echo "-- linux iproute2 --"  	@IPROUTE@ addr show     | grep -v valid_lft  	@IPROUTE@ route show -	@IPROUTE@ -o -6 route show | grep -v ' cache' | sed -E -e 's/ expires [0-9]*sec//' -e 's/ (mtu|hoplimit|cwnd) [0-9]+//g' -e 's/ (rtt|rttvar) [0-9]+ms//g' +	@IPROUTE@ -o -6 route show | grep -v ' cache' | sed -E -e 's/ expires [0-9]*sec//' -e 's/ (mtu|hoplimit|cwnd|ssthresh) [0-9]+//g' -e 's/ (rtt|rttvar) [0-9]+ms//g'  	return      fi | 
