From c69ba1780496c260a1b4498596bae428e0df232d Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Wed, 23 Apr 2014 12:20:12 +0200 Subject: Update openvpn code --- main/openvpn/Makefile.am | 2 +- main/openvpn/README.ec | 37 ++++ main/openvpn/config-msvc.h | 3 + main/openvpn/config-version.h | 2 +- main/openvpn/configure.ac | 23 +-- main/openvpn/doc/openvpn.8 | 14 ++ main/openvpn/include/openvpn-plugin.h | 4 +- main/openvpn/sample/sample-keys/README | 6 +- main/openvpn/sample/sample-keys/ec-ca.crt | 13 ++ main/openvpn/sample/sample-keys/ec-ca.key | 6 + main/openvpn/sample/sample-keys/ec-client.crt | 61 +++++++ main/openvpn/sample/sample-keys/ec-client.key | 6 + main/openvpn/sample/sample-keys/ec-server.crt | 61 +++++++ main/openvpn/sample/sample-keys/ec-server.key | 6 + main/openvpn/sample/sample-plugins/defer/build | 2 +- main/openvpn/src/openvpn/base64.c | 6 - main/openvpn/src/openvpn/base64.h | 4 - main/openvpn/src/openvpn/buffer.c | 5 - main/openvpn/src/openvpn/buffer.h | 6 - main/openvpn/src/openvpn/crypto_polarssl.c | 7 +- main/openvpn/src/openvpn/forward.c | 12 +- main/openvpn/src/openvpn/init.c | 52 +----- main/openvpn/src/openvpn/openvpn.c | 1 + main/openvpn/src/openvpn/openvpn.h | 4 - main/openvpn/src/openvpn/options.c | 69 ++++--- main/openvpn/src/openvpn/options.h | 8 +- main/openvpn/src/openvpn/pkcs11_polarssl.c | 13 +- main/openvpn/src/openvpn/proxy.c | 7 - main/openvpn/src/openvpn/proxy.h | 4 - main/openvpn/src/openvpn/push.c | 2 + main/openvpn/src/openvpn/route.c | 10 +- main/openvpn/src/openvpn/socket.c | 55 +----- main/openvpn/src/openvpn/socket.h | 15 +- main/openvpn/src/openvpn/socks.c | 24 ++- main/openvpn/src/openvpn/socks.h | 3 - main/openvpn/src/openvpn/ssl.c | 5 + main/openvpn/src/openvpn/ssl_backend.h | 21 +++ main/openvpn/src/openvpn/ssl_openssl.c | 113 ++++++++++++ main/openvpn/src/openvpn/ssl_polarssl.c | 239 ++++++++++++++----------- main/openvpn/src/openvpn/ssl_polarssl.h | 7 +- main/openvpn/src/openvpn/ssl_verify.c | 6 +- main/openvpn/src/openvpn/ssl_verify_backend.h | 4 +- main/openvpn/src/openvpn/ssl_verify_openssl.c | 4 +- main/openvpn/src/openvpn/ssl_verify_polarssl.c | 109 ++++------- main/openvpn/src/openvpn/ssl_verify_polarssl.h | 6 +- main/openvpn/src/openvpn/syshead.h | 25 +-- main/openvpn/src/openvpn/tun.c | 6 +- main/openvpn/tests/t_client.sh.in | 2 +- 48 files changed, 643 insertions(+), 457 deletions(-) create mode 100644 main/openvpn/README.ec create mode 100644 main/openvpn/sample/sample-keys/ec-ca.crt create mode 100644 main/openvpn/sample/sample-keys/ec-ca.key create mode 100644 main/openvpn/sample/sample-keys/ec-client.crt create mode 100644 main/openvpn/sample/sample-keys/ec-client.key create mode 100644 main/openvpn/sample/sample-keys/ec-server.crt create mode 100644 main/openvpn/sample/sample-keys/ec-server.key (limited to 'main/openvpn') 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 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='. 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 @@ -120,20 +120,6 @@ AC_ARG_ENABLE( [enable_pkcs11="no"] ) -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 @@ -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 ]], [[ -#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 +#include #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 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 /* 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. "); #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 +#include 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 @@ -185,6 +185,16 @@ void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers); 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. @@ -460,10 +470,21 @@ 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 #include #include +#include /* * 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 #include #include "ssl_verify_polarssl.h" #include #include +#include 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); @@ -1067,6 +1090,12 @@ show_available_tls_ciphers (const char *cipher_list) tls_ctx_free(&tls_ctx); } +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) { @@ -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 +#include #if defined(ENABLE_PKCS11) #include @@ -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 #include #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 +#include #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 @@ -585,11 +585,6 @@ socket_defined (const socket_descriptor_t sd) #define UNIX_SOCK_SUPPORT 0 #endif -/* - * Compile the struct buffer_list code - */ -#define ENABLE_BUFFER_LIST - /* * Should we include OCC (options consistency check) code? */ @@ -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,19 +604,12 @@ 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? */ @@ -660,15 +648,6 @@ socket_defined (const socket_descriptor_t sd) #define EPOLL 0 #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 -- cgit v1.2.3