From: <lo...@fr...> - 2017-02-17 22:01:11
|
From: Emmanuel Deloget <lo...@fr...> The purpose of this RFC series is to make the latest master of OpenVPN (2.5-git) linkable with OpenSSL v1.1.x. It may not be complete (I may have missed something due to my work environment, but any missing pieces will be added next week) so be a bit cautious with this. The configuration I used (--without-systemd, --without-lzo) seems to work but I must confess I did not tested much. As you may know, the important information about the API of OpenSSL 1.1 if that it no longer provide access to the content of its objects. The structure types are now opaque and various functions have been added to fetch information from these objects. Once theses patches have been applied, it is possible to compile OpenSSL with the latest 1.0.1 and with the latest 1.1.0. I still have to check whether compilation with 1.0.0 and 0.9.8 works. I don't try to get the OpenSSL version -- I instead decided to check for the presence of individual functions in the library and chose to reimplement the missing ones. Then I changed caller code in order to use this new interface. The net result is that OpenVPN is now using the OpenSSL 1.1 API -- regardless of the real version of OpenSSL. This might make futur changes simpler at the cost of adding more functions in the openssl_compat.h file. Las but not least, because of the way I worked I introduced some strange artefacts (I believe they are not really relevant but some of them are weird enough to need some explaination). * I had to introduce a function of the 1.0 API in the 1.1 code. In the 1.0 API, HMAC_CTX is populated with HMAC_CTX_init() and cleaned with HMAC_CTX_cleanup(). In 1.1 these two functions are gone and replaced with HMAC_CTX_reset(). I decided to use _reset() to implement _cleanup() but since I then could not use it for _init() (that would break an OpenVPN linked with 1.0) I created a small wrapper in 1.1 mode. So, in 1.1, HMAC_CTX_init() calls _reset() -- and everybody is happy (well, maybe not everybody). * HMAC_CTX, EVP_MD_CTX and a few other objects cannot be allocated using malloc() so I had to change the way these object are used and initialized. I introduces a few new functions in the crypto backend to handle this. * x509_verify_ns_cert_type() checks had to be changed. OpenSSL 1.1 does not provide any solution to access both X509::ex_flags and X509::ex_nscert so the check could not be implemented this way. The only solution I found was to use X509_check_purpose() but I'm worried that the implemented test is now far more strict. * weirdly enough, it's no longer possible to duplicate the n parameter of a RSA public key into another RSA public key. If you do so, you also need to duplicate the e parameter. The reason is that you cannot have (n && !e) or (!n && e) (see RSA_set0_key[1]). I deciced to go the same route in my implementation and thus I needed to change the code in tls_ctx_use_external_private_key(). Thanks for your comprehension, [1] https://github.com/openssl/openssl/blob/master/crypto/rsa/rsa_lib.c#L191 -- Emmanuel Deloget Emmanuel Deloget (15): OpenSSL: don't use direct access to the internal of SSL_CTX OpenSSL: don't use direct access to the internal of X509_STORE OpenSSL: don't use direct access to the internal of X509_OBJECT OpenSSL: don't use direct access to the internal of RSA_METHOD OpenSSL: don't use direct access to the internal of X509 OpenSSL: don't use direct access to the internal of EVP_PKEY OpenSSL: don't use direct access to the internal of RSA OpenSSL: don't use direct access to the internal of DSA OpenSSL: don't use direct access to the internal of X509_STORE_CTX OpenSSL: don't use direct access to the internal of EVP_MD_CTX OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX OpenSSL: don't use direct access to the internal of HMAC_CTX OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1 OpenSSL: check for the SSL reason, not the full error OpenSSL: constify getbio() parameters configure.ac | 37 +++ src/openvpn/crypto.c | 8 +- src/openvpn/crypto_backend.h | 42 +++ src/openvpn/crypto_mbedtls.c | 40 +++ src/openvpn/crypto_openssl.c | 53 +++- src/openvpn/httpdigest.c | 78 ++--- src/openvpn/misc.c | 14 +- src/openvpn/ntlm.c | 12 +- src/openvpn/openssl_compat.h | 609 +++++++++++++++++++++++++++++++++++++++ src/openvpn/openvpn.h | 2 +- src/openvpn/push.c | 11 +- src/openvpn/ssl.c | 38 +-- src/openvpn/ssl_openssl.c | 94 +++--- src/openvpn/ssl_verify_openssl.c | 55 ++-- 14 files changed, 947 insertions(+), 146 deletions(-) create mode 100644 src/openvpn/openssl_compat.h -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:29
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including SSL_CTX. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 9 ++++++ src/openvpn/openssl_compat.h | 74 ++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_openssl.c | 13 +++++--- 3 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 src/openvpn/openssl_compat.h diff --git a/configure.ac b/configure.ac index b29f8b410dfb69bce1145c3bb4a1ba011f0636ec..5fe5d6046ceafa2b577296af772c347ac2ad8039 100644 --- a/configure.ac +++ b/configure.ac @@ -898,6 +898,15 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then [have_crypto_aead_modes="no"; break] ) + AC_CHECK_FUNCS( + [ \ + SSL_CTX_get_default_passwd_cb \ + SSL_CTX_get_default_passwd_cb_userdata \ + ], + , + [] + ) + CFLAGS="${saved_CFLAGS}" LIBS="${saved_LIBS}" diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..59bad9ff24d10b358419d345181a0e2e52a0c662 --- /dev/null +++ b/src/openvpn/openssl_compat.h @@ -0,0 +1,74 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sa...@op...> + * Copyright (C) 2010-2017 Fox Crypto B.V. <op...@fo...> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file OpenSSL compatibility stub + * + * This file provide compatibility stubs for the OpenSSL libraries + * prior to version 1.1. This version introduces many changes in the + * library interface, including the fact that various objects and + * structures are not fully opaque. + */ + +#ifndef OPENSSL_COMPAT_H_ +#define OPENSSL_COMPAT_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include <openssl/ssl.h> + +#if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) +/** + * Fetch the default password callback user data from the SSL context + * + * @param ctx SSL context + * @return The password callback user data + */ +static inline void * +SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) +{ + return ctx ? ctx->default_passwd_callback_userdata : NULL; +} +#endif + +#if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB) +/** + * Fetch the default password callback from the SSL context + * + * @param ctx SSL context + * @return The password callback + */ +static inline pem_password_cb * +SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) +{ + return ctx ? ctx->default_passwd_callback : NULL; +} +#endif + +#endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index abf69c91a60910e450ae6d2d49ea7e5b1cd3a535..39e92f8cdae52d54d0ad95a9362e4e0e1b2289f4 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -45,6 +45,7 @@ #include "ssl_backend.h" #include "ssl_common.h" #include "base64.h" +#include "openssl_compat.h" #ifdef ENABLE_CRYPTOAPI #include "cryptoapi.h" @@ -658,7 +659,8 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, { for (i = 0; i < sk_X509_num(ca); i++) { - if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i))) + X509_STORE *cert_store = SSL_CTX_get_cert_store(ctx->ctx); + if (!X509_STORE_add_cert(cert_store,sk_X509_value(ca, i))) { crypto_msg(M_FATAL,"Cannot add certificate to certificate chain (X509_STORE_add_cert)"); } @@ -760,8 +762,9 @@ tls_ctx_load_cert_file_and_copy(struct tls_root_ctx *ctx, goto end; } - x = PEM_read_bio_X509(in, NULL, ctx->ctx->default_passwd_callback, - ctx->ctx->default_passwd_callback_userdata); + x = PEM_read_bio_X509(in, NULL, + SSL_CTX_get_default_passwd_cb(ctx->ctx), + SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx)); if (x == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB); @@ -843,8 +846,8 @@ tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, } pkey = PEM_read_bio_PrivateKey(in, NULL, - ssl_ctx->default_passwd_callback, - ssl_ctx->default_passwd_callback_userdata); + SSL_CTX_get_default_passwd_cb(ctx->ctx), + SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx)); if (!pkey) { goto end; -- 2.7.4 |
Re: [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct
access to the internal of SSL_CTX
From: Steffan K. <st...@ka...> - 2017-02-22 20:27:48
Attachments:
signature.asc
|
On 17-02-17 23:00, lo...@fr... wrote: > From: Emmanuel Deloget <lo...@fr...> > > OpenSSL 1.1 does not allow us to directly access the internal of > any data type, including SSL_CTX. We have to use the defined functions > to do so. > > Compatibility with OpenSSL 1.0 is kept by defining the corresponding > functions when they are not found in the library. > > Signed-off-by: Emmanuel Deloget <lo...@fr...> > --- > configure.ac | 9 ++++++ > src/openvpn/openssl_compat.h | 74 ++++++++++++++++++++++++++++++++++++++++++++ > src/openvpn/ssl_openssl.c | 13 +++++--- > 3 files changed, 91 insertions(+), 5 deletions(-) > create mode 100644 src/openvpn/openssl_compat.h > > diff --git a/configure.ac b/configure.ac > index b29f8b410dfb69bce1145c3bb4a1ba011f0636ec..5fe5d6046ceafa2b577296af772c347ac2ad8039 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -898,6 +898,15 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then > [have_crypto_aead_modes="no"; break] > ) > > + AC_CHECK_FUNCS( > + [ \ > + SSL_CTX_get_default_passwd_cb \ > + SSL_CTX_get_default_passwd_cb_userdata \ > + ], > + , > + [] > + ) > + > CFLAGS="${saved_CFLAGS}" > LIBS="${saved_LIBS}" > > diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h > new file mode 100644 > index 0000000000000000000000000000000000000000..59bad9ff24d10b358419d345181a0e2e52a0c662 > --- /dev/null > +++ b/src/openvpn/openssl_compat.h > @@ -0,0 +1,74 @@ > +/* > + * OpenVPN -- An application to securely tunnel IP networks > + * over a single TCP/UDP port, with support for SSL/TLS-based > + * session authentication and key exchange, > + * packet encryption, packet authentication, and > + * packet compression. > + * > + * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sa...@op...> > + * Copyright (C) 2010-2017 Fox Crypto B.V. <op...@fo...> > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 > + * as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program (see the file COPYING included with this > + * distribution); if not, write to the Free Software Foundation, Inc., > + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +/** > + * @file OpenSSL compatibility stub > + * > + * This file provide compatibility stubs for the OpenSSL libraries > + * prior to version 1.1. This version introduces many changes in the > + * library interface, including the fact that various objects and > + * structures are not fully opaque. > + */ > + > +#ifndef OPENSSL_COMPAT_H_ > +#define OPENSSL_COMPAT_H_ > + > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#elif defined(_MSC_VER) > +#include "config-msvc.h" > +#endif > + > +#include <openssl/ssl.h> > + > +#if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) > +/** > + * Fetch the default password callback user data from the SSL context > + * > + * @param ctx SSL context > + * @return The password callback user data > + */ > +static inline void * > +SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) > +{ > + return ctx ? ctx->default_passwd_callback_userdata : NULL; > +} > +#endif > + > +#if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB) > +/** > + * Fetch the default password callback from the SSL context > + * > + * @param ctx SSL context > + * @return The password callback > + */ > +static inline pem_password_cb * > +SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) > +{ > + return ctx ? ctx->default_passwd_callback : NULL; > +} > +#endif > + > +#endif /* OPENSSL_COMPAT_H_ */ > diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c > index abf69c91a60910e450ae6d2d49ea7e5b1cd3a535..39e92f8cdae52d54d0ad95a9362e4e0e1b2289f4 100644 > --- a/src/openvpn/ssl_openssl.c > +++ b/src/openvpn/ssl_openssl.c > @@ -45,6 +45,7 @@ > #include "ssl_backend.h" > #include "ssl_common.h" > #include "base64.h" > +#include "openssl_compat.h" > > #ifdef ENABLE_CRYPTOAPI > #include "cryptoapi.h" > @@ -658,7 +659,8 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, > { > for (i = 0; i < sk_X509_num(ca); i++) > { > - if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i))) > + X509_STORE *cert_store = SSL_CTX_get_cert_store(ctx->ctx); > + if (!X509_STORE_add_cert(cert_store,sk_X509_value(ca, i))) > { > crypto_msg(M_FATAL,"Cannot add certificate to certificate chain (X509_STORE_add_cert)"); > } > @@ -760,8 +762,9 @@ tls_ctx_load_cert_file_and_copy(struct tls_root_ctx *ctx, > goto end; > } > > - x = PEM_read_bio_X509(in, NULL, ctx->ctx->default_passwd_callback, > - ctx->ctx->default_passwd_callback_userdata); > + x = PEM_read_bio_X509(in, NULL, > + SSL_CTX_get_default_passwd_cb(ctx->ctx), > + SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx)); > if (x == NULL) > { > SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB); > @@ -843,8 +846,8 @@ tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, > } > > pkey = PEM_read_bio_PrivateKey(in, NULL, > - ssl_ctx->default_passwd_callback, > - ssl_ctx->default_passwd_callback_userdata); > + SSL_CTX_get_default_passwd_cb(ctx->ctx), > + SSL_CTX_get_default_passwd_cb_userdata(ctx->ctx)); > if (!pkey) > { > goto end; > ACK -Steffan |
From: Gert D. <ge...@gr...> - 2017-02-22 21:14:11
|
Your patch has been applied to the master and release/2.4 branch. commit 6554ac9fed9c5680f22aa4722e6e07ebf3aa3441 (master) commit b936ddfb631e3a4b219bd035f7110da5679b2d12 (release/2.4) Author: Emmanuel Deloget Date: Fri Feb 17 23:00:40 2017 +0100 OpenSSL: don't use direct access to the internal of SSL_CTX Signed-off-by: Emmanuel Deloget <lo...@fr...> Acked-by: Steffan Karger <ste...@fo...> Message-Id: <a77...@fr...> URL: https://www.mail-archive.com/ope...@li.../msg14088.html Signed-off-by: Gert Doering <ge...@gr...> -- kind regards, Gert Doering |
From: <lo...@fr...> - 2017-02-17 22:01:30
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including X509_STORE. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 1 + src/openvpn/openssl_compat.h | 15 +++++++++++++++ src/openvpn/ssl_openssl.c | 7 ++++--- src/openvpn/ssl_verify_openssl.c | 6 ++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 5fe5d6046ceafa2b577296af772c347ac2ad8039..415128c9f8687a53e4a73419f3048d07f66b70cc 100644 --- a/configure.ac +++ b/configure.ac @@ -902,6 +902,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then [ \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ + X509_STORE_get0_objects \ ], , [] diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 59bad9ff24d10b358419d345181a0e2e52a0c662..016008bc1705a41ee0ee09fecfc0b16b282cede3 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -42,6 +42,7 @@ #endif #include <openssl/ssl.h> +#include <openssl/x509.h> #if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) /** @@ -71,4 +72,18 @@ SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) } #endif +#if !defined(HAVE_X509_STORE_GET0_OBJECTS) +/** + * Fetch the X509 object stack from the X509 store + * + * @param store X509 object store + * @return the X509 object stack + */ +static inline STACK_OF(X509_OBJECT) * +X509_STORE_get0_objects(X509_STORE *store) +{ + return store ? store->objs : NULL; +} +#endif + #endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 39e92f8cdae52d54d0ad95a9362e4e0e1b2289f4..e57de43a748c89ff58ea00abade0b1c317013258 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -900,13 +900,14 @@ backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file, /* Always start with a cleared CRL list, for that we * we need to manually find the CRL object from the stack * and remove it */ - for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++) + STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store); + for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) { - X509_OBJECT *obj = sk_X509_OBJECT_value(store->objs, i); + X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); ASSERT(obj); if (obj->type == X509_LU_CRL) { - sk_X509_OBJECT_delete(store->objs, i); + sk_X509_OBJECT_delete(objs, i); X509_OBJECT_free_contents(obj); OPENSSL_free(obj); } diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index 274e2bbf96b6c943ce628eab143f8c76e1c47103..fabbb0c370b123f54ce4a1eaf5f9650b440f47f8 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -43,6 +43,7 @@ #include "ssl_openssl.h" #include "ssl_verify.h" #include "ssl_verify_backend.h" +#include "openssl_compat.h" #include <openssl/x509v3.h> #include <openssl/err.h> @@ -715,9 +716,10 @@ tls_verify_crl_missing(const struct tls_options *opt) crypto_msg(M_FATAL, "Cannot get certificate store"); } - for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++) + STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store); + for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) { - X509_OBJECT *obj = sk_X509_OBJECT_value(store->objs, i); + X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); ASSERT(obj); if (obj->type == X509_LU_CRL) { -- 2.7.4 |
From: Steffan K. <st...@ka...> - 2017-02-22 20:36:42
Attachments:
signature.asc
|
On 17-02-17 23:00, lo...@fr... wrote: > From: Emmanuel Deloget <lo...@fr...> > > OpenSSL 1.1 does not allow us to directly access the internal of > any data type, including X509_STORE. We have to use the defined functions > to do so. > > Compatibility with OpenSSL 1.0 is kept by defining the corresponding > functions when they are not found in the library. > > Signed-off-by: Emmanuel Deloget <lo...@fr...> > --- > configure.ac | 1 + > src/openvpn/openssl_compat.h | 15 +++++++++++++++ > src/openvpn/ssl_openssl.c | 7 ++++--- > src/openvpn/ssl_verify_openssl.c | 6 ++++-- > 4 files changed, 24 insertions(+), 5 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 5fe5d6046ceafa2b577296af772c347ac2ad8039..415128c9f8687a53e4a73419f3048d07f66b70cc 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -902,6 +902,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then > [ \ > SSL_CTX_get_default_passwd_cb \ > SSL_CTX_get_default_passwd_cb_userdata \ > + X509_STORE_get0_objects \ > ], > , > [] > diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h > index 59bad9ff24d10b358419d345181a0e2e52a0c662..016008bc1705a41ee0ee09fecfc0b16b282cede3 100644 > --- a/src/openvpn/openssl_compat.h > +++ b/src/openvpn/openssl_compat.h > @@ -42,6 +42,7 @@ > #endif > > #include <openssl/ssl.h> > +#include <openssl/x509.h> > > #if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) > /** > @@ -71,4 +72,18 @@ SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) > } > #endif > > +#if !defined(HAVE_X509_STORE_GET0_OBJECTS) > +/** > + * Fetch the X509 object stack from the X509 store > + * > + * @param store X509 object store > + * @return the X509 object stack > + */ > +static inline STACK_OF(X509_OBJECT) * > +X509_STORE_get0_objects(X509_STORE *store) > +{ > + return store ? store->objs : NULL; > +} > +#endif > + > #endif /* OPENSSL_COMPAT_H_ */ > diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c > index 39e92f8cdae52d54d0ad95a9362e4e0e1b2289f4..e57de43a748c89ff58ea00abade0b1c317013258 100644 > --- a/src/openvpn/ssl_openssl.c > +++ b/src/openvpn/ssl_openssl.c > @@ -900,13 +900,14 @@ backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file, > /* Always start with a cleared CRL list, for that we > * we need to manually find the CRL object from the stack > * and remove it */ > - for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++) > + STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store); > + for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) > { > - X509_OBJECT *obj = sk_X509_OBJECT_value(store->objs, i); > + X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); > ASSERT(obj); > if (obj->type == X509_LU_CRL) > { > - sk_X509_OBJECT_delete(store->objs, i); > + sk_X509_OBJECT_delete(objs, i); > X509_OBJECT_free_contents(obj); > OPENSSL_free(obj); > } > diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c > index 274e2bbf96b6c943ce628eab143f8c76e1c47103..fabbb0c370b123f54ce4a1eaf5f9650b440f47f8 100644 > --- a/src/openvpn/ssl_verify_openssl.c > +++ b/src/openvpn/ssl_verify_openssl.c > @@ -43,6 +43,7 @@ > #include "ssl_openssl.h" > #include "ssl_verify.h" > #include "ssl_verify_backend.h" > +#include "openssl_compat.h" > > #include <openssl/x509v3.h> > #include <openssl/err.h> > @@ -715,9 +716,10 @@ tls_verify_crl_missing(const struct tls_options *opt) > crypto_msg(M_FATAL, "Cannot get certificate store"); > } > > - for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++) > + STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store); > + for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) > { > - X509_OBJECT *obj = sk_X509_OBJECT_value(store->objs, i); > + X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); > ASSERT(obj); > if (obj->type == X509_LU_CRL) > { > ACK -Steffan |
From: Gert D. <ge...@gr...> - 2017-02-22 21:14:12
|
Your patch has been applied to the master and release/2.4 branch. commit f05665df4150c6a345eec5432a02fd799bea0f2c (master) commit 24bca7bee2ee5c48880a197ce9727bbc5a0149e5 (release/2.4) Author: Emmanuel Deloget Date: Fri Feb 17 23:00:41 2017 +0100 OpenSSL: don't use direct access to the internal of X509_STORE Signed-off-by: Emmanuel Deloget <lo...@fr...> Acked-by: Steffan Karger <ste...@fo...> Message-Id: <8e6...@fr...> URL: https://www.mail-archive.com/ope...@li.../msg14076.html Signed-off-by: Gert Doering <ge...@gr...> -- kind regards, Gert Doering |
[Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct
access to the internal of X509_OBJECT
From: <lo...@fr...> - 2017-02-17 22:01:32
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including X509_OBJECT. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 2 ++ src/openvpn/openssl_compat.h | 31 +++++++++++++++++++++++++++++++ src/openvpn/ssl_openssl.c | 5 ++--- src/openvpn/ssl_verify_openssl.c | 2 +- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 415128c9f8687a53e4a73419f3048d07f66b70cc..789ad08fbaa3b3fc4c95d2b7a22332c0a93aeab4 100644 --- a/configure.ac +++ b/configure.ac @@ -903,6 +903,8 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ X509_STORE_get0_objects \ + X509_OBJECT_free \ + X509_OBJECT_get_type \ ], , [] diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 016008bc1705a41ee0ee09fecfc0b16b282cede3..458a6adbe2b3fcd5ea63dcea6596cc24315d463c 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -86,4 +86,35 @@ X509_STORE_get0_objects(X509_STORE *store) } #endif +#if !defined(HAVE_X509_OBJECT_FREE) +/** + * Destroy a X509 object + * + * @param obj X509 object + */ +static inline void +X509_OBJECT_free(X509_OBJECT *obj) +{ + if (obj) + { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + } +} +#endif + +#if !defined(HAVE_X509_OBJECT_GET_TYPE) +/** + * Get the type of an X509 object + * + * @param obj X509 object + * @return The underlying object type + */ +static inline int +X509_OBJECT_get_type(const X509_OBJECT *obj) +{ + return obj ? obj->type : X509_LU_FAIL; +} +#endif + #endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index e57de43a748c89ff58ea00abade0b1c317013258..bf0f643f25439f71cbfe71bf5a7e8eb834b0f012 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -905,11 +905,10 @@ backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file, { X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); ASSERT(obj); - if (obj->type == X509_LU_CRL) + if (X509_OBJECT_get_type(obj) == X509_LU_CRL) { sk_X509_OBJECT_delete(objs, i); - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); + X509_OBJECT_free(obj); } } diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index fabbb0c370b123f54ce4a1eaf5f9650b440f47f8..07975248035b48121d1383b47f40a56042bc7380 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -721,7 +721,7 @@ tls_verify_crl_missing(const struct tls_options *opt) { X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); ASSERT(obj); - if (obj->type == X509_LU_CRL) + if (X509_OBJECT_get_type(obj) == X509_LU_CRL) { return false; } -- 2.7.4 |
From: Steffan K. <st...@ka...> - 2017-02-22 20:50:31
Attachments:
signature.asc
|
On 17-02-17 23:00, lo...@fr... wrote: > From: Emmanuel Deloget <lo...@fr...> > > OpenSSL 1.1 does not allow us to directly access the internal of > any data type, including X509_OBJECT. We have to use the defined > functions to do so. > > Compatibility with OpenSSL 1.0 is kept by defining the corresponding > functions when they are not found in the library. > > Signed-off-by: Emmanuel Deloget <lo...@fr...> > --- > configure.ac | 2 ++ > src/openvpn/openssl_compat.h | 31 +++++++++++++++++++++++++++++++ > src/openvpn/ssl_openssl.c | 5 ++--- > src/openvpn/ssl_verify_openssl.c | 2 +- > 4 files changed, 36 insertions(+), 4 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 415128c9f8687a53e4a73419f3048d07f66b70cc..789ad08fbaa3b3fc4c95d2b7a22332c0a93aeab4 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -903,6 +903,8 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then > SSL_CTX_get_default_passwd_cb \ > SSL_CTX_get_default_passwd_cb_userdata \ > X509_STORE_get0_objects \ > + X509_OBJECT_free \ > + X509_OBJECT_get_type \ > ], > , > [] > diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h > index 016008bc1705a41ee0ee09fecfc0b16b282cede3..458a6adbe2b3fcd5ea63dcea6596cc24315d463c 100644 > --- a/src/openvpn/openssl_compat.h > +++ b/src/openvpn/openssl_compat.h > @@ -86,4 +86,35 @@ X509_STORE_get0_objects(X509_STORE *store) > } > #endif > > +#if !defined(HAVE_X509_OBJECT_FREE) > +/** > + * Destroy a X509 object > + * > + * @param obj X509 object > + */ > +static inline void > +X509_OBJECT_free(X509_OBJECT *obj) > +{ > + if (obj) > + { > + X509_OBJECT_free_contents(obj); > + OPENSSL_free(obj); > + } > +} > +#endif > + > +#if !defined(HAVE_X509_OBJECT_GET_TYPE) > +/** > + * Get the type of an X509 object > + * > + * @param obj X509 object > + * @return The underlying object type > + */ > +static inline int > +X509_OBJECT_get_type(const X509_OBJECT *obj) > +{ > + return obj ? obj->type : X509_LU_FAIL; > +} > +#endif > + > #endif /* OPENSSL_COMPAT_H_ */ > diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c > index e57de43a748c89ff58ea00abade0b1c317013258..bf0f643f25439f71cbfe71bf5a7e8eb834b0f012 100644 > --- a/src/openvpn/ssl_openssl.c > +++ b/src/openvpn/ssl_openssl.c > @@ -905,11 +905,10 @@ backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file, > { > X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); > ASSERT(obj); > - if (obj->type == X509_LU_CRL) > + if (X509_OBJECT_get_type(obj) == X509_LU_CRL) > { > sk_X509_OBJECT_delete(objs, i); > - X509_OBJECT_free_contents(obj); > - OPENSSL_free(obj); > + X509_OBJECT_free(obj); > } > } > > diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c > index fabbb0c370b123f54ce4a1eaf5f9650b440f47f8..07975248035b48121d1383b47f40a56042bc7380 100644 > --- a/src/openvpn/ssl_verify_openssl.c > +++ b/src/openvpn/ssl_verify_openssl.c > @@ -721,7 +721,7 @@ tls_verify_crl_missing(const struct tls_options *opt) > { > X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i); > ASSERT(obj); > - if (obj->type == X509_LU_CRL) > + if (X509_OBJECT_get_type(obj) == X509_LU_CRL) > { > return false; > } > ACK -Steffan |
From: Gert D. <ge...@gr...> - 2017-02-22 21:14:17
|
Your patch has been applied to the master and release/2.4 branch. commit 47191f49890ee5c53fa78a8ce9bf96b9c8d27a82 (master) commit d782597ede843266fd2c7854a6f90ec7ce4bb92b (release/2.4) Author: Emmanuel Deloget Date: Fri Feb 17 23:00:42 2017 +0100 OpenSSL: don't use direct access to the internal of X509_OBJECT Signed-off-by: Emmanuel Deloget <lo...@fr...> Acked-by: Steffan Karger <ste...@fo...> Message-Id: <c84...@fr...> URL: https://www.mail-archive.com/ope...@li.../msg14080.html Signed-off-by: Gert Doering <ge...@gr...> -- kind regards, Gert Doering |
From: <lo...@fr...> - 2017-02-17 22:01:34
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including RSA_METHOD. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 9 +++ src/openvpn/openssl_compat.h | 186 +++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_openssl.c | 22 ++--- 3 files changed, 206 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 789ad08fbaa3b3fc4c95d2b7a22332c0a93aeab4..6f31609d0aeedd2c7841d271ecadd1aa6f3b11da 100644 --- a/configure.ac +++ b/configure.ac @@ -905,6 +905,15 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then X509_STORE_get0_objects \ X509_OBJECT_free \ X509_OBJECT_get_type \ + RSA_meth_new \ + RSA_meth_free \ + RSA_meth_set_pub_enc \ + RSA_meth_set_pub_dec \ + RSA_meth_set_priv_enc \ + RSA_meth_set_priv_dec \ + RSA_meth_set_init \ + RSA_meth_set_finish \ + RSA_meth_set0_app_data \ ], , [] diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 458a6adbe2b3fcd5ea63dcea6596cc24315d463c..b1748754f821f472cf9ed7083ade918336c9b075 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -41,6 +41,8 @@ #include "config-msvc.h" #endif +#include "buffer.h" + #include <openssl/ssl.h> #include <openssl/x509.h> @@ -117,4 +119,188 @@ X509_OBJECT_get_type(const X509_OBJECT *obj) } #endif +#if !defined(HAVE_RSA_METH_NEW) +/** + * Allocate a new RSA method object + * + * @param name The object name + * @param flags Configuration flags + * @return A new RSA method object + */ +static inline RSA_METHOD * +RSA_meth_new(const char *name, int flags) +{ + RSA_METHOD *rsa_meth = NULL; + ALLOC_OBJ_CLEAR(rsa_meth, RSA_METHOD); + rsa_meth->name = name; + rsa_meth->flags = flags; + return rsa_meth; +} +#endif + +#if !defined(HAVE_RSA_METH_FREE) +/** + * Free an existing RSA_METHOD object + * + * @param meth The RSA_METHOD object + */ +static inline void +RSA_meth_free(RSA_METHOD *meth) +{ + free(meth); +} +#endif + +#if !defined(HAVE_RSA_METH_SET_PUB_ENC) +/** + * Set the public encoding function of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param pub_enc the public encoding function + * @return 1 on success, 0 on error + */ +static inline int +RSA_meth_set_pub_enc(RSA_METHOD *meth, + int (*pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + if (meth) + { + meth->rsa_pub_enc = pub_enc; + return 1; + } + return 0; +} +#endif + +#if !defined(HAVE_RSA_METH_SET_PUB_DEC) +/** + * Set the public decoding function of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param pub_dec the public decoding function + * @return 1 on success, 0 on error + */ +static inline int +RSA_meth_set_pub_dec(RSA_METHOD *meth, + int (*pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + if (meth) + { + meth->rsa_pub_dec = pub_dec; + return 1; + } + return 0; +} +#endif + +#if !defined(HAVE_RSA_METH_SET_PRIV_ENC) +/** + * Set the private encoding function of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param priv_enc the private encoding function + * @return 1 on success, 0 on error + */ +static inline int +RSA_meth_set_priv_enc(RSA_METHOD *meth, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + if (meth) + { + meth->rsa_priv_enc = priv_enc; + return 1; + } + return 0; +} +#endif + +#if !defined(HAVE_RSA_METH_SET_PRIV_DEC) +/** + * Set the private decoding function of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param priv_dec the private decoding function + * @return 1 on success, 0 on error + */ +static inline int +RSA_meth_set_priv_dec(RSA_METHOD *meth, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + if (meth) + { + meth->rsa_priv_dec = priv_dec; + return 1; + } + return 0; +} +#endif + +#if !defined(HAVE_RSA_METH_SET_INIT) +/** + * Set the init function of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param init the init function + * @return 1 on success, 0 on error + */ +static inline int +RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa)) +{ + if (meth) + { + meth->init = init; + return 1; + } + return 0; +} +#endif + +#if !defined(HAVE_RSA_METH_SET_FINISH) +/** + * Set the finish function of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param finish the finish function + * @return 1 on success, 0 on error + */ +static inline int +RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) +{ + if (meth) + { + meth->finish = finish; + return 1; + } + return 0; +} +#endif + +#if !defined(HAVE_RSA_METH_SET0_APP_DATA) +/** + * Set the application data of an RSA_METHOD object + * + * @param meth The RSA_METHOD object + * @param app_data Application data + * @return 1 on success, 0 on error + */ +static inline int +RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) +{ + if (meth) + { + meth->app_data = app_data; + return 1; + } + return 0; +} +#endif + #endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index bf0f643f25439f71cbfe71bf5a7e8eb834b0f012..f011e06702529ff34e91f6d0169d1adf8cc9d767 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -978,7 +978,7 @@ rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i static int rsa_finish(RSA *rsa) { - free((void *)rsa->meth); + RSA_meth_free(rsa->meth); rsa->meth = NULL; return 1; } @@ -1053,16 +1053,16 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, ASSERT(NULL != cert); /* allocate custom RSA method object */ - ALLOC_OBJ_CLEAR(rsa_meth, RSA_METHOD); - rsa_meth->name = "OpenVPN external private key RSA Method"; - rsa_meth->rsa_pub_enc = rsa_pub_enc; - rsa_meth->rsa_pub_dec = rsa_pub_dec; - rsa_meth->rsa_priv_enc = rsa_priv_enc; - rsa_meth->rsa_priv_dec = rsa_priv_dec; - rsa_meth->init = NULL; - rsa_meth->finish = rsa_finish; - rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; - rsa_meth->app_data = NULL; + rsa_meth = RSA_meth_new("OpenVPN external private key RSA Method", + RSA_METHOD_FLAG_NO_CHECK); + check_malloc_return(rsa_meth); + RSA_meth_set_pub_enc(rsa_meth, rsa_pub_enc); + RSA_meth_set_pub_dec(rsa_meth, rsa_pub_dec); + RSA_meth_set_priv_enc(rsa_meth, rsa_priv_enc); + RSA_meth_set_priv_dec(rsa_meth, rsa_priv_dec); + RSA_meth_set_init(rsa_meth, NULL); + RSA_meth_set_finish(rsa_meth, rsa_finish); + RSA_meth_set0_app_data(rsa_meth, NULL); /* allocate RSA object */ rsa = RSA_new(); -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:36
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including X509. We have to use the defined functions to do so. In x509_verify_ns_cert_type() in particular, this means that we cannot directly check for the extended flags to find whether the certificate should be used as a client or as a server certificate. We need to leverage the X509_check_purpose() API yet this API is far stricter than the currently implemented check. So far, I have not been able to find a situation where this stricter test fails (although I must admit that I haven't tested that very well). Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 1 + src/openvpn/openssl_compat.h | 15 +++++++++++++++ src/openvpn/ssl_openssl.c | 3 ++- src/openvpn/ssl_verify_openssl.c | 28 +++++++++++++++++++--------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 6f31609d0aeedd2c7841d271ecadd1aa6f3b11da..c41db3effbb26318be4f44009a5055e808b89b56 100644 --- a/configure.ac +++ b/configure.ac @@ -902,6 +902,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then [ \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ + X509_get0_pubkey \ X509_STORE_get0_objects \ X509_OBJECT_free \ X509_OBJECT_get_type \ diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index b1748754f821f472cf9ed7083ade918336c9b075..6a89b91b05e0370a50ac5a1cae20ae659e6c7634 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -74,6 +74,21 @@ SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) } #endif +#if !defined(HAVE_X509_GET0_PUBKEY) +/** + * Get the public key from a X509 certificate + * + * @param x X509 certificate + * @return The certificate public key + */ +static inline EVP_PKEY * +X509_get0_pubkey(const X509 *x) +{ + return (x && x->cert_info && x->cert_info->key) ? + x->cert_info->key->pkey : NULL; +} +#endif + #if !defined(HAVE_X509_STORE_GET0_OBJECTS) /** * Fetch the X509 object stack from the X509 store diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index f011e06702529ff34e91f6d0169d1adf8cc9d767..b683961d9e4e79b9ee04cfa7ecd1b377ade9651b 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -1073,7 +1073,8 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, } /* get the public key */ - ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */ + EVP_PKEY *pkey = X509_get0_pubkey(cert); + ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ pub_rsa = cert->cert_info->key->pkey->pkey.rsa; /* initialize RSA object */ diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index 07975248035b48121d1383b47f40a56042bc7380..edc709b89eb05bca895639dde606b29f8e1f7024 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -285,18 +285,20 @@ backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc) struct buffer x509_get_sha1_fingerprint(X509 *cert, struct gc_arena *gc) { - struct buffer hash = alloc_buf_gc(sizeof(cert->sha1_hash), gc); - memcpy(BPTR(&hash), cert->sha1_hash, sizeof(cert->sha1_hash)); - ASSERT(buf_inc_len(&hash, sizeof(cert->sha1_hash))); + const EVP_MD *sha1 = EVP_sha1(); + struct buffer hash = alloc_buf_gc(EVP_MD_size(sha1), gc); + X509_digest(cert, EVP_sha1(), BPTR(&hash), NULL); + ASSERT(buf_inc_len(&hash, EVP_MD_size(sha1))); return hash; } struct buffer x509_get_sha256_fingerprint(X509 *cert, struct gc_arena *gc) { - struct buffer hash = alloc_buf_gc((EVP_sha256())->md_size, gc); + const EVP_MD *sha256 = EVP_sha256(); + struct buffer hash = alloc_buf_gc(EVP_MD_size(sha256), gc); X509_digest(cert, EVP_sha256(), BPTR(&hash), NULL); - ASSERT(buf_inc_len(&hash, (EVP_sha256())->md_size)); + ASSERT(buf_inc_len(&hash, EVP_MD_size(sha256))); return hash; } @@ -573,13 +575,21 @@ x509_verify_ns_cert_type(const openvpn_x509_cert_t *peer_cert, const int usage) } if (usage == NS_CERT_CHECK_CLIENT) { - return ((peer_cert->ex_flags & EXFLAG_NSCERT) - && (peer_cert->ex_nscert & NS_SSL_CLIENT)) ? SUCCESS : FAILURE; + /* + * Unfortunately, X509_check_purpose() does some wierd thing that + * prevent it to take a const argument + */ + return X509_check_purpose((X509 *)peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ? + SUCCESS : FAILURE; } if (usage == NS_CERT_CHECK_SERVER) { - return ((peer_cert->ex_flags & EXFLAG_NSCERT) - && (peer_cert->ex_nscert & NS_SSL_SERVER)) ? SUCCESS : FAILURE; + /* + * Unfortunately, X509_check_purpose() does some wierd thing that + * prevent it to take a const argument + */ + return X509_check_purpose((X509 *)peer_cert, X509_PURPOSE_SSL_SERVER, 0) ? + SUCCESS : FAILURE; } return FAILURE; -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:36
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including EVP_PKEY. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 2 ++ src/openvpn/openssl_compat.h | 28 ++++++++++++++++++++++++++++ src/openvpn/ssl_openssl.c | 6 +++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index c41db3effbb26318be4f44009a5055e808b89b56..4815b8928dc04239d5019d246fd2cb13cbc99d52 100644 --- a/configure.ac +++ b/configure.ac @@ -906,6 +906,8 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then X509_STORE_get0_objects \ X509_OBJECT_free \ X509_OBJECT_get_type \ + EVP_PKEY_get0_RSA \ + EVP_PKEY_get0_DSA \ RSA_meth_new \ RSA_meth_free \ RSA_meth_set_pub_enc \ diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 6a89b91b05e0370a50ac5a1cae20ae659e6c7634..5062b705cccdff7c6b8a248be6819d3f54f64133 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -134,6 +134,34 @@ X509_OBJECT_get_type(const X509_OBJECT *obj) } #endif +#if !defined(HAVE_EVP_PKEY_GET0_RSA) +/** + * Get the RSA object of a public key + * + * @param pkey Public key object + * @return The underlying RSA object + */ +static inline RSA * +EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + return pkey ? pkey->pkey.rsa : NULL; +} +#endif + +#if !defined(HAVE_EVP_PKEY_GET0_DSA) +/** + * Get the DSA object of a public key + * + * @param pkey Public key object + * @return The underlying DSA object + */ +static inline DSA * +EVP_PKEY_get0_DSA(EVP_PKEY *pkey) +{ + return pkey ? pkey->pkey.dsa : NULL; +} +#endif + #if !defined(HAVE_RSA_METH_NEW) /** * Allocate a new RSA method object diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index b683961d9e4e79b9ee04cfa7ecd1b377ade9651b..dbeb868ebe89f8c18a7b89afd797c3e42dda1503 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -1075,7 +1075,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, /* get the public key */ EVP_PKEY *pkey = X509_get0_pubkey(cert); ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ - pub_rsa = cert->cert_info->key->pkey->pkey.rsa; + pub_rsa = EVP_PKEY_get0_RSA(pkey); /* initialize RSA object */ rsa->n = BN_dup(pub_rsa->n); @@ -1680,13 +1680,13 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) EVP_PKEY *pkey = X509_get_pubkey(cert); if (pkey != NULL) { - if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL && pkey->pkey.rsa->n != NULL) { openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", BN_num_bits(pkey->pkey.rsa->n)); } - else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL + else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL && pkey->pkey.dsa->p != NULL) { openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:39
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including RSA. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 3 ++ src/openvpn/openssl_compat.h | 84 ++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_openssl.c | 25 ++++++++----- 3 files changed, 104 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 4815b8928dc04239d5019d246fd2cb13cbc99d52..d2f9eb5aae7351fb76c94b4cccd7e0a7cd50ddee 100644 --- a/configure.ac +++ b/configure.ac @@ -908,6 +908,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then X509_OBJECT_get_type \ EVP_PKEY_get0_RSA \ EVP_PKEY_get0_DSA \ + RSA_set_flags \ + RSA_get0_key \ + RSA_set0_key \ RSA_meth_new \ RSA_meth_free \ RSA_meth_set_pub_enc \ diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 5062b705cccdff7c6b8a248be6819d3f54f64133..1e6f062b805022a3555204fe95cc0ef428b2bc54 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -162,6 +162,90 @@ EVP_PKEY_get0_DSA(EVP_PKEY *pkey) } #endif +#if !defined(HAVE_RSA_SET_FLAGS) +/** + * Set the RSA flags + * + * @param rsa The RSA object + * @param flags New flags value + */ +static inline void +RSA_set_flags(RSA *rsa, int flags) +{ + if (rsa) + { + rsa->flags = flags; + } +} +#endif + +#if !defined(HAVE_RSA_GET0_KEY) +/** + * Get the RSA parameters + * + * @param rsa The RSA object + * @param n The @c n parameter + * @param e The @c e parameter + * @param d The @c d parameter + */ +static inline void +RSA_get0_key(const RSA *rsa, const BIGNUM **n, + const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + { + *n = rsa ? rsa->n : NULL; + } + if (e != NULL) + { + *e = rsa ? rsa->e : NULL; + } + if (d != NULL) + { + *d = rsa ? rsa->d : NULL; + } +} +#endif + +#if !defined(HAVE_RSA_SET0_KEY) +/** + * Set the RSA parameters + * + * @param rsa The RSA object + * @param n The @c n parameter + * @param e The @c e parameter + * @param d The @c d parameter + * @return 1 on success, 0 on error + */ +static inline int +RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + if ((rsa->n == NULL && n == NULL) + || (rsa->e == NULL && e == NULL)) + { + return 0; + } + + if (n != NULL) + { + BN_free(rsa->n); + rsa->n = n; + } + if (e != NULL) + { + BN_free(rsa->e); + rsa->e = e; + } + if (d != NULL) + { + BN_free(rsa->d); + rsa->d = d; + } + + return 1; +} +#endif + #if !defined(HAVE_RSA_METH_NEW) /** * Allocate a new RSA method object diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index dbeb868ebe89f8c18a7b89afd797c3e42dda1503..416ba0c5620a013d97db455c719a8fef60128b88 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -978,8 +978,9 @@ rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i static int rsa_finish(RSA *rsa) { - RSA_meth_free(rsa->meth); - rsa->meth = NULL; + RSA_METHOD *meth = (RSA_METHOD *)RSA_get_method(rsa); + RSA_meth_free(meth); + RSA_set_method(rsa, NULL); return 1; } @@ -1078,8 +1079,11 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, pub_rsa = EVP_PKEY_get0_RSA(pkey); /* initialize RSA object */ - rsa->n = BN_dup(pub_rsa->n); - rsa->flags |= RSA_FLAG_EXT_PKEY; + const BIGNUM *n = NULL; + const BIGNUM *e = NULL; + RSA_get0_key(pub_rsa, &n, &e, NULL); + RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL); + RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY); if (!RSA_set_method(rsa, rsa_meth)) { goto err; @@ -1680,11 +1684,16 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) EVP_PKEY *pkey = X509_get_pubkey(cert); if (pkey != NULL) { - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL - && pkey->pkey.rsa->n != NULL) + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL) { - openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", - BN_num_bits(pkey->pkey.rsa->n)); + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + const BIGNUM *n = NULL; + RSA_get0_key(rsa, &n, NULL, NULL); + if (n != NULL) + { + openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", + BN_num_bits(n)); + } } else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL && pkey->pkey.dsa->p != NULL) -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:40
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including X509_STORE_CTX. We have to use the defined functions to do so. Fortunately, these functions have existed since the dawn of time so we don't have any compatibility issue here. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- src/openvpn/ssl_verify_openssl.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index edc709b89eb05bca895639dde606b29f8e1f7024..5bdd1e3609c4a2693e16c0835a9e5c39babd5ff8 100644 --- a/src/openvpn/ssl_verify_openssl.c +++ b/src/openvpn/ssl_verify_openssl.c @@ -62,14 +62,15 @@ verify_callback(int preverify_ok, X509_STORE_CTX *ctx) session = (struct tls_session *) SSL_get_ex_data(ssl, mydata_index); ASSERT(session); - struct buffer cert_hash = x509_get_sha256_fingerprint(ctx->current_cert, &gc); - cert_hash_remember(session, ctx->error_depth, &cert_hash); + X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); + struct buffer cert_hash = x509_get_sha256_fingerprint(current_cert, &gc); + cert_hash_remember(session, X509_STORE_CTX_get_error_depth(ctx), &cert_hash); /* did peer present cert which was signed by our root cert? */ if (!preverify_ok) { /* get the X509 name */ - char *subject = x509_get_subject(ctx->current_cert, &gc); + char *subject = x509_get_subject(current_cert, &gc); if (!subject) { @@ -77,11 +78,11 @@ verify_callback(int preverify_ok, X509_STORE_CTX *ctx) } /* Log and ignore missing CRL errors */ - if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL) + if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL) { msg(D_TLS_DEBUG_LOW, "VERIFY WARNING: depth=%d, %s: %s", - ctx->error_depth, - X509_verify_cert_error_string(ctx->error), + X509_STORE_CTX_get_error_depth(ctx), + X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)), subject); ret = 1; goto cleanup; @@ -89,8 +90,8 @@ verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* Remote site specified a certificate, but it's not correct */ msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s", - ctx->error_depth, - X509_verify_cert_error_string(ctx->error), + X509_STORE_CTX_get_error_depth(ctx), + X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)), subject); ERR_clear_error(); @@ -99,7 +100,7 @@ verify_callback(int preverify_ok, X509_STORE_CTX *ctx) goto cleanup; } - if (SUCCESS != verify_cert(session, ctx->current_cert, ctx->error_depth)) + if (SUCCESS != verify_cert(session, current_cert, X509_STORE_CTX_get_error_depth(ctx))) { goto cleanup; } -- 2.7.4 |
From: Gert D. <ge...@gr...> - 2017-02-22 16:07:39
|
Your patch has been applied to the master and release/2.4 branch. commit 88046ad9e8e333259ae6fb4a295a9931a1a0e47f (master) commit 58efba5013f6dae4136cc038af9ffd23796cbc0d (release/2.4) Author: Emmanuel Deloget Date: Fri Feb 17 23:00:48 2017 +0100 OpenSSL: don't use direct access to the internal of X509_STORE_CTX Signed-off-by: Emmanuel Deloget <lo...@fr...> Acked-by: Steffan Karger <ste...@fo...> Message-Id: <114...@fr...> URL: https://www.mail-archive.com/ope...@li.../msg14085.html Signed-off-by: Gert Doering <ge...@gr...> -- kind regards, Gert Doering |
From: <lo...@fr...> - 2017-02-17 22:01:39
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including DSA. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 1 + src/openvpn/openssl_compat.h | 28 ++++++++++++++++++++++++++++ src/openvpn/ssl_openssl.c | 13 +++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index d2f9eb5aae7351fb76c94b4cccd7e0a7cd50ddee..3f59ba051692fa40304a203355c82812ca0962e8 100644 --- a/configure.ac +++ b/configure.ac @@ -911,6 +911,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then RSA_set_flags \ RSA_get0_key \ RSA_set0_key \ + DSA_get0_pqg \ RSA_meth_new \ RSA_meth_free \ RSA_meth_set_pub_enc \ diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 1e6f062b805022a3555204fe95cc0ef428b2bc54..d4f16e4a2ce485d80ad82ca1ef677cf6c4c4ebf7 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -246,6 +246,34 @@ RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) } #endif +#if !defined(HAVE_DSA_GET0_PQG) +/** + * Get the DSA parameters + * + * @param dsa The DSA object + * @param p The @c p parameter + * @param q The @c q parameter + * @param g The @c g parameter + */ +static inline void +DSA_get0_pqg(const DSA *dsa, const BIGNUM **p, + const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + { + *p = dsa ? dsa->p : NULL; + } + if (q != NULL) + { + *q = dsa ? dsa->q : NULL; + } + if (g != NULL) + { + *g = dsa ? dsa->g : NULL; + } +} +#endif + #if !defined(HAVE_RSA_METH_NEW) /** * Allocate a new RSA method object diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 416ba0c5620a013d97db455c719a8fef60128b88..a9ae20f45fe60d35af97e7d14bfd2332f9360c30 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -1695,11 +1695,16 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) BN_num_bits(n)); } } - else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL - && pkey->pkey.dsa->p != NULL) + else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL) { - openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", - BN_num_bits(pkey->pkey.dsa->p)); + DSA *dsa = EVP_PKEY_get0_DSA(pkey); + const BIGNUM *p = NULL; + DSA_get0_pqg(dsa, &p, NULL, NULL); + if (p != NULL) + { + openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", + BN_num_bits(p)); + } } EVP_PKEY_free(pkey); } -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:43
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including EVP_MD_CTX. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 3 ++ src/openvpn/crypto_backend.h | 14 ++++++++ src/openvpn/crypto_mbedtls.c | 12 +++++++ src/openvpn/crypto_openssl.c | 18 ++++++++-- src/openvpn/httpdigest.c | 78 +++++++++++++++++++++++--------------------- src/openvpn/misc.c | 14 ++++---- src/openvpn/openssl_compat.h | 50 ++++++++++++++++++++++++++++ src/openvpn/openvpn.h | 2 +- src/openvpn/push.c | 11 ++++--- 9 files changed, 150 insertions(+), 52 deletions(-) diff --git a/configure.ac b/configure.ac index 3f59ba051692fa40304a203355c82812ca0962e8..c7e9df5e3ef3f3740f2db79fef6d5c1587c47800 100644 --- a/configure.ac +++ b/configure.ac @@ -900,6 +900,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then AC_CHECK_FUNCS( [ \ + EVP_MD_CTX_new \ + EVP_MD_CTX_free \ + EVP_MD_CTX_reset \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ X509_get0_pubkey \ diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index 2c79baa15c2021d679e1bddf269f4662e1686e5f..9b35cdaaf5a5f6c9f2b6af766fbb1b439db4c58f 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -502,6 +502,20 @@ int md_kt_size(const md_kt_t *kt); int md_full(const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst); /* + * Allocate a new message digest context + * + * @return a new zeroed MD context + */ +md_ctx_t *md_ctx_new(void); + +/* + * Free an existing, non-null message digest context + * + * @param ctx Message digest context + */ +void md_ctx_free(md_ctx_t *ctx); + +/* * Initialises the given message digest context. * * @param ctx Message digest context diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index 942684ce03f62761bee538ec1abf53e958218ad1..d67415233cd4f7d7b75a43ac30ad864458b75b47 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -766,6 +766,18 @@ md_full(const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst) return 0 == mbedtls_md(kt, src, src_len, dst); } +mbedtls_md_context_t * +md_ctx_new(void) +{ + mbedtls_md_context_t *ctx; + ALLOC_OBJ_CLEAR(ctx, mbedtls_md_context_t); + return ctx; +} + +void md_ctx_free(mbedtls_md_context_t *ctx) +{ + free(ctx); +} void md_ctx_init(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index e4557156106ae099ea07979a3dcc656995659502..da3abfb7ef30fe23d7b47cd398c5cbdf61a9718b 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -42,6 +42,7 @@ #include "integer.h" #include "crypto.h" #include "crypto_backend.h" +#include "openssl_compat.h" #include <openssl/des.h> #include <openssl/err.h> @@ -846,13 +847,24 @@ md_full(const EVP_MD *kt, const uint8_t *src, int src_len, uint8_t *dst) return EVP_Digest(src, src_len, dst, &in_md_len, kt, NULL); } +EVP_MD_CTX * +md_ctx_new(void) +{ + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + check_malloc_return(ctx); + return ctx; +} + +void md_ctx_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_free(ctx); +} + void md_ctx_init(EVP_MD_CTX *ctx, const EVP_MD *kt) { ASSERT(NULL != ctx && NULL != kt); - CLEAR(*ctx); - EVP_MD_CTX_init(ctx); EVP_DigestInit(ctx, kt); } @@ -860,7 +872,7 @@ md_ctx_init(EVP_MD_CTX *ctx, const EVP_MD *kt) void md_ctx_cleanup(EVP_MD_CTX *ctx) { - EVP_MD_CTX_cleanup(ctx); + EVP_MD_CTX_reset(ctx); } int diff --git a/src/openvpn/httpdigest.c b/src/openvpn/httpdigest.c index ae4a638fbf9f1307a7e91da02c42edff95cc9307..2a66d9b8470d205e242463b55c0f549fd766d6f4 100644 --- a/src/openvpn/httpdigest.c +++ b/src/openvpn/httpdigest.c @@ -81,27 +81,28 @@ DigestCalcHA1( ) { HASH HA1; - md_ctx_t md5_ctx; + md_ctx_t *md5_ctx = md_ctx_new(); const md_kt_t *md5_kt = md_kt_get("MD5"); - md_ctx_init(&md5_ctx, md5_kt); - md_ctx_update(&md5_ctx, (const uint8_t *) pszUserName, strlen(pszUserName)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszRealm, strlen(pszRealm)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszPassword, strlen(pszPassword)); - md_ctx_final(&md5_ctx, HA1); + md_ctx_init(md5_ctx, md5_kt); + md_ctx_update(md5_ctx, (const uint8_t *) pszUserName, strlen(pszUserName)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszRealm, strlen(pszRealm)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszPassword, strlen(pszPassword)); + md_ctx_final(md5_ctx, HA1); if (pszAlg && strcasecmp(pszAlg, "md5-sess") == 0) { - md_ctx_init(&md5_ctx, md5_kt); - md_ctx_update(&md5_ctx, HA1, HASHLEN); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); - md_ctx_final(&md5_ctx, HA1); + md_ctx_init(md5_ctx, md5_kt); + md_ctx_update(md5_ctx, HA1, HASHLEN); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); + md_ctx_final(md5_ctx, HA1); } - md_ctx_cleanup(&md5_ctx); + md_ctx_cleanup(md5_ctx); + md_ctx_free(md5_ctx); CvtHex(HA1, SessionKey); } @@ -123,40 +124,41 @@ DigestCalcResponse( HASH RespHash; HASHHEX HA2Hex; - md_ctx_t md5_ctx; + md_ctx_t *md5_ctx = md_ctx_new(); const md_kt_t *md5_kt = md_kt_get("MD5"); /* calculate H(A2) */ - md_ctx_init(&md5_ctx, md5_kt); - md_ctx_update(&md5_ctx, (const uint8_t *) pszMethod, strlen(pszMethod)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszDigestUri, strlen(pszDigestUri)); + md_ctx_init(md5_ctx, md5_kt); + md_ctx_update(md5_ctx, (const uint8_t *) pszMethod, strlen(pszMethod)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszDigestUri, strlen(pszDigestUri)); if (strcasecmp(pszQop, "auth-int") == 0) { - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, HEntity, HASHHEXLEN); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, HEntity, HASHHEXLEN); } - md_ctx_final(&md5_ctx, HA2); + md_ctx_final(md5_ctx, HA2); CvtHex(HA2, HA2Hex); /* calculate response */ - md_ctx_init(&md5_ctx, md5_kt); - md_ctx_update(&md5_ctx, HA1, HASHHEXLEN); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); + md_ctx_init(md5_ctx, md5_kt); + md_ctx_update(md5_ctx, HA1, HASHHEXLEN); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); if (*pszQop) { - md_ctx_update(&md5_ctx, (const uint8_t *) pszNonceCount, strlen(pszNonceCount)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); - md_ctx_update(&md5_ctx, (const uint8_t *) pszQop, strlen(pszQop)); - md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszNonceCount, strlen(pszNonceCount)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); + md_ctx_update(md5_ctx, (const uint8_t *) pszQop, strlen(pszQop)); + md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); } - md_ctx_update(&md5_ctx, HA2Hex, HASHHEXLEN); - md_ctx_final(&md5_ctx, RespHash); - md_ctx_cleanup(&md5_ctx); + md_ctx_update(md5_ctx, HA2Hex, HASHHEXLEN); + md_ctx_final(md5_ctx, RespHash); + md_ctx_cleanup(md5_ctx); + md_ctx_free(md5_ctx); CvtHex(RespHash, Response); } diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index a2f45b61c1aa1dd279fddaf5031fc2bc9aa82145..0c422dd128a6f01f04b0943f86ed4648c4cb2576 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -1439,7 +1439,7 @@ get_user_pass_auto_userid(struct user_pass *up, const char *tag) static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST"; const md_kt_t *md5_kt = md_kt_get("MD5"); - md_ctx_t ctx; + md_ctx_t *ctx; CLEAR(*up); buf_set_write(&buf, (uint8_t *)up->username, USER_PASS_LEN); @@ -1447,11 +1447,13 @@ get_user_pass_auto_userid(struct user_pass *up, const char *tag) if (get_default_gateway_mac_addr(macaddr)) { dmsg(D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex(macaddr, sizeof(macaddr), 0, 1, ":", &gc)); - md_ctx_init(&ctx, md5_kt); - md_ctx_update(&ctx, hashprefix, sizeof(hashprefix) - 1); - md_ctx_update(&ctx, macaddr, sizeof(macaddr)); - md_ctx_final(&ctx, digest); - md_ctx_cleanup(&ctx) + ctx = md_ctx_new(); + md_ctx_init(ctx, md5_kt); + md_ctx_update(ctx, hashprefix, sizeof(hashprefix) - 1); + md_ctx_update(ctx, macaddr, sizeof(macaddr)); + md_ctx_final(ctx, digest); + md_ctx_cleanup(ctx); + md_ctx_free(ctx); buf_printf(&buf, "%s", format_hex_ex(digest, sizeof(digest), 0, 256, " ", &gc)); } else diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index d4f16e4a2ce485d80ad82ca1ef677cf6c4c4ebf7..3be0f4a5abe913e5b67115b86f840a4d107f9c56 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -46,6 +46,56 @@ #include <openssl/ssl.h> #include <openssl/x509.h> +#include <openssl/des.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/objects.h> +#include <openssl/rand.h> +#include <openssl/ssl.h> + +#if !defined(HAVE_EVP_MD_CTX_RESET) +/** + * Reset a message digest context + * + * @param ctx The message digest context + * @return 1 on success, 0 on error + */ +static inline int +EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_cleanup(ctx); + return 1; +} +#endif + +#if !defined(HAVE_EVP_MD_CTX_FREE) +/** + * Free an existing message digest context + * + * @param ctx The message digest context + */ +static inline void +EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + free(ctx); +} +#endif + +#if !defined(HAVE_EVP_MD_CTX_NEW) +/** + * Allocate a new message digest object + * + * @return A zero'ed message digest object + */ +static inline EVP_MD_CTX * +EVP_MD_CTX_new(void) +{ + EVP_MD_CTX *ctx = NULL; + ALLOC_OBJ_CLEAR(ctx, EVP_MD_CTX); + return ctx; +} +#endif + #if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) /** * Fetch the default password callback user data from the SSL context diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index 893296edc539800db6463b5861e6f7c83cbac115..e6cea506e37f987c8dffcef33033556d6f2c37ee 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -472,7 +472,7 @@ struct context_2 /* hash of pulled options, so we can compare when options change */ bool pulled_options_digest_init_done; - md_ctx_t pulled_options_state; + md_ctx_t *pulled_options_state; struct sha256_digest pulled_options_digest; struct event_timeout scheduled_exit; diff --git a/src/openvpn/push.c b/src/openvpn/push.c index 8c3104ed7690cdf24463c1d610cecf955d744cf4..7479f7c2f925dd2f74011c73e283a4421ed60bf6 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -722,7 +722,8 @@ process_incoming_push_msg(struct context *c, struct buffer buf_orig = buf; if (!c->c2.pulled_options_digest_init_done) { - md_ctx_init(&c->c2.pulled_options_state, md_kt_get("SHA256")); + c->c2.pulled_options_state = md_ctx_new(); + md_ctx_init(c->c2.pulled_options_state, md_kt_get("SHA256")); c->c2.pulled_options_digest_init_done = true; } if (!c->c2.did_pre_pull_restore) @@ -736,14 +737,16 @@ process_incoming_push_msg(struct context *c, option_types_found, c->c2.es)) { - push_update_digest(&c->c2.pulled_options_state, &buf_orig, + push_update_digest(c->c2.pulled_options_state, &buf_orig, &c->options); switch (c->options.push_continuation) { case 0: case 1: - md_ctx_final(&c->c2.pulled_options_state, c->c2.pulled_options_digest.digest); - md_ctx_cleanup(&c->c2.pulled_options_state); + md_ctx_final(c->c2.pulled_options_state, c->c2.pulled_options_digest.digest); + md_ctx_cleanup(c->c2.pulled_options_state); + md_ctx_free(c->c2.pulled_options_state); + c->c2.pulled_options_state = NULL; c->c2.pulled_options_digest_init_done = false; ret = PUSH_MSG_REPLY; break; -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:44
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including EVP_CIPHER_CTX. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 2 ++ src/openvpn/crypto.c | 4 ++-- src/openvpn/crypto_backend.h | 14 ++++++++++++++ src/openvpn/crypto_mbedtls.c | 13 +++++++++++++ src/openvpn/crypto_openssl.c | 15 +++++++++++++-- src/openvpn/openssl_compat.h | 28 ++++++++++++++++++++++++++++ 6 files changed, 72 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index c7e9df5e3ef3f3740f2db79fef6d5c1587c47800..ff9b00447fce07d9f1c408a00ea2fafe8c786cb7 100644 --- a/configure.ac +++ b/configure.ac @@ -900,6 +900,8 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then AC_CHECK_FUNCS( [ \ + EVP_CIPHER_CTX_new \ + EVP_CIPHER_CTX_free \ EVP_MD_CTX_new \ EVP_MD_CTX_free \ EVP_MD_CTX_reset \ diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 909f725300fce7fb8986f4afb706a97e968ff195..4ba344d1f6185afcc2205a7ce501607a2b5fff87 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -820,7 +820,7 @@ init_key_ctx(struct key_ctx *ctx, struct key *key, if (kt->cipher && kt->cipher_length > 0) { - ALLOC_OBJ(ctx->cipher, cipher_ctx_t); + ctx->cipher = cipher_ctx_new(); cipher_ctx_init(ctx->cipher, key->cipher, kt->cipher_length, kt->cipher, enc); @@ -869,7 +869,7 @@ free_key_ctx(struct key_ctx *ctx) if (ctx->cipher) { cipher_ctx_cleanup(ctx->cipher); - free(ctx->cipher); + cipher_ctx_free(ctx->cipher); ctx->cipher = NULL; } if (ctx->hmac) diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index 9b35cdaaf5a5f6c9f2b6af766fbb1b439db4c58f..04876bffe9c9de0afd40ff58bcba5dce3eab18ca 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -295,6 +295,20 @@ bool cipher_kt_mode_aead(const cipher_kt_t *cipher); */ /** + * Allocate a new cipher context + * + * @return a new cipher context + */ +cipher_ctx_t *cipher_ctx_new(void); + +/** + * Free a cipher context + * + * @param ctx Cipher context. + */ +void cipher_ctx_free(cipher_ctx_t *ctx); + +/** * Initialise a cipher context, based on the given key and key type. * * @param ctx Cipher context. May not be NULL diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index d67415233cd4f7d7b75a43ac30ad864458b75b47..4d38aadcdbd3a3158cd8a1da5f335e80e0c3a27d 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -509,6 +509,19 @@ cipher_kt_mode_aead(const cipher_kt_t *cipher) * */ +mbedtls_cipher_context_t * +cipher_ctx_new(void) +{ + mbedtls_cipher_context_t *ctx; + ALLOC_OBJ(ctx, mbedtls_cipher_context_t); + return ctx; +} + +void +cipher_ctx_free(mbedtls_cipher_context_t *ctx) +{ + free(ctx); +} void cipher_ctx_init(mbedtls_cipher_context_t *ctx, uint8_t *key, int key_len, diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index da3abfb7ef30fe23d7b47cd398c5cbdf61a9718b..82da531f353a2430dbc2c4396aff459844af0cc2 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -653,6 +653,19 @@ cipher_kt_mode_aead(const cipher_kt_t *cipher) * */ +cipher_ctx_t * +cipher_ctx_new(void) +{ + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + check_malloc_return(ctx); + return ctx; +} + +void +cipher_ctx_free(EVP_CIPHER_CTX *ctx) +{ + EVP_CIPHER_CTX_free(ctx); +} void cipher_ctx_init(EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, @@ -660,8 +673,6 @@ cipher_ctx_init(EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, { ASSERT(NULL != kt && NULL != ctx); - CLEAR(*ctx); - EVP_CIPHER_CTX_init(ctx); if (!EVP_CipherInit(ctx, kt, NULL, NULL, enc)) { diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 3be0f4a5abe913e5b67115b86f840a4d107f9c56..9e3969c65bfdcf2a2453ba2196bb70a0102112bd 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -96,6 +96,34 @@ EVP_MD_CTX_new(void) } #endif +#if !defined(HAVE_EVP_CIPHER_CTX_FREE) +/** + * Free an existing cipher context + * + * @param ctx The cipher context + */ +static inline void +EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c) +{ + free(c); +} +#endif + +#if !defined(HAVE_EVP_CIPHER_CTX_NEW) +/** + * Allocate a new cipher context object + * + * @return A zero'ed cipher context object + */ +static inline EVP_CIPHER_CTX * +EVP_CIPHER_CTX_new(void) +{ + EVP_CIPHER_CTX *ctx = NULL; + ALLOC_OBJ_CLEAR(ctx, EVP_CIPHER_CTX); + return ctx; +} +#endif + #if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) /** * Fetch the default password callback user data from the SSL context -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:46
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 does not allow us to directly access the internal of any data type, including HMAC_CTX. We have to use the defined functions to do so. Compatibility with OpenSSL 1.0 is kept by defining the corresponding functions when they are not found in the library. Signed-off-by: Emmanuel Deloget <lo...@fr...> --- configure.ac | 4 +++ src/openvpn/crypto.c | 4 +-- src/openvpn/crypto_backend.h | 14 ++++++++++ src/openvpn/crypto_mbedtls.c | 15 ++++++++++ src/openvpn/crypto_openssl.c | 17 ++++++++++-- src/openvpn/ntlm.c | 12 ++++---- src/openvpn/openssl_compat.h | 65 ++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl.c | 38 ++++++++++++++------------ 8 files changed, 140 insertions(+), 29 deletions(-) diff --git a/configure.ac b/configure.ac index ff9b00447fce07d9f1c408a00ea2fafe8c786cb7..b8afda2df90081b7e1a7272d019eddfc21cf7bc8 100644 --- a/configure.ac +++ b/configure.ac @@ -902,6 +902,10 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then [ \ EVP_CIPHER_CTX_new \ EVP_CIPHER_CTX_free \ + HMAC_CTX_new \ + HMAC_CTX_free \ + HMAC_CTX_reset \ + HMAC_CTX_init \ EVP_MD_CTX_new \ EVP_MD_CTX_free \ EVP_MD_CTX_reset \ diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 4ba344d1f6185afcc2205a7ce501607a2b5fff87..dd7c8d8a8113d5e8136544df325de9d39b2be2b9 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -844,7 +844,7 @@ init_key_ctx(struct key_ctx *ctx, struct key *key, } if (kt->digest && kt->hmac_length > 0) { - ALLOC_OBJ(ctx->hmac, hmac_ctx_t); + ctx->hmac = hmac_ctx_new(); hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest); msg(D_HANDSHAKE, @@ -875,7 +875,7 @@ free_key_ctx(struct key_ctx *ctx) if (ctx->hmac) { hmac_ctx_cleanup(ctx->hmac); - free(ctx->hmac); + hmac_ctx_free(ctx->hmac); ctx->hmac = NULL; } ctx->implicit_iv_len = 0; diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index 04876bffe9c9de0afd40ff58bcba5dce3eab18ca..e5442c5f7875dad6156c21870c5c168a4c8a2929 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -578,6 +578,20 @@ void md_ctx_final(md_ctx_t *ctx, uint8_t *dst); */ /* + * Create a new HMAC context + * + * @return A new HMAC context + */ +hmac_ctx_t *hmac_ctx_new(void); + +/* + * Free an existing HMAC context + * + * @param ctx HMAC context to free + */ +void hmac_ctx_free(hmac_ctx_t *ctx); + +/* * Initialises the given HMAC context, using the given digest * and key. * diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index 4d38aadcdbd3a3158cd8a1da5f335e80e0c3a27d..f0698f61dd925f591cc39a9e931cbd7fb7a0dee0 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -841,6 +841,21 @@ md_ctx_final(mbedtls_md_context_t *ctx, uint8_t *dst) /* * TODO: re-enable dmsg for crypto debug */ + +mbedtls_md_context_t * +hmac_ctx_new(void) +{ + mbedtls_md_context_t *ctx; + ALLOC_OBJ(ctx, mbedtls_md_context_t); + return ctx; +} + +void +hmac_ctx_free(mbedtls_md_context_t *ctx) +{ + free(ctx); +} + void hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, int key_len, const mbedtls_md_info_t *kt) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 82da531f353a2430dbc2c4396aff459844af0cc2..2f77a9853ac484770dcd808efdf13671ade7e758 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -913,6 +913,19 @@ md_ctx_final(EVP_MD_CTX *ctx, uint8_t *dst) * */ +HMAC_CTX * +hmac_ctx_new(void) +{ + HMAC_CTX *ctx = HMAC_CTX_new(); + check_malloc_return(ctx); + return ctx; +} + +void +hmac_ctx_free(HMAC_CTX *ctx) +{ + HMAC_CTX_free(ctx); +} void hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len, @@ -920,8 +933,6 @@ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len, { ASSERT(NULL != kt && NULL != ctx); - CLEAR(*ctx); - HMAC_CTX_init(ctx); HMAC_Init_ex(ctx, key, key_len, kt, NULL); @@ -932,7 +943,7 @@ hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len, void hmac_ctx_cleanup(HMAC_CTX *ctx) { - HMAC_CTX_cleanup(ctx); + HMAC_CTX_reset(ctx); } int diff --git a/src/openvpn/ntlm.c b/src/openvpn/ntlm.c index 0c436812ece383331fc0106e9e399fb1e660786c..4a4e8b9b034efa6a8fd752aa43f892df585f94d5 100644 --- a/src/openvpn/ntlm.c +++ b/src/openvpn/ntlm.c @@ -86,13 +86,13 @@ static void gen_hmac_md5(const char *data, int data_len, const char *key, int key_len,char *result) { const md_kt_t *md5_kt = md_kt_get("MD5"); - hmac_ctx_t hmac_ctx; - CLEAR(hmac_ctx); + hmac_ctx_t *hmac_ctx = hmac_ctx_new(); - hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt); - hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len); - hmac_ctx_final(&hmac_ctx, (unsigned char *)result); - hmac_ctx_cleanup(&hmac_ctx); + hmac_ctx_init(hmac_ctx, key, key_len, md5_kt); + hmac_ctx_update(hmac_ctx, (const unsigned char *)data, data_len); + hmac_ctx_final(hmac_ctx, (unsigned char *)result); + hmac_ctx_cleanup(hmac_ctx); + hmac_ctx_free(hmac_ctx); } static void diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 9e3969c65bfdcf2a2453ba2196bb70a0102112bd..f81ec59c134fb6da2b802e66339ecd0d67040928 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -124,6 +124,71 @@ EVP_CIPHER_CTX_new(void) } #endif +#if !defined(HAVE_HMAC_CTX_RESET) +/** + * Reset a HMAC context + * + * @param ctx The HMAC context + * @return 1 on success, 0 on error + */ +static inline int +HMAC_CTX_reset(HMAC_CTX *ctx) +{ + HMAC_CTX_cleanup(ctx); + return 1; +} +#endif + +#if !defined(HAVE_HMAC_CTX_INIT) +/** + * Init a HMAC context + * + * @param ctx The HMAC context + * + * Contrary to many functions in this file, HMAC_CTX_init() is not + * an OpenSSL 1.1 function: it comes from previous versions and was + * removed in v1.1. As a consequence, there is no distincting in + * v1.1 between a cleanup, and init and a reset. Yet, previous OpenSSL + * version need this distinction. + * + * In order to respect previous OpenSSL versions, we implement init + * as reset for OpenSSL 1.1+. + */ +static inline void +HMAC_CTX_init(HMAC_CTX *ctx) +{ + HMAC_CTX_reset(ctx); +} +#endif + +#if !defined(HAVE_HMAC_CTX_FREE) +/** + * Free an existing HMAC context + * + * @param ctx The HMAC context + */ +static inline void +HMAC_CTX_free(HMAC_CTX *c) +{ + free(c); +} +#endif + +#if !defined(HAVE_HMAC_CTX_NEW) +/** + * Allocate a new HMAC context object + * + * @return A zero'ed HMAC context object + */ +static inline HMAC_CTX * +HMAC_CTX_new(void) +{ + HMAC_CTX *ctx = NULL; + ALLOC_OBJ_CLEAR(ctx, HMAC_CTX); + return ctx; +} +#endif + #if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) /** * Fetch the default password callback user data from the SSL context diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 86450fe057f33fa10803775da69d2506687a4313..03dc80ff9e4b69184bd90dc2f3b1fe1d2718be49 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1614,8 +1614,8 @@ tls1_P_hash(const md_kt_t *md_kt, { struct gc_arena gc = gc_new(); int chunk; - hmac_ctx_t ctx; - hmac_ctx_t ctx_tmp; + hmac_ctx_t *ctx; + hmac_ctx_t *ctx_tmp; uint8_t A1[MAX_HMAC_KEY_LENGTH]; unsigned int A1_len; @@ -1624,8 +1624,8 @@ tls1_P_hash(const md_kt_t *md_kt, const uint8_t *out_orig = out; #endif - CLEAR(ctx); - CLEAR(ctx_tmp); + ctx = hmac_ctx_new(); + ctx_tmp = hmac_ctx_new(); dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc)); dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc)); @@ -1633,36 +1633,38 @@ tls1_P_hash(const md_kt_t *md_kt, chunk = md_kt_size(md_kt); A1_len = md_kt_size(md_kt); - hmac_ctx_init(&ctx, sec, sec_len, md_kt); - hmac_ctx_init(&ctx_tmp, sec, sec_len, md_kt); + hmac_ctx_init(ctx, sec, sec_len, md_kt); + hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt); - hmac_ctx_update(&ctx,seed,seed_len); - hmac_ctx_final(&ctx, A1); + hmac_ctx_update(ctx,seed,seed_len); + hmac_ctx_final(ctx, A1); for (;; ) { - hmac_ctx_reset(&ctx); - hmac_ctx_reset(&ctx_tmp); - hmac_ctx_update(&ctx,A1,A1_len); - hmac_ctx_update(&ctx_tmp,A1,A1_len); - hmac_ctx_update(&ctx,seed,seed_len); + hmac_ctx_reset(ctx); + hmac_ctx_reset(ctx_tmp); + hmac_ctx_update(ctx,A1,A1_len); + hmac_ctx_update(ctx_tmp,A1,A1_len); + hmac_ctx_update(ctx,seed,seed_len); if (olen > chunk) { - hmac_ctx_final(&ctx, out); + hmac_ctx_final(ctx, out); out += chunk; olen -= chunk; - hmac_ctx_final(&ctx_tmp, A1); /* calc the next A1 value */ + hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */ } else /* last one */ { - hmac_ctx_final(&ctx, A1); + hmac_ctx_final(ctx, A1); memcpy(out,A1,olen); break; } } - hmac_ctx_cleanup(&ctx); - hmac_ctx_cleanup(&ctx_tmp); + hmac_ctx_cleanup(ctx); + hmac_ctx_free(ctx); + hmac_ctx_cleanup(ctx_tmp); + hmac_ctx_free(ctx_tmp); secure_memzero(A1, sizeof(A1)); dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc)); -- 2.7.4 |
From: <lo...@fr...> - 2017-02-17 22:01:46
|
From: Emmanuel Deloget <lo...@fr...> The old symbols do not exist anymore but the library gained new equivalent symbols (OSSL). Use them instead of the old ones Signed-off-by: Emmanuel Deloget <lo...@fr...> --- src/openvpn/openssl_compat.h | 5 +++++ src/openvpn/ssl_openssl.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index f81ec59c134fb6da2b802e66339ecd0d67040928..054fd56cd1833bb5278eb5fd88a4c4d1908d6415 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -601,4 +601,9 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) } #endif +/* SSLeay symbols have been renamed in OpenSSL 1.1 */ +#if !defined(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT) +#define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT +#endif + #endif /* OPENSSL_COMPAT_H_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index a9ae20f45fe60d35af97e7d14bfd2332f9360c30..2ff3e12b93d6f829e4b27aefc2622d52e41ce589 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -996,7 +996,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i if (padding != RSA_PKCS1_PADDING) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto done; } -- 2.7.4 |
From: Steffan K. <st...@ka...> - 2017-03-02 20:39:46
|
Hi, On 17-02-17 23:00, lo...@fr... wrote: > From: Emmanuel Deloget <lo...@fr...> > > The old symbols do not exist anymore but the library gained new > equivalent symbols (OSSL). Use them instead of the old ones > > Signed-off-by: Emmanuel Deloget <lo...@fr...> > --- > src/openvpn/openssl_compat.h | 5 +++++ > src/openvpn/ssl_openssl.c | 2 +- > 2 files changed, 6 insertions(+), 1 deletion(-) > > diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h > index f81ec59c134fb6da2b802e66339ecd0d67040928..054fd56cd1833bb5278eb5fd88a4c4d1908d6415 100644 > --- a/src/openvpn/openssl_compat.h > +++ b/src/openvpn/openssl_compat.h > @@ -601,4 +601,9 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) > } > #endif > > +/* SSLeay symbols have been renamed in OpenSSL 1.1 */ > +#if !defined(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT) > +#define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT > +#endif > + > #endif /* OPENSSL_COMPAT_H_ */ > diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c > index a9ae20f45fe60d35af97e7d14bfd2332f9360c30..2ff3e12b93d6f829e4b27aefc2622d52e41ce589 100644 > --- a/src/openvpn/ssl_openssl.c > +++ b/src/openvpn/ssl_openssl.c > @@ -996,7 +996,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i > > if (padding != RSA_PKCS1_PADDING) > { > - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); > + RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); > goto done; > } > > ACK -Steffan |
From: Gert D. <ge...@gr...> - 2017-03-05 12:21:13
|
Your patch has been applied to the master and release/2.4 branch. commit c828ffc648eebda20e2f9087248944fa0f52a582 (master) commit d702b2539d43a3326d76cc1764fedf237fc6744f (release/2.4) Author: Emmanuel Deloget Date: Fri Feb 17 23:00:52 2017 +0100 OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1 Signed-off-by: Emmanuel Deloget <lo...@fr...> Acked-by: Steffan Karger <ste...@fo...> Message-Id: <9ce...@fr...> URL: https://www.mail-archive.com/ope...@li.../msg14089.html Signed-off-by: Gert Doering <ge...@gr...> -- kind regards, Gert Doering |
From: <lo...@fr...> - 2017-02-17 22:01:47
|
From: Emmanuel Deloget <lo...@fr...> OpenSSL 1.1 changed the SSLv3 API and removed many SSL_L_SSL3_* constants. Moreover, new code might use different function code for the same error. Thus, we extract the error reason from the error code before we compare it instead of trying to rebuild an error code that might not be correct. The new version is compatible with OpenSSL 1.0.x as well as with older versions (starting at 0.9.8). Signed-off-by: Emmanuel Deloget <lo...@fr...> --- src/openvpn/crypto_openssl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 2f77a9853ac484770dcd808efdf13671ade7e758..23de17542bf0f4a311825373ecf8d8261fd21c73 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -194,8 +194,7 @@ crypto_print_openssl_errors(const unsigned int flags) while ((err = ERR_get_error())) { /* Be more clear about frequently occurring "no shared cipher" error */ - if (err == ERR_PACK(ERR_LIB_SSL,SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_NO_SHARED_CIPHER)) + if (ERR_GET_REASON(err) == SSL_R_NO_SHARED_CIPHER) { msg(D_CRYPT_ERRORS, "TLS error: The server has no TLS ciphersuites " "in common with the client. Your --tls-cipher setting might be " -- 2.7.4 |
From: Steffan K. <st...@ka...> - 2017-02-19 12:37:02
|
Hi, On 17-02-17 23:00, lo...@fr... wrote: > From: Emmanuel Deloget <lo...@fr...> > > OpenSSL 1.1 changed the SSLv3 API and removed many SSL_L_SSL3_* > constants. Moreover, new code might use different function > code for the same error. > > Thus, we extract the error reason from the error code before > we compare it instead of trying to rebuild an error code > that might not be correct. > > The new version is compatible with OpenSSL 1.0.x as well as > with older versions (starting at 0.9.8). > > Signed-off-by: Emmanuel Deloget <lo...@fr...> > --- > src/openvpn/crypto_openssl.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c > index 2f77a9853ac484770dcd808efdf13671ade7e758..23de17542bf0f4a311825373ecf8d8261fd21c73 100644 > --- a/src/openvpn/crypto_openssl.c > +++ b/src/openvpn/crypto_openssl.c > @@ -194,8 +194,7 @@ crypto_print_openssl_errors(const unsigned int flags) > while ((err = ERR_get_error())) > { > /* Be more clear about frequently occurring "no shared cipher" error */ > - if (err == ERR_PACK(ERR_LIB_SSL,SSL_F_SSL3_GET_CLIENT_HELLO, > - SSL_R_NO_SHARED_CIPHER)) > + if (ERR_GET_REASON(err) == SSL_R_NO_SHARED_CIPHER) > { > msg(D_CRYPT_ERRORS, "TLS error: The server has no TLS ciphersuites " > "in common with the client. Your --tls-cipher setting might be " > This patch is correct even outside the context of the transition to 1.1, and can be applied immediately. ACK. -Steffan |