* [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
@ 2017-02-17 22:00 logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX logout
` (16 more replies)
0 siblings, 17 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
@ 2017-02-17 22:00 ` logout
2017-02-22 20:27 ` Steffan Karger
` (2 more replies)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 02/15] OpenSSL: don't use direct access to the internal of X509_STORE logout
` (15 subsequent siblings)
16 siblings, 3 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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. <sales@...515...>
+ * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@...1435...>
+ *
+ * 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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 02/15] OpenSSL: don't use direct access to the internal of X509_STORE
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX logout
@ 2017-02-17 22:00 ` logout
2017-02-22 20:36 ` Steffan Karger
2017-02-22 21:14 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct access to the internal of X509_OBJECT logout
` (14 subsequent siblings)
16 siblings, 2 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct access to the internal of X509_OBJECT
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 02/15] OpenSSL: don't use direct access to the internal of X509_STORE logout
@ 2017-02-17 22:00 ` logout
2017-02-22 20:50 ` Steffan Karger
2017-02-22 21:14 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD logout
` (13 subsequent siblings)
16 siblings, 2 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (2 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct access to the internal of X509_OBJECT logout
@ 2017-02-17 22:00 ` logout
2017-02-22 22:13 ` Steffan Karger
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509 logout
` (12 subsequent siblings)
16 siblings, 1 reply; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (3 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD logout
@ 2017-02-17 22:00 ` logout
2017-03-02 20:36 ` Steffan Karger
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY logout
` (11 subsequent siblings)
16 siblings, 1 reply; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (4 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509 logout
@ 2017-02-17 22:00 ` logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 07/15] OpenSSL: don't use direct access to the internal of RSA logout
` (10 subsequent siblings)
16 siblings, 0 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 07/15] OpenSSL: don't use direct access to the internal of RSA
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (5 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY logout
@ 2017-02-17 22:00 ` logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 08/15] OpenSSL: don't use direct access to the internal of DSA logout
` (9 subsequent siblings)
16 siblings, 0 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 08/15] OpenSSL: don't use direct access to the internal of DSA
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (6 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 07/15] OpenSSL: don't use direct access to the internal of RSA logout
@ 2017-02-17 22:00 ` logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX logout
` (8 subsequent siblings)
16 siblings, 0 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (7 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 08/15] OpenSSL: don't use direct access to the internal of DSA logout
@ 2017-02-17 22:00 ` logout
2017-02-21 21:30 ` Steffan Karger
2017-02-22 16:07 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 10/15] OpenSSL: don't use direct access to the internal of EVP_MD_CTX logout
` (7 subsequent siblings)
16 siblings, 2 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 10/15] OpenSSL: don't use direct access to the internal of EVP_MD_CTX
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (8 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX logout
@ 2017-02-17 22:00 ` logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 11/15] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX logout
` (6 subsequent siblings)
16 siblings, 0 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 11/15] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (9 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 10/15] OpenSSL: don't use direct access to the internal of EVP_MD_CTX logout
@ 2017-02-17 22:00 ` logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 12/15] OpenSSL: don't use direct access to the internal of HMAC_CTX logout
` (5 subsequent siblings)
16 siblings, 0 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 12/15] OpenSSL: don't use direct access to the internal of HMAC_CTX
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (10 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 11/15] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX logout
@ 2017-02-17 22:00 ` logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 13/15] OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1 logout
` (4 subsequent siblings)
16 siblings, 0 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 13/15] OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (11 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 12/15] OpenSSL: don't use direct access to the internal of HMAC_CTX logout
@ 2017-02-17 22:00 ` logout
2017-03-02 20:39 ` Steffan Karger
2017-03-05 12:21 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 14/15] OpenSSL: check for the SSL reason, not the full error logout
` (3 subsequent siblings)
16 siblings, 2 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 14/15] OpenSSL: check for the SSL reason, not the full error
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (12 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 13/15] OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1 logout
@ 2017-02-17 22:00 ` logout
2017-02-19 12:36 ` Steffan Karger
2017-02-19 17:52 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 15/15] OpenSSL: constify getbio() parameters logout
` (2 subsequent siblings)
16 siblings, 2 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
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 <logout@...260...>
---
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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v1 15/15] OpenSSL: constify getbio() parameters
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (13 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 14/15] OpenSSL: check for the SSL reason, not the full error logout
@ 2017-02-17 22:00 ` logout
2017-02-19 12:03 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Steffan Karger
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 " Emmanuel Deloget
16 siblings, 0 replies; 92+ messages in thread
From: logout @ 2017-02-17 22:00 UTC (permalink / raw)
To: openvpn-devel
From: Emmanuel Deloget <logout@...260...>
Although it is required by BIO_new() to have a non-const object,
this is merely an OpenSSL interface accident. Newer versions of
OpenSSL (i.e. OpenSSL 1.1) have are a bit better w.r.t. constification
and changed this.
As a result, we can safely constify the BIO_METHOD parameter of getbio()
(yet we still need to un-const the value when feeding it to BIO_new()
for the sake of compatibility).
Signed-off-by: Emmanuel Deloget <logout@...260...>
---
src/openvpn/ssl_openssl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 2ff3e12b93d6f829e4b27aefc2622d52e41ce589..46942c225d72e42760cbb9fae577c87aee553508 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1389,10 +1389,10 @@ bio_debug_oc(const char *mode, BIO *bio)
* through "memory BIOs".
*/
static BIO *
-getbio(BIO_METHOD *type, const char *desc)
+getbio(const BIO_METHOD *type, const char *desc)
{
BIO *ret;
- ret = BIO_new(type);
+ ret = BIO_new((BIO_METHOD *)type);
if (!ret)
{
crypto_msg(M_FATAL, "Error creating %s BIO", desc);
--
2.7.4
^ permalink raw reply related [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (14 preceding siblings ...)
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 15/15] OpenSSL: constify getbio() parameters logout
@ 2017-02-19 12:03 ` Steffan Karger
2017-02-19 14:58 ` David Sommerseth
` (2 more replies)
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 " Emmanuel Deloget
16 siblings, 3 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-19 12:03 UTC (permalink / raw)
To: openvpn-devel
Hi Emmanuel,
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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
Thank you very much. You approach looks good to me, and quite closely
matches what I had in mind for when I would find the time to tackle
this. (Which might have taken me a while, so really happy to see these
patches!)
As discussed in other threads, we do want to support building on RHEL6,
which is why we would prefer to be compatible with (patched) OpenSSL
0.9.8. I haven't tested anything yet, but looking at the patches this
might very well just work, or otherwise just needs some minor tweaking.
Also very good that this is split up into small and independently
reviewable patches. I'll start review soon.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 14/15] OpenSSL: check for the SSL reason, not the full error
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 14/15] OpenSSL: check for the SSL reason, not the full error logout
@ 2017-02-19 12:36 ` Steffan Karger
2017-02-19 17:52 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-19 12:36 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> 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
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-19 12:03 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Steffan Karger
@ 2017-02-19 14:58 ` David Sommerseth
2017-02-19 15:09 ` Steffan Karger
2017-02-19 15:01 ` Emmanuel Deloget
2017-02-19 17:49 ` Gert Doering
2 siblings, 1 reply; 92+ messages in thread
From: David Sommerseth @ 2017-02-19 14:58 UTC (permalink / raw)
To: Steffan Karger <steffan@
[-- Attachment #1.1: Type: text/plain, Size: 644 bytes --]
On 19/02/17 13:03, Steffan Karger wrote:
> As discussed in other threads, we do want to support building on RHEL6,
> which is why we would prefer to be compatible with (patched) OpenSSL
> 0.9.8. I haven't tested anything yet, but looking at the patches this
> might very well just work, or otherwise just needs some minor tweaking.
RHEL6 ships with OpenSSL 1.0.1e. We don't need anything older for git
master, and I would even argue release/2.4.
RHEL5 (which goes EOL by end of next month) ships with OpenSSL 0.9.8e.
So I vote for ditching 0.9.8e now.
--
kind regards,
David Sommerseth
OpenVPN Technologies, Inc
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-19 12:03 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Steffan Karger
2017-02-19 14:58 ` David Sommerseth
@ 2017-02-19 15:01 ` Emmanuel Deloget
2017-02-19 17:49 ` Gert Doering
2 siblings, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-19 15:01 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
Hello,
On Sun, Feb 19, 2017 at 1:03 PM, Steffan Karger <steffan@...1856...> wrote:
>
> Hi Emmanuel,
>
> Thank you very much. You approach looks good to me, and quite closely
> matches what I had in mind for when I would find the time to tackle
> this. (Which might have taken me a while, so really happy to see these
> patches!)
>
Thanks Steffan,
> As discussed in other threads, we do want to support building on RHEL6,
> which is why we would prefer to be compatible with (patched) OpenSSL
> 0.9.8. I haven't tested anything yet, but looking at the patches this
> might very well just work, or otherwise just needs some minor tweaking.
I haven't tested compilation with 0.9.8 but unless some massive
changes in the interface occured, this should not be a problem. I'd do
that at the beginning of next week.
> Also very good that this is split up into small and independently
> reviewable patches. I'll start review soon.
>
> -Steffan
For the record, most of the patches deal with changing how the code
access to one selected OpenSSL type. I hope it will ease review -- in
the sense that people who are accustomed to the code might be able to
see if something is missing.
BR,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-19 14:58 ` David Sommerseth
@ 2017-02-19 15:09 ` Steffan Karger
0 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-19 15:09 UTC (permalink / raw)
To: openvpn-devel
On 19-02-17 15:58, David Sommerseth wrote:
> On 19/02/17 13:03, Steffan Karger wrote:
>
>> As discussed in other threads, we do want to support building on RHEL6,
>> which is why we would prefer to be compatible with (patched) OpenSSL
>> 0.9.8. I haven't tested anything yet, but looking at the patches this
>> might very well just work, or otherwise just needs some minor tweaking.
>
> RHEL6 ships with OpenSSL 1.0.1e. We don't need anything older for git
> master, and I would even argue release/2.4.
>
> RHEL5 (which goes EOL by end of next month) ships with OpenSSL 0.9.8e.
> So I vote for ditching 0.9.8e now.
Oh, very good. I messed up the versions again...
The other big long-term-support distro, SLES, does still ship and
support 0.9.8 in SELS11 until 2019 (2022 for extended support), but can
be updated to 1.0.1.
As far as I'm concerned, that is enough reason to only support OpenSSL
1.0.1+ for OpenVPN 2.4 (and newer).
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-19 12:03 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Steffan Karger
2017-02-19 14:58 ` David Sommerseth
2017-02-19 15:01 ` Emmanuel Deloget
@ 2017-02-19 17:49 ` Gert Doering
2017-02-20 11:45 ` Emmanuel Deloget
2 siblings, 1 reply; 92+ messages in thread
From: Gert Doering @ 2017-02-19 17:49 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 1142 bytes --]
Hi,
On Sun, Feb 19, 2017 at 01:03:45PM +0100, Steffan Karger wrote:
> Thank you very much. You approach looks good to me, and quite closely
> matches what I had in mind for when I would find the time to tackle
> this. (Which might have taken me a while, so really happy to see these
> patches!)
[..]
> Also very good that this is split up into small and independently
> reviewable patches. I'll start review soon.
While Steffan is our resident expert on nasty crypto libraries, I just
want to echo the sentiment - having these "chunks" tackle one API function
at a time, they are easily testable, and in case something explodes, it's
much easier to bisect to find the problematic one.
Now back to being a commit slave for Steffan's ACKs :-) (I do not know
the APIs well enough to properly comment on the changes, I can only run
tests...)
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: check for the SSL reason, not the full error
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 14/15] OpenSSL: check for the SSL reason, not the full error logout
2017-02-19 12:36 ` Steffan Karger
@ 2017-02-19 17:52 ` Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-02-19 17:52 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
Your patch has been applied to the master and release/2.4 branch.
2.3 does not have this code, as far as I could see, so doesn't get
the patch.
I can't reach sf.net right now (git.code.sf.net gives me "connection
refused"), so only pushed to github and gitlab.
commit 6ddc43d1bf9b3ea3ee5db8c50d56a98fe4db4c97 (master)
commit c4c359736e3ab7f06a21f1eab09e6fd4cf2bef2f (release/2.4)
Author: Emmanuel Deloget
Date: Fri Feb 17 23:00:53 2017 +0100
OpenSSL: check for the SSL reason, not the full error
Signed-off-by: Emmanuel Deloget <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <0e0d4a67192b563cd07d3f06685f85e34c304142.1487368114.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14087.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-19 17:49 ` Gert Doering
@ 2017-02-20 11:45 ` Emmanuel Deloget
2017-02-20 12:29 ` Christian Hesse
2017-02-20 12:37 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Gert Doering
0 siblings, 2 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 11:45 UTC (permalink / raw)
To: Gert Doering <gert@; +Cc: openvpn-devel
Hello,
On Sun, Feb 19, 2017 at 6:49 PM, Gert Doering <gert@...1296...> wrote:
> Hi,
>
> On Sun, Feb 19, 2017 at 01:03:45PM +0100, Steffan Karger wrote:
>> Thank you very much. You approach looks good to me, and quite closely
>> matches what I had in mind for when I would find the time to tackle
>> this. (Which might have taken me a while, so really happy to see these
>> patches!)
> [..]
>> Also very good that this is split up into small and independently
>> reviewable patches. I'll start review soon.
>
> While Steffan is our resident expert on nasty crypto libraries, I just
> want to echo the sentiment - having these "chunks" tackle one API function
> at a time, they are easily testable, and in case something explodes, it's
> much easier to bisect to find the problematic one.
>
> Now back to being a commit slave for Steffan's ACKs :-) (I do not know
> the APIs well enough to properly comment on the changes, I can only run
> tests...)
I resumed the work this morning. So far the results are :
* 0.9.8zh --> EVP_PKEY_id() is not defined. I'm adding this to
openssl_compat.h and will provide a v2 patch with the change. Once
added, OpenVPN compiled successfully and was able to connect to my
/2.3 server.
* 1.0.0t --> compile OK, connect OK
* 1.0.1u --> compile OK, connect OK
* 1.0.2.k --> compile OK, connect OK
* 1.1.0-git --> compile OK, failure to connect. I'm currently
investigating this issue. I'll provide a patch as soon as I fix this
(this is a bit ironic ; I may have forgotten something somewhere...).
I don't have much time to test with other OpenSSL versions but I guess
you have the infrastructure that will help.
> gert
Best regards,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 11:45 ` Emmanuel Deloget
@ 2017-02-20 12:29 ` Christian Hesse
2017-02-20 13:33 ` Emmanuel Deloget
2017-02-20 12:37 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Gert Doering
1 sibling, 1 reply; 92+ messages in thread
From: Christian Hesse @ 2017-02-20 12:29 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 2270 bytes --]
Emmanuel Deloget <logout@...260...> on Mon, 2017/02/20 12:45:
> Hello,
>
> On Sun, Feb 19, 2017 at 6:49 PM, Gert Doering <gert@...1296...> wrote:
> > Hi,
> >
> > On Sun, Feb 19, 2017 at 01:03:45PM +0100, Steffan Karger wrote:
> >> Thank you very much. You approach looks good to me, and quite closely
> >> matches what I had in mind for when I would find the time to tackle
> >> this. (Which might have taken me a while, so really happy to see these
> >> patches!)
> > [..]
> >> Also very good that this is split up into small and independently
> >> reviewable patches. I'll start review soon.
> >
> > While Steffan is our resident expert on nasty crypto libraries, I just
> > want to echo the sentiment - having these "chunks" tackle one API function
> > at a time, they are easily testable, and in case something explodes, it's
> > much easier to bisect to find the problematic one.
> >
> > Now back to being a commit slave for Steffan's ACKs :-) (I do not know
> > the APIs well enough to properly comment on the changes, I can only run
> > tests...)
>
> I resumed the work this morning. So far the results are :
>
> * 0.9.8zh --> EVP_PKEY_id() is not defined. I'm adding this to
> openssl_compat.h and will provide a v2 patch with the change. Once
> added, OpenVPN compiled successfully and was able to connect to my
> /2.3 server.
>
> * 1.0.0t --> compile OK, connect OK
>
> * 1.0.1u --> compile OK, connect OK
>
> * 1.0.2.k --> compile OK, connect OK
>
> * 1.1.0-git --> compile OK, failure to connect. I'm currently
> investigating this issue. I'll provide a patch as soon as I fix this
> (this is a bit ironic ; I may have forgotten something somewhere...).
That matches my findings. Built against openssl 1.1.0e (Arch Linux package
openssl 1.1.0.e-1 [0]) the build itself succeeds, but 'make check' reports
lots of cipher failures.
Are your patches available from a public git repository?
[0] https://www.archlinux.org/packages/staging/x86_64/openssl/
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 11:45 ` Emmanuel Deloget
2017-02-20 12:29 ` Christian Hesse
@ 2017-02-20 12:37 ` Gert Doering
2017-02-20 13:38 ` Emmanuel Deloget
1 sibling, 1 reply; 92+ messages in thread
From: Gert Doering @ 2017-02-20 12:37 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 1503 bytes --]
Hi,
On Mon, Feb 20, 2017 at 12:45:24PM +0100, Emmanuel Deloget wrote:
> * 0.9.8zh --> EVP_PKEY_id() is not defined. I'm adding this to
> openssl_compat.h and will provide a v2 patch with the change. Once
> added, OpenVPN compiled successfully and was able to connect to my
> /2.3 server.
If possible, please do only resend the commit that got changed, not all
of it (easier to keep track when Steffan starts sending reviews).
> * 1.0.0t --> compile OK, connect OK
>
> * 1.0.1u --> compile OK, connect OK
>
> * 1.0.2.k --> compile OK, connect OK
Great :-)
> * 1.1.0-git --> compile OK, failure to connect. I'm currently
> investigating this issue. I'll provide a patch as soon as I fix this
> (this is a bit ironic ; I may have forgotten something somewhere...).
Interesting. Anything useful in openvpn's logs?
> I don't have much time to test with other OpenSSL versions but I guess
> you have the infrastructure that will help.
Well, *I* do not have specific "test across various OpenSSL versions"
infrastructure, but compiling across our buildbot zoo gives us quite a
bit of coverage... and I assume Steffan has more coverage on SSL library
versions.
thanks for your work!
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 12:29 ` Christian Hesse
@ 2017-02-20 13:33 ` Emmanuel Deloget
2017-02-20 13:53 ` Emmanuel Deloget
0 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 13:33 UTC (permalink / raw)
To: Christian Hesse <list@; +Cc: openvpn-devel
Hi Christian,
On Mon, Feb 20, 2017 at 1:29 PM, Christian Hesse <list@...1798...> wrote:
> That matches my findings. Built against openssl 1.1.0e (Arch Linux package
> openssl 1.1.0.e-1 [0]) the build itself succeeds, but 'make check' reports
> lots of cipher failures.
>
> Are your patches available from a public git repository?
I will make my patches available on github ASAP.
Best regards
-- Emmanuel Deloget
On Mon, Feb 20, 2017 at 1:29 PM, Christian Hesse <list@...1798...> wrote:
> Emmanuel Deloget <logout@...260...> on Mon, 2017/02/20 12:45:
>> Hello,
>>
>> On Sun, Feb 19, 2017 at 6:49 PM, Gert Doering <gert@...1296...> wrote:
>> > Hi,
>> >
>> > On Sun, Feb 19, 2017 at 01:03:45PM +0100, Steffan Karger wrote:
>> >> Thank you very much. You approach looks good to me, and quite closely
>> >> matches what I had in mind for when I would find the time to tackle
>> >> this. (Which might have taken me a while, so really happy to see these
>> >> patches!)
>> > [..]
>> >> Also very good that this is split up into small and independently
>> >> reviewable patches. I'll start review soon.
>> >
>> > While Steffan is our resident expert on nasty crypto libraries, I just
>> > want to echo the sentiment - having these "chunks" tackle one API function
>> > at a time, they are easily testable, and in case something explodes, it's
>> > much easier to bisect to find the problematic one.
>> >
>> > Now back to being a commit slave for Steffan's ACKs :-) (I do not know
>> > the APIs well enough to properly comment on the changes, I can only run
>> > tests...)
>>
>> I resumed the work this morning. So far the results are :
>>
>> * 0.9.8zh --> EVP_PKEY_id() is not defined. I'm adding this to
>> openssl_compat.h and will provide a v2 patch with the change. Once
>> added, OpenVPN compiled successfully and was able to connect to my
>> /2.3 server.
>>
>> * 1.0.0t --> compile OK, connect OK
>>
>> * 1.0.1u --> compile OK, connect OK
>>
>> * 1.0.2.k --> compile OK, connect OK
>>
>> * 1.1.0-git --> compile OK, failure to connect. I'm currently
>> investigating this issue. I'll provide a patch as soon as I fix this
>> (this is a bit ironic ; I may have forgotten something somewhere...).
>
> That matches my findings. Built against openssl 1.1.0e (Arch Linux package
> openssl 1.1.0.e-1 [0]) the build itself succeeds, but 'make check' reports
> lots of cipher failures.
>
> Are your patches available from a public git repository?
>
> [0] https://www.archlinux.org/packages/staging/x86_64/openssl/
> --
> main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
> "CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
> putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 12:37 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Gert Doering
@ 2017-02-20 13:38 ` Emmanuel Deloget
0 siblings, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 13:38 UTC (permalink / raw)
To: Gert Doering <gert@; +Cc: openvpn-devel
Hi,
On Mon, Feb 20, 2017 at 1:37 PM, Gert Doering <gert@...1296...> wrote:
>
> Interesting. Anything useful in openvpn's logs?
>
Mon Feb 20 11:57:56 2017 us=371715 OpenSSL: error:0607B083:digital
envelope routines:EVP_CipherInit_ex:no cipher set
Mon Feb 20 11:57:56 2017 us=371746 EVP cipher init #2
I found the culprit: OpenSSL's EVP_CipherInit() changed way too much
for a 3 lines function. Prior to v1.1, the code did a check on cipher
parameter and cleared the EVP context only if cipher was not null. In
1.1, it clears the context unconditionnaly. Having to cope with
changes in the interface is not that fun, having to cope with behavior
changes is even worse :)
I'm producing an additional commit to work around that change (the
proposed change does not depend on the OpenSSL version).
>> I don't have much time to test with other OpenSSL versions but I guess
>> you have the infrastructure that will help.
>
> Well, *I* do not have specific "test across various OpenSSL versions"
> infrastructure, but compiling across our buildbot zoo gives us quite a
> bit of coverage... and I assume Steffan has more coverage on SSL library
> versions.
>
> thanks for your work!
>
> gert
Well, thanks to everyone involved -- all of you have been really kind
with me (for now :))
Best regards,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 13:33 ` Emmanuel Deloget
@ 2017-02-20 13:53 ` Emmanuel Deloget
2017-02-20 14:52 ` Emmanuel Deloget
0 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 13:53 UTC (permalink / raw)
To: Christian Hesse <list@; +Cc: openvpn-devel
Hi again,
On Mon, Feb 20, 2017 at 2:33 PM, Emmanuel Deloget <logout@...260...> wrote:
> Hi Christian,
>
> On Mon, Feb 20, 2017 at 1:29 PM, Christian Hesse <list@...1798...> wrote:
>> That matches my findings. Built against openssl 1.1.0e (Arch Linux package
>> openssl 1.1.0.e-1 [0]) the build itself succeeds, but 'make check' reports
>> lots of cipher failures.
>>
>> Are your patches available from a public git repository?
>
> I will make my patches available on github ASAP.
I did as fast as I could, here they are:
https://github.com/emmanuel-deloget/openvpn/commits/openvpn-1.1
I post the PATCH V2 in a few minutes
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v2 00/15] Add support for OpenSSL 1.1.x
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
` (15 preceding siblings ...)
2017-02-19 12:03 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Steffan Karger
@ 2017-02-20 14:32 ` Emmanuel Deloget
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 15/15] OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit() Emmanuel Deloget
16 siblings, 2 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 14:32 UTC (permalink / raw)
To: openvpn-devel
This (limited) series replaces a few patches on the v1 series, namely:
* "OpenSSL: don't use direct access to the internal of EVP_PKEY"
This version replaces the previous version and adds function
EVP_PKEY_id() which is present in 1.0.0 and later but not in
0.9.8.
* "OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()"
This version has been compile-tested with the following versions:
* 0.9.8zh
* 1.0.0t
* 1.0.1u
* 1.0.2k
* 1.1.0-git
Each compilation test was followed by a connection test to an OpenVPN
server (v2.3). So far, everything seems to work.
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: constify getbio() parameters
OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()
configure.ac | 38 +++
src/openvpn/crypto.c | 8 +-
src/openvpn/crypto_backend.h | 42 +++
src/openvpn/crypto_mbedtls.c | 40 +++
src/openvpn/crypto_openssl.c | 54 +++-
src/openvpn/httpdigest.c | 78 ++---
src/openvpn/misc.c | 14 +-
src/openvpn/ntlm.c | 12 +-
src/openvpn/openssl_compat.h | 623 +++++++++++++++++++++++++++++++++++++++
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, 963 insertions(+), 146 deletions(-)
create mode 100644 src/openvpn/openssl_compat.h
--
2.7.4
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v2 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 " Emmanuel Deloget
@ 2017-02-20 14:32 ` Emmanuel Deloget
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 15/15] OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit() Emmanuel Deloget
1 sibling, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 14:32 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
configure.ac | 3 +++
src/openvpn/openssl_compat.h | 42 ++++++++++++++++++++++++++++++++++++++++++
src/openvpn/ssl_openssl.c | 6 +++---
3 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index c41db3e..8d99eb3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -906,6 +906,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
X509_STORE_get0_objects \
X509_OBJECT_free \
X509_OBJECT_get_type \
+ EVP_PKEY_id \
+ 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 6a89b91..72ed7ac 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -134,6 +134,48 @@ 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_ID)
+/**
+ * Get the PKEY type
+ *
+ * @param pkey Public key object
+ * @return The key type
+ */
+static inline int
+EVP_PKEY_id(const EVP_PKEY *pkey)
+{
+ return pkey ? pkey->type : EVP_PKEY_NONE;
+}
+#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 b683961..dbeb868 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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [RFC PATCH v2 15/15] OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 " Emmanuel Deloget
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
@ 2017-02-20 14:32 ` Emmanuel Deloget
2017-03-02 20:44 ` Steffan Karger
2017-03-05 12:21 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 2 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 14:32 UTC (permalink / raw)
To: openvpn-devel
The behavior of EVP_CipherInit() changed in OpenSSL 1.1 -- instead
of clearing the context when the cipher parameter was !NULL, it now
clears the context unconditionnaly. As a result, subsequent calls
to the function with additional information now fails.
The bulk work is done by EVP_CipherInit_ex() which has been part of the
OpenSSL interface since the dawn of time (0.9.8 already has it). Thus,
the change allows us to get the old behavior back instead of relying
on dirty tricks.
Signed-off-by: Emmanuel Deloget <logout@...260...>
---
src/openvpn/crypto_openssl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 23de175..2bca88b 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -683,7 +683,7 @@ cipher_ctx_init(EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len,
crypto_msg(M_FATAL, "EVP set key size");
}
#endif
- if (!EVP_CipherInit(ctx, NULL, key, NULL, enc))
+ if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, enc))
{
crypto_msg(M_FATAL, "EVP cipher init #2");
}
@@ -736,7 +736,7 @@ cipher_ctx_get_cipher_kt(const cipher_ctx_t *ctx)
int
cipher_ctx_reset(EVP_CIPHER_CTX *ctx, uint8_t *iv_buf)
{
- return EVP_CipherInit(ctx, NULL, NULL, iv_buf, -1);
+ return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv_buf, -1);
}
int
--
2.7.4
^ permalink raw reply related [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 13:53 ` Emmanuel Deloget
@ 2017-02-20 14:52 ` Emmanuel Deloget
2017-02-20 15:02 ` Christian Hesse
0 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-20 14:52 UTC (permalink / raw)
To: Christian Hesse <list@; +Cc: openvpn-devel
On Mon, Feb 20, 2017 at 2:53 PM, Emmanuel Deloget <logout@...260...> wrote:
> Hi again,
>
> On Mon, Feb 20, 2017 at 2:33 PM, Emmanuel Deloget <logout@...260...> wrote:
>> Hi Christian,
>>
>> On Mon, Feb 20, 2017 at 1:29 PM, Christian Hesse <list@...1798...> wrote:
>>> That matches my findings. Built against openssl 1.1.0e (Arch Linux package
>>> openssl 1.1.0.e-1 [0]) the build itself succeeds, but 'make check' reports
>>> lots of cipher failures.
>>>
>>> Are your patches available from a public git repository?
>>
>> I will make my patches available on github ASAP.
>
> I did as fast as I could, here they are:
>
> https://github.com/emmanuel-deloget/openvpn/commits/openvpn-1.1
BTW, sorry for the branch name. I believe my fingers got stuck to a
limited number of characters. This should have been openssl-1.1 but
it's not too late to change it :)
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 14:52 ` Emmanuel Deloget
@ 2017-02-20 15:02 ` Christian Hesse
2017-02-20 15:08 ` Christian Hesse
0 siblings, 1 reply; 92+ messages in thread
From: Christian Hesse @ 2017-02-20 15:02 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 1301 bytes --]
Emmanuel Deloget <logout@...260...> on Mon, 2017/02/20 15:52:
> On Mon, Feb 20, 2017 at 2:53 PM, Emmanuel Deloget <logout@...260...> wrote:
> > Hi again,
> >
> > On Mon, Feb 20, 2017 at 2:33 PM, Emmanuel Deloget <logout@...260...>
> > wrote:
> >> Hi Christian,
> >>
> >> On Mon, Feb 20, 2017 at 1:29 PM, Christian Hesse <list@...1798...> wrote:
> >>> That matches my findings. Built against openssl 1.1.0e (Arch Linux
> >>> package openssl 1.1.0.e-1 [0]) the build itself succeeds, but 'make
> >>> check' reports lots of cipher failures.
> >>>
> >>> Are your patches available from a public git repository?
> >>
> >> I will make my patches available on github ASAP.
> >
> > I did as fast as I could, here they are:
> >
> > https://github.com/emmanuel-deloget/openvpn/commits/openvpn-1.1
>
> BTW, sorry for the branch name. I believe my fingers got stuck to a
> limited number of characters. This should have been openssl-1.1 but
> it's not too late to change it :)
Ah, I checked out the wrong branch. :-p
Redoing my test...
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x
2017-02-20 15:02 ` Christian Hesse
@ 2017-02-20 15:08 ` Christian Hesse
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 " Emmanuel Deloget
` (2 more replies)
0 siblings, 3 replies; 92+ messages in thread
From: Christian Hesse @ 2017-02-20 15:08 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 1529 bytes --]
Christian Hesse <list@...1798...> on Mon, 2017/02/20 16:02:
> Emmanuel Deloget <logout@...260...> on Mon, 2017/02/20 15:52:
> > On Mon, Feb 20, 2017 at 2:53 PM, Emmanuel Deloget <logout@...260...>
> > wrote:
> > > Hi again,
> > >
> > > On Mon, Feb 20, 2017 at 2:33 PM, Emmanuel Deloget <logout@...260...>
> > > wrote:
> > >> Hi Christian,
> > >>
> > >> On Mon, Feb 20, 2017 at 1:29 PM, Christian Hesse <list@...1798...>
> > >> wrote:
> > >>> That matches my findings. Built against openssl 1.1.0e (Arch Linux
> > >>> package openssl 1.1.0.e-1 [0]) the build itself succeeds, but 'make
> > >>> check' reports lots of cipher failures.
> > >>>
> > >>> Are your patches available from a public git repository?
> > >>
> > >> I will make my patches available on github ASAP.
> > >
> > > I did as fast as I could, here they are:
> > >
> > > https://github.com/emmanuel-deloget/openvpn/commits/openvpn-1.1
> >
> > BTW, sorry for the branch name. I believe my fingers got stuck to a
> > limited number of characters. This should have been openssl-1.1 but
> > it's not too late to change it :)
>
> Ah, I checked out the wrong branch. :-p
>
> Redoing my test...
That one looks good! Build and tested against ArchLinux package
openssl 1.1.0e.
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX logout
@ 2017-02-21 21:30 ` Steffan Karger
2017-02-22 14:47 ` Christian Hesse
2017-02-22 16:07 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 1 reply; 92+ messages in thread
From: Steffan Karger @ 2017-02-21 21:30 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> 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;
> }
>
ACK. Changes look good and tested against OpenSSL 0.9.8, 1.0.0, 1.0.1
and 1.0.2.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX
2017-02-21 21:30 ` Steffan Karger
@ 2017-02-22 14:47 ` Christian Hesse
2017-02-22 15:34 ` Steffan Karger
0 siblings, 1 reply; 92+ messages in thread
From: Christian Hesse @ 2017-02-22 14:47 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 505 bytes --]
Steffan Karger <steffan@...1856...> on Tue, 2017/02/21 22:30:
> ACK. Changes look good and tested against OpenSSL 0.9.8, 1.0.0, 1.0.1
> and 1.0.2.
You answered to a patch in the middle of a series. Does this ACK apply to the
complete series or just this patch?
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX
2017-02-22 14:47 ` Christian Hesse
@ 2017-02-22 15:34 ` Steffan Karger
0 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-22 15:34 UTC (permalink / raw)
To: Christian Hesse <list@; +Cc: openvpn-devel
On 22 February 2017 at 15:47, Christian Hesse <list@...1798...> wrote:
> Steffan Karger <steffan@...1856...> on Tue, 2017/02/21 22:30:
>> ACK. Changes look good and tested against OpenSSL 0.9.8, 1.0.0, 1.0.1
>> and 1.0.2.
>
> You answered to a patch in the middle of a series. Does this ACK apply to the
> complete series or just this patch?
Just this one. Not much brains left last night, so I only reviewed
this rather simple and independent patch out of the series :)
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of X509_STORE_CTX
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX logout
2017-02-21 21:30 ` Steffan Karger
@ 2017-02-22 16:07 ` Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-02-22 16:07 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
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 <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <11477a0a3cf636572c84e0110a6f1b726bc60c2c.1487368114.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14085.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX logout
@ 2017-02-22 20:27 ` Steffan Karger
2017-02-22 21:13 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-23 8:03 ` [Openvpn-devel] [RFC PATCH v1 01/15] " Gert Doering
2 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-22 20:27 UTC (permalink / raw)
To: openvpn-devel
[-- Attachment #1.1: Type: text/plain, Size: 6396 bytes --]
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> 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. <sales@...515...>
> + * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@...1435...>
> + *
> + * 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
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 02/15] OpenSSL: don't use direct access to the internal of X509_STORE
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 02/15] OpenSSL: don't use direct access to the internal of X509_STORE logout
@ 2017-02-22 20:36 ` Steffan Karger
2017-02-22 21:14 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-22 20:36 UTC (permalink / raw)
To: openvpn-devel
[-- Attachment #1.1: Type: text/plain, Size: 4285 bytes --]
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> 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
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct access to the internal of X509_OBJECT
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct access to the internal of X509_OBJECT logout
@ 2017-02-22 20:50 ` Steffan Karger
2017-02-22 21:14 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-22 20:50 UTC (permalink / raw)
To: openvpn-devel
[-- Attachment #1.1: Type: text/plain, Size: 3658 bytes --]
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> 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
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of SSL_CTX
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX logout
2017-02-22 20:27 ` Steffan Karger
@ 2017-02-22 21:13 ` Gert Doering
2017-02-23 8:03 ` [Openvpn-devel] [RFC PATCH v1 01/15] " Gert Doering
2 siblings, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-02-22 21:13 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
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 <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <a77187a66affdba318ef70e0e218b69cdad509d1.1487368114.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14088.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of X509_STORE
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 02/15] OpenSSL: don't use direct access to the internal of X509_STORE logout
2017-02-22 20:36 ` Steffan Karger
@ 2017-02-22 21:14 ` Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-02-22 21:14 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
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 <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <8e6d66e3a9a40abb3d7c99c48ba59bad1037d0ef.1487368114.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14076.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of X509_OBJECT
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct access to the internal of X509_OBJECT logout
2017-02-22 20:50 ` Steffan Karger
@ 2017-02-22 21:14 ` Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-02-22 21:14 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
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 <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <c849c9778d2b2faa4eb4d31367b37d993da5eb85.1487368114.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14080.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD logout
@ 2017-02-22 22:13 ` Steffan Karger
2017-02-23 9:39 ` Emmanuel Deloget
0 siblings, 1 reply; 92+ messages in thread
From: Steffan Karger @ 2017-02-22 22:13 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> 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
I think it would be nicer to more closely mimic the 1.1 behaviour in
RSA_meth_{new,free}(), and copy the name string in new() and free it
again in free(). That could prevent a future use-after-free that would
occur for pre-1.1.0, but not 1.1.0+:
char *mystring = calloc(50, 1);
RSA_METHOD *meth = RSA_meth_new(mystring, 0);
free(mystring);
meth.smoke();
^^ might cause problems
(Hint: use string_alloc(x, NULL).)
> +
> +#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;
> }
This change still works, but he follow up change in this method in 07/15
causes problems:
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;
}
Casting away const on the object returned by RSA_get_method() is a
smell, but it really fails because RSA_set_method(rsa, NULL) calls
rsa->meth->finish(), which is implemented by this very function. That
means that RSA_meth_free() will perform a double free on meth->name.
I briefly looked into a fix, but didn't immediately see a nice solution
here. At least the RSA_set_method(rsa, RSA_get_default_method())
doesn't work either, because you'll end up with rsa_finish() and
RSA_set_method() calling each other infinitely...
(Noting this here, because the fix for 07 might cause changes to this
patch too.)
> @@ -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();
>
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX logout
2017-02-22 20:27 ` Steffan Karger
2017-02-22 21:13 ` [Openvpn-devel] [PATCH applied] " Gert Doering
@ 2017-02-23 8:03 ` Gert Doering
2017-02-23 9:23 ` Gert Doering
2 siblings, 1 reply; 92+ messages in thread
From: Gert Doering @ 2017-02-23 8:03 UTC (permalink / raw)
To: logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 1944 bytes --]
Good morning,
On Fri, Feb 17, 2017 at 11:00:40PM +0100, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> configure.ac | 9 ++++++
> src/openvpn/openssl_compat.h | 74 ++++++++++++++++++++++++++++++++++++++++++++
This patch brings two problems outside the "OpenSSL functionality"
part.
- openssl_compat.h is not included in the built tarballs, so mingw builds
fail (and "builds for anyone building from tarballs" would break) ->
findable by running "make distcheck"
- configure.ac does something to CentOS 6 / RHEL 6 which makes configure
explode:
...
checking for linux/if_tun.h... yes
checking tap-windows.h usability... no
checking tap-windows.h presence... no
checking for tap-windows.h... no
checking whether TUNSETPERSIST is declared... yes
checking for setcon in -lselinux... yes
checking for pam_start in -lpam... yes
checking for PKCS11_HELPER... no
./configure: line 21440: syntax error near unexpected token `fi'
./configure: line 21440: `fi'
The first one is easily fixed, but I do not know how to tackle the
second one - no access to a CentOS6/RHEL6 box, and not enough autoconf
clue to see this right away. Patch *looks* good... most likely just a
stray "\" where none should be, or so...
Please :-)
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX
2017-02-23 8:03 ` [Openvpn-devel] [RFC PATCH v1 01/15] " Gert Doering
@ 2017-02-23 9:23 ` Gert Doering
2017-02-23 9:31 ` Emmanuel Deloget
2017-02-23 10:35 ` [Openvpn-devel] [PATCH] OpenSSL: 1.1 fallout - fix configure on old autoconf Steffan Karger
0 siblings, 2 replies; 92+ messages in thread
From: Gert Doering @ 2017-02-23 9:23 UTC (permalink / raw)
To: logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 1275 bytes --]
Hi,
On Thu, Feb 23, 2017 at 09:03:47AM +0100, Gert Doering wrote:
> This patch brings two problems outside the "OpenSSL functionality"
> part.
>
> - openssl_compat.h is not included in the built tarballs, so mingw builds
> fail (and "builds for anyone building from tarballs" would break) ->
> findable by running "make distcheck"
This has been fixed & pushed (so we can build windows snapshots again).
> - configure.ac does something to CentOS 6 / RHEL 6 which makes configure
> explode:
>
> ...
> checking for linux/if_tun.h... yes
> checking tap-windows.h usability... no
> checking tap-windows.h presence... no
> checking for tap-windows.h... no
> checking whether TUNSETPERSIST is declared... yes
> checking for setcon in -lselinux... yes
> checking for pam_start in -lpam... yes
> checking for PKCS11_HELPER... no
> ./configure: line 21440: syntax error near unexpected token `fi'
> ./configure: line 21440: `fi'
This still needs investigation.
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX
2017-02-23 9:23 ` Gert Doering
@ 2017-02-23 9:31 ` Emmanuel Deloget
2017-02-23 9:36 ` Steffan Karger
2017-02-23 10:35 ` [Openvpn-devel] [PATCH] OpenSSL: 1.1 fallout - fix configure on old autoconf Steffan Karger
1 sibling, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-23 9:31 UTC (permalink / raw)
To: Gert Doering <gert@; +Cc: openvpn-devel
Hello,
On Thu, Feb 23, 2017 at 10:23 AM, Gert Doering <gert@...1296...> wrote:
> Hi,
>
> On Thu, Feb 23, 2017 at 09:03:47AM +0100, Gert Doering wrote:
>> This patch brings two problems outside the "OpenSSL functionality"
>> part.
>>
>> - openssl_compat.h is not included in the built tarballs, so mingw builds
>> fail (and "builds for anyone building from tarballs" would break) ->
>> findable by running "make distcheck"
>
> This has been fixed & pushed (so we can build windows snapshots again).
>
>> - configure.ac does something to CentOS 6 / RHEL 6 which makes configure
>> explode:
>>
>> ...
>> checking for linux/if_tun.h... yes
>> checking tap-windows.h usability... no
>> checking tap-windows.h presence... no
>> checking for tap-windows.h... no
>> checking whether TUNSETPERSIST is declared... yes
>> checking for setcon in -lselinux... yes
>> checking for pam_start in -lpam... yes
>> checking for PKCS11_HELPER... no
>> ./configure: line 21440: syntax error near unexpected token `fi'
>> ./configure: line 21440: `fi'
>
> This still needs investigation.
I'm taking the time to install a CentOS 6 on a VM. I'll test this asap.
Best regards,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX
2017-02-23 9:31 ` Emmanuel Deloget
@ 2017-02-23 9:36 ` Steffan Karger
0 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-02-23 9:36 UTC (permalink / raw)
To: openvpn-devel
On 23-02-17 10:31, Emmanuel Deloget wrote:
>>> - configure.ac does something to CentOS 6 / RHEL 6 which makes configure
>>> explode:
>>>
>>> ...
>>> checking for linux/if_tun.h... yes
>>> checking tap-windows.h usability... no
>>> checking tap-windows.h presence... no
>>> checking for tap-windows.h... no
>>> checking whether TUNSETPERSIST is declared... yes
>>> checking for setcon in -lselinux... yes
>>> checking for pam_start in -lpam... yes
>>> checking for PKCS11_HELPER... no
>>> ./configure: line 21440: syntax error near unexpected token `fi'
>>> ./configure: line 21440: `fi'
>>
>> This still needs investigation.
>
> I'm taking the time to install a CentOS 6 on a VM. I'll test this asap.
I have a fix ready, but am busy with testing it on various platforms.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-02-22 22:13 ` Steffan Karger
@ 2017-02-23 9:39 ` Emmanuel Deloget
0 siblings, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-23 9:39 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
Hi Steffan,
On Wed, Feb 22, 2017 at 11:13 PM, Steffan Karger <steffan@...1856...> wrote:
> Hi,
>
> On 17-02-17 23:00, logout@...260... wrote:
>> From: Emmanuel Deloget <logout@...260...>
>>
>> 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 <logout@...260...>
>> ---
>> 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
>
> I think it would be nicer to more closely mimic the 1.1 behaviour in
> RSA_meth_{new,free}(), and copy the name string in new() and free it
> again in free(). That could prevent a future use-after-free that would
> occur for pre-1.1.0, but not 1.1.0+:
I failed to see that when I implemented my solution. I'll give a look
as soon as possible.
> char *mystring = calloc(50, 1);
> RSA_METHOD *meth = RSA_meth_new(mystring, 0);
> free(mystring);
>
> meth.smoke();
> ^^ might cause problems
>
> (Hint: use string_alloc(x, NULL).)
>
>> +
>> +#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;
>> }
>
> This change still works, but he follow up change in this method in 07/15
> causes problems:
>
> 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;
> }
>
> Casting away const on the object returned by RSA_get_method() is a
> smell, but it really fails because RSA_set_method(rsa, NULL) calls
> rsa->meth->finish(), which is implemented by this very function. That
> means that RSA_meth_free() will perform a double free on meth->name.
>
> I briefly looked into a fix, but didn't immediately see a nice solution
> here. At least the RSA_set_method(rsa, RSA_get_default_method())
> doesn't work either, because you'll end up with rsa_finish() and
> RSA_set_method() calling each other infinitely...
Ouch. I failed to see that as well. Sorry :)
I'll try to find a better solution to this issue as well.
> (Noting this here, because the fix for 07 might cause changes to this
> patch too.)
>
>> @@ -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();
>>
>
> -Steffan
>
Best regards,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH] OpenSSL: 1.1 fallout - fix configure on old autoconf
2017-02-23 9:23 ` Gert Doering
2017-02-23 9:31 ` Emmanuel Deloget
@ 2017-02-23 10:35 ` Steffan Karger
2017-02-23 10:59 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 1 reply; 92+ messages in thread
From: Steffan Karger @ 2017-02-23 10:35 UTC (permalink / raw)
To: openvpn-devel
Older versions of autoconf generate an empty "else fi" block for empty
fields in an AC_CHECK_FUNCS() macro. This breaks on e.g. RHEL6.
Signed-off-by: Steffan Karger <steffan.karger@...1435...>
---
configure.ac | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 546a7d6..79ef52d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -912,9 +912,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
X509_STORE_get0_objects \
X509_OBJECT_free \
X509_OBJECT_get_type \
- ],
- ,
- []
+ ]
)
CFLAGS="${saved_CFLAGS}"
--
2.7.4
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: 1.1 fallout - fix configure on old autoconf
2017-02-23 10:35 ` [Openvpn-devel] [PATCH] OpenSSL: 1.1 fallout - fix configure on old autoconf Steffan Karger
@ 2017-02-23 10:59 ` Gert Doering
0 siblings, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-02-23 10:59 UTC (permalink / raw)
To: Steffan Karger <steffan.karger@; +Cc: openvpn-devel
ACK, thanks.
Your patch has been applied to the master and release/2.4 branch.
commit 07372a0fdeb3638204d197d0614f776a0eb73ab9 (master)
commit b97a5cc044dc6db3f0e1f9f06a6f5da522f0a33a (release/2.4)
Author: Steffan Karger
Date: Thu Feb 23 11:35:38 2017 +0100
OpenSSL: 1.1 fallout - fix configure on old autoconf
Signed-off-by: Steffan Karger <steffan.karger@...1435...>
Acked-by: Gert Doering <gert@...1296...>
Message-Id: <1487846138-22231-1-git-send-email-steffan.karger@...1435...>
URL: http://www.mail-archive.com/search?l=mid&q=1487846138-22231-1-git-send-email-steffan.karger@...1435...
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH v3 00/15] Add support for OpenSSL 1.1.x
2017-02-20 15:08 ` Christian Hesse
@ 2017-02-23 14:35 ` Emmanuel Deloget
2017-02-23 20:57 ` Christian Hesse
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD Emmanuel Deloget
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 07/15] OpenSSL: don't use direct access to the internal of RSA Emmanuel Deloget
2 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-23 14:35 UTC (permalink / raw)
To: openvpn-devel
This is v3 of the remaining patches for the "Add support for OpenSSL
1.1.x" series. This series is partial: only the modified patches are
sent to the ML -- the other have not changed. The stats are a bit off
so I don't include them in this mail.
They have been generated after a rebase from the master tree. Individual
commits can be viewed at
https://github.com/emmanuel-deloget/openvpn/commits/openssl-1.1-v3
(This time, the branch name is correct :))
Changes v2 --> v3:
* RSA_METHOD (04/15): rsa_meth->name is now a dup of the name parameter;
it's freed in RSA_meth_free().
* RSA (07/15): calling RSA_set_method() in rsa_finish() is both a Bad
Idea and not required so it has been removed.
Changes v1 --> v2:
* EVP_PKEY (06/15): add missing function EVP_PKEY_id() for 0.9.8.
* replace patch 15/15 with a new patch to use EVP_CipherInit_ex()
instead of EVP_CipherInit() when a full init is not needed.
Emmanuel Deloget (15):
[commited] OpenSSL: don't use direct access to the internal of SSL_CTX
[commited] OpenSSL: don't use direct access to the internal of X509_STORE
[commited] 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
[commited] 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: constify getbio() parameters
OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()
--
2.7.4
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH v3 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-02-20 15:08 ` Christian Hesse
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 " Emmanuel Deloget
@ 2017-02-23 14:35 ` Emmanuel Deloget
2017-03-02 20:01 ` Steffan Karger
2017-03-05 9:53 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 07/15] OpenSSL: don't use direct access to the internal of RSA Emmanuel Deloget
2 siblings, 2 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-23 14:35 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
configure.ac | 9 ++
src/openvpn/openssl_compat.h | 190 +++++++++++++++++++++++++++++++++++++++++++
src/openvpn/ssl_openssl.c | 22 ++---
3 files changed, 210 insertions(+), 11 deletions(-)
diff --git a/configure.ac b/configure.ac
index 0c55d78327597a0690fa9625e06adb8b055852b1..2406ad8d6bf10f202d3fc1e9b971bc8ec135bd4f 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..e98e8dffc5773d73684398ae28215d4fdccac3c4 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,192 @@ 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 = string_alloc(name, NULL);
+ 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)
+{
+ if (meth)
+ {
+ free(meth->name);
+ 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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH v3 07/15] OpenSSL: don't use direct access to the internal of RSA
2017-02-20 15:08 ` Christian Hesse
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 " Emmanuel Deloget
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD Emmanuel Deloget
@ 2017-02-23 14:35 ` Emmanuel Deloget
2 siblings, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-02-23 14:35 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
configure.ac | 3 ++
src/openvpn/openssl_compat.h | 84 ++++++++++++++++++++++++++++++++++++++++++++
src/openvpn/ssl_openssl.c | 24 ++++++++-----
3 files changed, 103 insertions(+), 8 deletions(-)
diff --git a/configure.ac b/configure.ac
index 089aa89459803234f847579d393c2be6e17d958a..e9942e38f5675c8bcfcc30f5e5c30731a08abba2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -909,6 +909,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
EVP_PKEY_id \
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 9d99c72920bd9ab450809e6d3247db846d4bd564..0f7b0bb799d2c5e506b6372aa9cc023e8cbf3b29 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -176,6 +176,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..25935b45dcac6dfc5c9d034fe14e7b29ec1cc1c3 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -978,8 +978,8 @@ 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;
+ const RSA_METHOD *meth = RSA_get_method(rsa);
+ RSA_meth_free((RSA_METHOD *)meth);
return 1;
}
@@ -1078,8 +1078,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 +1683,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
^ permalink raw reply related [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH v3 00/15] Add support for OpenSSL 1.1.x
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 " Emmanuel Deloget
@ 2017-02-23 20:57 ` Christian Hesse
2017-02-24 12:13 ` Christian Hesse
0 siblings, 1 reply; 92+ messages in thread
From: Christian Hesse @ 2017-02-23 20:57 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 2635 bytes --]
Emmanuel Deloget <logout@...260...> on Thu, 2017/02/23 15:35:
> This is v3 of the remaining patches for the "Add support for OpenSSL
> 1.1.x" series. This series is partial: only the modified patches are
> sent to the ML -- the other have not changed. The stats are a bit off
> so I don't include them in this mail.
>
> They have been generated after a rebase from the master tree. Individual
> commits can be viewed at
>
> https://github.com/emmanuel-deloget/openvpn/commits/openssl-1.1-v3
>
> (This time, the branch name is correct :))
>
> Changes v2 --> v3:
>
> * RSA_METHOD (04/15): rsa_meth->name is now a dup of the name parameter;
> it's freed in RSA_meth_free().
>
> * RSA (07/15): calling RSA_set_method() in rsa_finish() is both a Bad
> Idea and not required so it has been removed.
>
> Changes v1 --> v2:
>
> * EVP_PKEY (06/15): add missing function EVP_PKEY_id() for 0.9.8.
>
> * replace patch 15/15 with a new patch to use EVP_CipherInit_ex()
> instead of EVP_CipherInit() when a full init is not needed.
>
>
> Emmanuel Deloget (15):
> [commited] OpenSSL: don't use direct access to the internal of SSL_CTX
> [commited] OpenSSL: don't use direct access to the internal of X509_STORE
> [commited] 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
> [commited] 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: constify getbio() parameters
> OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()
Built v3 against openssl 1.0.2k without issues, tests succeed and two
instanced successfully established vpn connection (with server version 2.3.12
and 2.4.0).
Built against openssl 1.1.0e without issues, tests succeed. Did not test with
real world connectivity, though.
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH v3 00/15] Add support for OpenSSL 1.1.x
2017-02-23 20:57 ` Christian Hesse
@ 2017-02-24 12:13 ` Christian Hesse
2017-02-24 21:49 ` Christian Hesse
0 siblings, 1 reply; 92+ messages in thread
From: Christian Hesse @ 2017-02-24 12:13 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 608 bytes --]
Christian Hesse <list@...1798...> on Thu, 2017/02/23 21:57:
> Built v3 against openssl 1.0.2k without issues, tests succeed and two
> instanced successfully established vpn connection (with server version
> 2.3.12 and 2.4.0).
Just tested a server instance with ancient client (version 2.1.4). Works as
well.
I will try to restart another server instance later.
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH v3 00/15] Add support for OpenSSL 1.1.x
2017-02-24 12:13 ` Christian Hesse
@ 2017-02-24 21:49 ` Christian Hesse
0 siblings, 0 replies; 92+ messages in thread
From: Christian Hesse @ 2017-02-24 21:49 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 896 bytes --]
Christian Hesse <list@...1798...> on Fri, 2017/02/24 13:13:
> Christian Hesse <list@...1798...> on Thu, 2017/02/23 21:57:
> > Built v3 against openssl 1.0.2k without issues, tests succeed and two
> > instanced successfully established vpn connection (with server version
> > 2.3.12 and 2.4.0).
>
> Just tested a server instance with ancient client (version 2.1.4). Works as
> well.
>
> I will try to restart another server instance later.
Just restarted the server. Here is the current client connect statistic:
1 2.3.8
4 2.3.12
6 2.3.13
7 2.3.11
18 2.3.14
70 2.4.0
So looks good for now. ;)
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH v3 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD Emmanuel Deloget
@ 2017-03-02 20:01 ` Steffan Karger
2017-03-05 9:53 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-03-02 20:01 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 23-02-17 15:35, Emmanuel Deloget wrote:
> 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 <logout@...260...>
> ---
> configure.ac | 9 ++
> src/openvpn/openssl_compat.h | 190 +++++++++++++++++++++++++++++++++++++++++++
> src/openvpn/ssl_openssl.c | 22 ++---
> 3 files changed, 210 insertions(+), 11 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 0c55d78327597a0690fa9625e06adb8b055852b1..2406ad8d6bf10f202d3fc1e9b971bc8ec135bd4f 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..e98e8dffc5773d73684398ae28215d4fdccac3c4 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,192 @@ 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 = string_alloc(name, NULL);
> + 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)
> +{
> + if (meth)
> + {
> + free(meth->name);
> + 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();
>
This looks good to me now, ACK. Thanks for following up.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509 logout
@ 2017-03-02 20:36 ` Steffan Karger
2017-03-02 21:26 ` Gert Doering
0 siblings, 1 reply; 92+ messages in thread
From: Steffan Karger @ 2017-03-02 20:36 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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).
The nsCertType x509 extension is very old, and replaced by keyUsage and
extendedKeyUsage (supported by OpenVPN via --remote-cert-tls or
--remote-cert-ku and --remote-cert-eku).
Changing this to the stricter API without warning will probably break
some people's setups with certs that do have nsCertType set, but not
keyUsage and/or extendedKeyUsage, while leaving them guessing why.
So, what I propose instead is:
* remove all the nsCertType code (except the option in add_option())
* update the help strings and man page to indicate that --ns-cert-type
is no longer supported and --remote-cert-tls should be used instead
* in add_option(), if the option is enabled in a config file, act as if
--remote-cert-tls was specified correspondingly, and print a clear
warning that --ns-cert-type is no longer supported and stricter checks
are enabled instead.
> 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 <logout@...260...>
> ---
> 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;
>
If we are to use X509_check_purpose() (see my comments above), we should
not cast away const here, but rather remove the const qualified from the
peer_cert argument. Casting away const is bad, in particular if a
comment on the function states that it really can't take a const
argument because it changes the object.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 13/15] OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 13/15] OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1 logout
@ 2017-03-02 20:39 ` Steffan Karger
2017-03-05 12:21 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-03-02 20:39 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 17-02-17 23:00, logout@...260... wrote:
> From: Emmanuel Deloget <logout@...260...>
>
> 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 <logout@...260...>
> ---
> 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
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v2 15/15] OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 15/15] OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit() Emmanuel Deloget
@ 2017-03-02 20:44 ` Steffan Karger
2017-03-05 12:21 ` [Openvpn-devel] [PATCH applied] " Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-03-02 20:44 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 20-02-17 15:32, Emmanuel Deloget wrote:
> The behavior of EVP_CipherInit() changed in OpenSSL 1.1 -- instead
> of clearing the context when the cipher parameter was !NULL, it now
> clears the context unconditionnaly. As a result, subsequent calls
> to the function with additional information now fails.
>
> The bulk work is done by EVP_CipherInit_ex() which has been part of the
> OpenSSL interface since the dawn of time (0.9.8 already has it). Thus,
> the change allows us to get the old behavior back instead of relying
> on dirty tricks.
>
> Signed-off-by: Emmanuel Deloget <logout@...260...>
> ---
> src/openvpn/crypto_openssl.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
> index 23de175..2bca88b 100644
> --- a/src/openvpn/crypto_openssl.c
> +++ b/src/openvpn/crypto_openssl.c
> @@ -683,7 +683,7 @@ cipher_ctx_init(EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len,
> crypto_msg(M_FATAL, "EVP set key size");
> }
> #endif
> - if (!EVP_CipherInit(ctx, NULL, key, NULL, enc))
> + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, enc))
> {
> crypto_msg(M_FATAL, "EVP cipher init #2");
> }
> @@ -736,7 +736,7 @@ cipher_ctx_get_cipher_kt(const cipher_ctx_t *ctx)
> int
> cipher_ctx_reset(EVP_CIPHER_CTX *ctx, uint8_t *iv_buf)
> {
> - return EVP_CipherInit(ctx, NULL, NULL, iv_buf, -1);
> + return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv_buf, -1);
> }
>
> int
>
ACK
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-03-02 20:36 ` Steffan Karger
@ 2017-03-02 21:26 ` Gert Doering
2017-03-04 15:13 ` Steffan Karger
0 siblings, 1 reply; 92+ messages in thread
From: Gert Doering @ 2017-03-02 21:26 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 1249 bytes --]
Hi,
On Thu, Mar 02, 2017 at 09:36:32PM +0100, Steffan Karger wrote:
> So, what I propose instead is:
> * remove all the nsCertType code (except the option in add_option())
> * update the help strings and man page to indicate that --ns-cert-type
> is no longer supported and --remote-cert-tls should be used instead
> * in add_option(), if the option is enabled in a config file, act as if
> --remote-cert-tls was specified correspondingly, and print a clear
> warning that --ns-cert-type is no longer supported and stricter checks
> are enabled instead.
Mmmmh. Is there a way to get the old behaviour with OpenSSL 1.1?
We decided that we do want 1.1 compatibility in release/2.4, but what
you propose might break people's working config when upgrading from 2.4.1
to 2.4.2 - bad enough if we make mistakes, but if there is an alternative
to consciously changing cert validation behaviour in the middle of a
release train, we should look again...
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-03-02 21:26 ` Gert Doering
@ 2017-03-04 15:13 ` Steffan Karger
2017-03-04 16:22 ` Emmanuel Deloget
2017-03-04 22:38 ` David Sommerseth
0 siblings, 2 replies; 92+ messages in thread
From: Steffan Karger @ 2017-03-04 15:13 UTC (permalink / raw)
To: Gert Doering <gert@; +Cc: openvpn-devel
Hi,
On 02-03-17 22:26, Gert Doering wrote:
> On Thu, Mar 02, 2017 at 09:36:32PM +0100, Steffan Karger wrote:
>> So, what I propose instead is:
>> * remove all the nsCertType code (except the option in add_option())
>> * update the help strings and man page to indicate that --ns-cert-type
>> is no longer supported and --remote-cert-tls should be used instead
>> * in add_option(), if the option is enabled in a config file, act as if
>> --remote-cert-tls was specified correspondingly, and print a clear
>> warning that --ns-cert-type is no longer supported and stricter checks
>> are enabled instead.
>
> Mmmmh. Is there a way to get the old behaviour with OpenSSL 1.1?
>
> We decided that we do want 1.1 compatibility in release/2.4, but what
> you propose might break people's working config when upgrading from 2.4.1
> to 2.4.2 - bad enough if we make mistakes, but if there is an alternative
> to consciously changing cert validation behaviour in the middle of a
> release train, we should look again...
So I looked again, and there really seems to be no way to get the old
behaviour with OpenSSL 1.1. However, the exact behaviour of
X509_check_purpose() is not as strict as I initially thought. The
current patch basically adds the following checks:
* if the cert has key usage set, it must be correct
* if the cert has extended key usage set, it must be correct
* if the cert has the CA flag set, it must be done correctly
These are fairly low-risk. I'd expect quite some issues if we would
reject certs *without* (extended) key usage set, but if (e)ku is set,
this will most likely be done correctly. Or in other words, we might
reject weird certificates, but not proper certificates.
All in all, I think the original patch (after fixing const correctness)
is fine.
As a last resort, we could consider keeping the old code inside #if
OSSL_VER < 1.1.0 in release/2.4, but that might just create more
confusion...
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-03-04 15:13 ` Steffan Karger
@ 2017-03-04 16:22 ` Emmanuel Deloget
2017-03-04 22:38 ` David Sommerseth
1 sibling, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-03-04 16:22 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
Hello,
On Sat, Mar 4, 2017 at 4:13 PM, Steffan Karger <steffan@...1856...> wrote:
> Hi,
>
> On 02-03-17 22:26, Gert Doering wrote:
>> On Thu, Mar 02, 2017 at 09:36:32PM +0100, Steffan Karger wrote:
>>> So, what I propose instead is:
>>> * remove all the nsCertType code (except the option in add_option())
>>> * update the help strings and man page to indicate that --ns-cert-type
>>> is no longer supported and --remote-cert-tls should be used instead
>>> * in add_option(), if the option is enabled in a config file, act as if
>>> --remote-cert-tls was specified correspondingly, and print a clear
>>> warning that --ns-cert-type is no longer supported and stricter checks
>>> are enabled instead.
>>
>> Mmmmh. Is there a way to get the old behaviour with OpenSSL 1.1?
>>
>> We decided that we do want 1.1 compatibility in release/2.4, but what
>> you propose might break people's working config when upgrading from 2.4.1
>> to 2.4.2 - bad enough if we make mistakes, but if there is an alternative
>> to consciously changing cert validation behaviour in the middle of a
>> release train, we should look again...
>
> So I looked again, and there really seems to be no way to get the old
> behaviour with OpenSSL 1.1. However, the exact behaviour of
> X509_check_purpose() is not as strict as I initially thought. The
> current patch basically adds the following checks:
> * if the cert has key usage set, it must be correct
> * if the cert has extended key usage set, it must be correct
> * if the cert has the CA flag set, it must be done correctly
When I coded this part, I searched for a long time before resorting to
using this function. It's true that the library does more check, yet I
didn't find any way to not do them, as the necessary members are not
available through getters.
However, my understanding is that OpenSSL does a full, correct check,
and that certificates that does not pass this check are probably not
correct - or at least, they hide some weird issues that could make
them a bit dangerous to use. Of course, I might be wrong. The
certificates I tested were valid w.r.t. this new code and I'm now sure
how I can generate certificates that do not pass.
> These are fairly low-risk. I'd expect quite some issues if we would
> reject certs *without* (extended) key usage set, but if (e)ku is set,
> this will most likely be done correctly. Or in other words, we might
> reject weird certificates, but not proper certificates.
Yet, rejecting certificates might pose problems in the organisations
that use them, and they should be warned by (at least) and
intermediate release that their certificates going to be rejected. So,
after a bit of thinking I would do :
1/ check the certificate with X209_check_purpose()
2/ on failure, for OpenSSL < 1.1.0, warn the user that the
certificates are probably not fully correct, and do the old check. If
it pass, continue
> All in all, I think the original patch (after fixing const correctness)
> is fine.
>
> As a last resort, we could consider keeping the old code inside #if
> OSSL_VER < 1.1.0 in release/2.4, but that might just create more
> confusion...
Unfortunately, I am overbooked right now and I'm not sure I'll be able
to do this fast (say, in less than 2 weeks). I'd be grateful of
someone else does it.
> -Steffan
Best regards,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-03-04 15:13 ` Steffan Karger
2017-03-04 16:22 ` Emmanuel Deloget
@ 2017-03-04 22:38 ` David Sommerseth
2017-03-27 15:49 ` Emmanuel Deloget
1 sibling, 1 reply; 92+ messages in thread
From: David Sommerseth @ 2017-03-04 22:38 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
[-- Attachment #1.1: Type: text/plain, Size: 2380 bytes --]
On 04/03/17 16:13, Steffan Karger wrote:
> As a last resort, we could consider keeping the old code inside #if
> OSSL_VER < 1.1.0 in release/2.4, but that might just create more
> confusion...
Just a very quick thought here ... I do dislike different behaviours
depending on which OpenSSL version being used. But given that this
feature is already deprecated and even removed in OpenSSL-1.1, I think
that gives us some options.
I agree with Gert that breaking --ns-cert-type isn't good at all.
However, consider when people upgrade from OpenSSL v1.0 to v1.1 - that
is most commonly when there is major distro update. It is not something
which happens "mid-term", as OpenSSL is quite commonly used by lots of
base system packages these days.
Regardless of OpenSSL version, I agree to loudly deprecate
--ns-cert-type, through documentation, --help and log files.
But I think we need to carry the existing behaviour for --ns-cert-type
when built against OpenSSL v1.0. And we can solve through some
compatibility wrapper when built against OpenSSL v1.1 - with even louder
warnings in the logs that this may break apart.
The reason I say this, is that Fedora users are quite unhappy that
--tls-remote disappeared in v2.4.0 *despite* a more recent
NetworkManager-OpenVPN plug-in actually making it easy to switch to
--verify-x509-name. But IIRC, this wasn't backported to all older and
still valid Fedora releases, so that caused additional pain for the
users. And don't get me started with the attempt of temporarily build
against mbed TLS instead of OpenSSL in Fedora Rawhide (which will become
Fedora 26), as that broke lots of configurations with CA certificates
using RSA 1024 bit keys. All this results in very little OpenVPN 2.4
adaptation among many Fedora users.
I can barely imagine what happens if we break --ns-cert-type on top of
that ... Just that the behaviour might change for a minority of users in
when Fedora 26 hits the streets, with OpenSSL v1.1, might hit us bad
again. But at least with OpenSSL v1.1, many users knows that things
will be somewhat different too. And we can actually point at OpenSSL
and explain why it broke, which is not something we could do with
the --tls-remote option.
Just my way too many cents ..... :)
--
kind regards,
David Sommerseth
OpenVPN Technologies, Inc
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD Emmanuel Deloget
2017-03-02 20:01 ` Steffan Karger
@ 2017-03-05 9:53 ` Gert Doering
2017-03-05 10:29 ` Steffan Karger
1 sibling, 1 reply; 92+ messages in thread
From: Gert Doering @ 2017-03-05 9:53 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
Your patch (v3) has been applied to the master and release/2.4 branch.
Small side note: I assume that RSA_meth_new() can fail and return NULL
in OpenSSL 1.1? Because for 1.0, the "check_malloc_return(rsa_meth)" call
isn't necessary, as ALLOC_OBJ_CLEAR() would call ALLOC_OBJ() and that
already checks... (mentioning this here in case someone wonders and goes
to the list archives).
commit 09776c5b52df13121504e07894a26d5cd1883317 (master)
commit 44bac2926d6b445a7773a24bb7c295b54f4be35e (release/2.4)
Author: Emmanuel Deloget
Date: Thu Feb 23 15:35:56 2017 +0100
OpenSSL: don't use direct access to the internal of RSA_METHOD
Signed-off-by: Emmanuel Deloget <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <79d89580db6fd92c059dabc4f5f4d83b72bb9d3d.1487859361.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14175.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-03-05 9:53 ` [Openvpn-devel] [PATCH applied] " Gert Doering
@ 2017-03-05 10:29 ` Steffan Karger
2017-03-05 12:08 ` Emmanuel Deloget
0 siblings, 1 reply; 92+ messages in thread
From: Steffan Karger @ 2017-03-05 10:29 UTC (permalink / raw)
To: openvpn-devel
On 05-03-17 10:53, Gert Doering wrote:
> Small side note: I assume that RSA_meth_new() can fail and return NULL
> in OpenSSL 1.1? Because for 1.0, the "check_malloc_return(rsa_meth)" call
> isn't necessary, as ALLOC_OBJ_CLEAR() would call ALLOC_OBJ() and that
> already checks... (mentioning this here in case someone wonders and goes
> to the list archives).
For the archives: yes, RSA_meth_new() indeed returns NULL if it's
internal malloc() call fails.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-03-05 10:29 ` Steffan Karger
@ 2017-03-05 12:08 ` Emmanuel Deloget
2017-03-05 12:26 ` Gert Doering
0 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-03-05 12:08 UTC (permalink / raw)
To: Steffan Karger <steffan@; +Cc: openvpn-devel
Hi,
On Sun, Mar 5, 2017 at 11:29 AM, Steffan Karger <steffan@...1856...> wrote:
>
> On 05-03-17 10:53, Gert Doering wrote:
>> Small side note: I assume that RSA_meth_new() can fail and return NULL
>> in OpenSSL 1.1? Because for 1.0, the "check_malloc_return(rsa_meth)" call
>> isn't necessary, as ALLOC_OBJ_CLEAR() would call ALLOC_OBJ() and that
>> already checks... (mentioning this here in case someone wonders and goes
>> to the list archives).
>
> For the archives: yes, RSA_meth_new() indeed returns NULL if it's
> internal malloc() call fails.
Yes, indeed. And that's the reason why I have a check_malloc_return()
here. I'm perfectly conscious that for OpenSSL < 1.1 we're checking
the pointer twice but on the other hand I would have missed the check
with OpenSSL 1.1. A solution would have been to use a direct
malloc()/calloc() call instead of ALLOC_OBJ_CLEAR() in the
compatibility code, but that would have looked weird. Another solution
would have been to encapsulate RSA_meth_new() but I don't think that
would have been a good idea (yet, I might be wrong on that one). So I
did this choice -- I don't like it much either but I cannot think of a
better solution.
> -Steffan
Best regards,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 13/15] OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1 logout
2017-03-02 20:39 ` Steffan Karger
@ 2017-03-05 12:21 ` Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-03-05 12:21 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
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 <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <9ce17efda7b1ed100e73554b1916c0bfa687d9d1.1487368114.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14089.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH applied] Re: OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 15/15] OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit() Emmanuel Deloget
2017-03-02 20:44 ` Steffan Karger
@ 2017-03-05 12:21 ` Gert Doering
1 sibling, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-03-05 12:21 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
Your patch has been applied to the master and release/2.4 branch.
commit 8d00afae88b626c9cf14170a943b33a7ed378070 (master)
commit 0fa3df510c10820d00b8f5c77a8730f90189f30d (release/2.4)
Author: Emmanuel Deloget
Date: Mon Feb 20 15:32:34 2017 +0100
OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit()
Signed-off-by: Emmanuel Deloget <logout@...260...>
Acked-by: Steffan Karger <steffan.karger@...1435...>
Message-Id: <2faff7647151d7fe362c1c5db9f97e520444d09b.1487600539.git.logout@...260...>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14120.html
Signed-off-by: Gert Doering <gert@...1296...>
--
kind regards,
Gert Doering
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH applied] Re: OpenSSL: don't use direct access to the internal of RSA_METHOD
2017-03-05 12:08 ` Emmanuel Deloget
@ 2017-03-05 12:26 ` Gert Doering
0 siblings, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-03-05 12:26 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 683 bytes --]
Hi,
On Sun, Mar 05, 2017 at 01:08:09PM +0100, Emmanuel Deloget wrote:
> I don't like it much either but I cannot think of a better solution.
I haven't said that I don't *like* it :-) - I came across it when
doing a "post commit sanity check" and assumed that there are good
reasons. Just wanted to clarify this, in case someone else looks
at the call chain and wonders.
All is well :-)
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-03-04 22:38 ` David Sommerseth
@ 2017-03-27 15:49 ` Emmanuel Deloget
2017-03-28 8:43 ` Emmanuel Deloget
2017-05-18 20:49 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
0 siblings, 2 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-03-27 15:49 UTC (permalink / raw)
To: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 3699 bytes --]
Hi everyone,
I got some time to try to fix all that stuff.
First,
On Sat, Mar 4, 2017 at 11:38 PM, David Sommerseth <
openvpn@...2080...> wrote:
> On 04/03/17 16:13, Steffan Karger wrote:
> > As a last resort, we could consider keeping the old code inside #if
> > OSSL_VER < 1.1.0 in release/2.4, but that might just create more
> > confusion...
>
I think I found a solution -- see later in the email.
I had a closer look to the corresponding code to see what are the
differences between the old check and the new one -- and indeed,
the discrepancies might only happen if the tested certificate is
kind-of-weird. For exemple, a client certificate:
* has the client bit set
* has no key, or has a key but the key usage is neither for
signature nor for key agreement
* is not used to auth a client
If a user creates a Frankenstein certificate that look like this,
it might be a good idea to warn him that such certificate is very
likely to be refused in the near future (one can have a similar
reasonning about server certificates).
>
> Just a very quick thought here ... I do dislike different behaviours
> depending on which OpenSSL version being used. But given that this
> feature is already deprecated and even removed in OpenSSL-1.1, I think
> that gives us some options.
>
> I agree with Gert that breaking --ns-cert-type isn't good at all.
> However, consider when people upgrade from OpenSSL v1.0 to v1.1 - that
> is most commonly when there is major distro update. It is not something
> which happens "mid-term", as OpenSSL is quite commonly used by lots of
> base system packages these days.
>
> Regardless of OpenSSL version, I agree to loudly deprecate
> --ns-cert-type, through documentation, --help and log files.
>
> But I think we need to carry the existing behaviour for --ns-cert-type
> when built against OpenSSL v1.0. And we can solve through some
> compatibility wrapper when built against OpenSSL v1.1 - with even louder
> warnings in the logs that this may break apart.
>
Fortunately, I think I found a solution that would help
when using OpenSSL 1.1. Idealy, this should be a call
to X509_check_purpose(.., X509_PURPOSE_SSL_*_WEAK, ...)
but I don't think the OpenSSL developers will accept such
a change :)
It might be possible to use the X509_get_ext_d2i() call
like this:
void *ns = X509_get_ext_d2i(x, NID_netscape_cert_type,
NULL, NULL);
In this case, the obtained ns object contains the data
we're interested in:
* if it exists, then EXFLAG_NSCERT is set
* if not null, ns is of type ASN1_BIT_STRING, and this
type is not opaque (yep, sir).
So the code would look like:
ASN1_BIT_STRING *ns;
result_t result = FAILURE;
ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL);
if (ns)
{
if (ns->length > 0)
{
int flags = ns->data[0];
if (flags & NS_SSL_CLIENT)
{
result = SUCCESS;
}
}
ASN1_BIT_STRING_free(ns);
}
For the record, it's the code that is used within function
x509v3_cache_extensions() which builds the X509 flags we
are using so I'm failry confident it's the right thing to
do (but it's a bit convoluted and I don't like it much).
Good news: the same code should work with nearly all the
previous versions of OpenSSL.
> <snip>
>
>
> --
> kind regards,
>
> David Sommerseth
> OpenVPN Technologies, Inc
>
I'll post my new patches as soon as I get over every issues
that have been talked on the ML (is that even a valid
sentence?)
Best regards,
-- Emmanuel Deloget
[-- Attachment #2: Type: text/html, Size: 10654 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-03-27 15:49 ` Emmanuel Deloget
@ 2017-03-28 8:43 ` Emmanuel Deloget
2017-03-28 8:49 ` Gert Doering
2017-05-18 20:49 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
1 sibling, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-03-28 8:43 UTC (permalink / raw)
To: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 4164 bytes --]
Hi,
I'm not sure why but it seems this mail (that I send yesterday) never found
its way to the ML. So I re-send it.
Sorry for the inconvenience.
BR,
-- Emmanuel Deloget
On Mon, Mar 27, 2017 at 5:49 PM, Emmanuel Deloget <logout@...260...> wrote:
> Hi everyone,
>
> I got some time to try to fix all that stuff.
>
> First,
>
> On Sat, Mar 4, 2017 at 11:38 PM, David Sommerseth <openvpn@...2142...
> topphemmelig.net> wrote:
>
>> On 04/03/17 16:13, Steffan Karger wrote:
>> > As a last resort, we could consider keeping the old code inside #if
>> > OSSL_VER < 1.1.0 in release/2.4, but that might just create more
>> > confusion...
>>
>
>
> I think I found a solution -- see later in the email.
>
> I had a closer look to the corresponding code to see what are the
> differences between the old check and the new one -- and indeed,
> the discrepancies might only happen if the tested certificate is
> kind-of-weird. For exemple, a client certificate:
>
> * has the client bit set
> * has no key, or has a key but the key usage is neither for
> signature nor for key agreement
> * is not used to auth a client
>
> If a user creates a Frankenstein certificate that look like this,
> it might be a good idea to warn him that such certificate is very
> likely to be refused in the near future (one can have a similar
> reasonning about server certificates).
>
>
>
>>
>> Just a very quick thought here ... I do dislike different behaviours
>> depending on which OpenSSL version being used. But given that this
>> feature is already deprecated and even removed in OpenSSL-1.1, I think
>> that gives us some options.
>>
>> I agree with Gert that breaking --ns-cert-type isn't good at all.
>> However, consider when people upgrade from OpenSSL v1.0 to v1.1 - that
>> is most commonly when there is major distro update. It is not something
>> which happens "mid-term", as OpenSSL is quite commonly used by lots of
>> base system packages these days.
>>
>> Regardless of OpenSSL version, I agree to loudly deprecate
>> --ns-cert-type, through documentation, --help and log files.
>>
>> But I think we need to carry the existing behaviour for --ns-cert-type
>> when built against OpenSSL v1.0. And we can solve through some
>> compatibility wrapper when built against OpenSSL v1.1 - with even louder
>> warnings in the logs that this may break apart.
>>
>
>
> Fortunately, I think I found a solution that would help
> when using OpenSSL 1.1. Idealy, this should be a call
> to X509_check_purpose(.., X509_PURPOSE_SSL_*_WEAK, ...)
> but I don't think the OpenSSL developers will accept such
> a change :)
>
> It might be possible to use the X509_get_ext_d2i() call
> like this:
>
> void *ns = X509_get_ext_d2i(x, NID_netscape_cert_type,
> NULL, NULL);
>
> In this case, the obtained ns object contains the data
> we're interested in:
>
> * if it exists, then EXFLAG_NSCERT is set
> * if not null, ns is of type ASN1_BIT_STRING, and this
> type is not opaque (yep, sir).
>
> So the code would look like:
>
> ASN1_BIT_STRING *ns;
> result_t result = FAILURE;
> ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL);
> if (ns)
> {
> if (ns->length > 0)
> {
> int flags = ns->data[0];
> if (flags & NS_SSL_CLIENT)
> {
> result = SUCCESS;
> }
> }
> ASN1_BIT_STRING_free(ns);
> }
>
>
> For the record, it's the code that is used within function
> x509v3_cache_extensions() which builds the X509 flags we
> are using so I'm failry confident it's the right thing to
> do (but it's a bit convoluted and I don't like it much).
>
> Good news: the same code should work with nearly all the
> previous versions of OpenSSL.
>
>
>
>> <snip>
>>
>>
>> --
>> kind regards,
>>
>> David Sommerseth
>> OpenVPN Technologies, Inc
>>
>
>
> I'll post my new patches as soon as I get over every issues
> that have been talked on the ML (is that even a valid
> sentence?)
>
> Best regards,
>
> -- Emmanuel Deloget
>
[-- Attachment #2: Type: text/html, Size: 10574 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509
2017-03-28 8:43 ` Emmanuel Deloget
@ 2017-03-28 8:49 ` Gert Doering
0 siblings, 0 replies; 92+ messages in thread
From: Gert Doering @ 2017-03-28 8:49 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 629 bytes --]
Hi,
On Tue, Mar 28, 2017 at 10:43:54AM +0200, Emmanuel Deloget wrote:
> I'm not sure why but it seems this mail (that I send yesterday) never found
> its way to the ML. So I re-send it.
>
> Sorry for the inconvenience.
According to
https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14307.html
it arrived fine :-)
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] OpenSSL 1.1 patch set - status?
2017-03-27 15:49 ` Emmanuel Deloget
2017-03-28 8:43 ` Emmanuel Deloget
@ 2017-05-18 20:49 ` Gert Doering
2017-05-19 10:37 ` Emmanuel Deloget
1 sibling, 1 reply; 92+ messages in thread
From: Gert Doering @ 2017-05-18 20:49 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 845 bytes --]
Hi Emmanuel,
On Mon, Mar 27, 2017 at 05:49:48PM +0200, Emmanuel Deloget wrote:
> I'll post my new patches as soon as I get over every issues
> that have been talked on the ML (is that even a valid
> sentence?)
I'm wondering where this got stuck - are you waiting for us to move
forward (like, missing review of parts of the patch set), or are we
waiting for you, and you've been busy?
We didn't really follow up on this from our end since the CVEs and
2.4.2 got in the way - but I think now would be a good time to move
ahead with this...
thanks,
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] OpenSSL 1.1 patch set - status?
2017-05-18 20:49 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
@ 2017-05-19 10:37 ` Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
2017-05-19 11:41 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
0 siblings, 2 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:37 UTC (permalink / raw)
To: Gert Doering <gert@; +Cc: openvpn-devel
Hi Gert,
On Thu, May 18, 2017 at 10:49 PM, Gert Doering <gert@...1296...> wrote:
>
> Hi Emmanuel,
>
> On Mon, Mar 27, 2017 at 05:49:48PM +0200, Emmanuel Deloget wrote:
> > I'll post my new patches as soon as I get over every issues
> > that have been talked on the ML (is that even a valid
> > sentence?)
>
> I'm wondering where this got stuck - are you waiting for us to move
> forward (like, missing review of parts of the patch set), or are we
> waiting for you, and you've been busy?
Problem is that I'm working in a more-than-full-time manner on
way-too-many-other subjects :)
> We didn't really follow up on this from our end since the CVEs and
> 2.4.2 got in the way - but I think now would be a good time to move
> ahead with this...
I have a git tree out there that I have not fully tested yet. It
compiles OK with OpenSSL 0.9.8, 1.0.0, 1.0.1, 1.0.2 and 1.1.0 but I
haven't checked the behavior.
The main difference with the previous version of the patch is the way
the certificate purpose is checked.
A) we do a fairly full check of the purpose using
X509_check_purpose(). This check is harder that the previous version
B) if that fails, we check for the certificate purpose using a lighter
method which is strictly equivalent to what was done before (it uses
X509_get_ext_d2i() to fetch the certificate type from within the
certificate).
The branch is available for viewing on github at
https://github.com/emmanuel-deloget/openvpn/tree/openssl-1.1-v6.
The followup emails contains the 7 patches which are needed to finish the work.
BR,
-- Emmanuel Deloget
^ permalink raw reply [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509
2017-05-19 10:37 ` Emmanuel Deloget
@ 2017-05-19 10:38 ` Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 2/7] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
` (6 more replies)
2017-05-19 11:41 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
1 sibling, 7 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:38 UTC (permalink / raw)
To: openvpn-devel
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).
We double-check the certificate purpose using "direct access" to the
internal of the certificate object (of course, this is not a real
direct access, but we still fetch ASN1 strings within the X509 object
and we check the internal value of these strings). This allow us to
warn the user if there is a discrepancy between the X509_check_purpose()
return value and our internal, less strict check.
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 <logout@...260...>
---
configure.ac | 1 +
src/openvpn/openssl_compat.h | 15 ++++++++++
src/openvpn/ssl_openssl.c | 3 +-
src/openvpn/ssl_verify_openssl.c | 64 ++++++++++++++++++++++++++++++++++------
4 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 7d3fce5b..9d5e340b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -922,6 +922,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 92f014d5..29a7588c 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 645ccf51..a082c3cd 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1070,7 +1070,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 9b1533bc..4785f314 100644
--- a/src/openvpn/ssl_verify_openssl.c
+++ b/src/openvpn/ssl_verify_openssl.c
@@ -294,18 +294,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;
}
@@ -578,13 +580,57 @@ 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
+ */
+ result_t result = X509_check_purpose((X509 *)peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ?
+ SUCCESS : FAILURE;
+
+ /*
+ * old versions of OpenSSL allow us to make the less strict check we used to
+ * do. If this less strict check pass, warn user that this might not be the
+ * case when its distribution will update to OpenSSL 1.1
+ */
+ if (result == FAILURE)
+ {
+ ASN1_BIT_STRING *ns;
+ ns = X509_get_ext_d2i((X509 *)peer_cert, NID_netscape_cert_type, NULL, NULL);
+ result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_CLIENT)) ? SUCCESS : FAILURE;
+ if (result == SUCCESS)
+ {
+ msg(M_WARN, "X509: Certificate is a client certificate yet it's purpose "
+ "cannot be verified (check may fail in the future)");
+ }
+ }
+ return result;
}
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
+ */
+ result_t result = X509_check_purpose((X509 *)peer_cert, X509_PURPOSE_SSL_SERVER, 0) ?
+ SUCCESS : FAILURE;
+
+ /*
+ * old versions of OpenSSL allow us to make the less strict check we used to
+ * do. If this less strict check pass, warn user that this might not be the
+ * case when its distribution will update to OpenSSL 1.1
+ */
+ if (result == FAILURE)
+ {
+ ASN1_BIT_STRING *ns;
+ ns = X509_get_ext_d2i((X509 *)peer_cert, NID_netscape_cert_type, NULL, NULL);
+ result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_SERVER)) ? SUCCESS : FAILURE;
+ if (result == SUCCESS)
+ {
+ msg(M_WARN, "X509: Certificate is a server certificate yet it's purpose "
+ "cannot be verified (check may fail in the future)");
+ }
+ }
+ return result;
}
return FAILURE;
--
2.11.0
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH 2/7] OpenSSL: don't use direct access to the internal of EVP_PKEY
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
@ 2017-05-19 10:38 ` Emmanuel Deloget
2017-06-11 19:40 ` Steffan Karger
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 3/7] OpenSSL: don't use direct access to the internal of RSA Emmanuel Deloget
` (5 subsequent siblings)
6 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:38 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
configure.ac | 3 +++
src/openvpn/openssl_compat.h | 42 ++++++++++++++++++++++++++++++++++++++++++
src/openvpn/ssl_openssl.c | 6 +++---
3 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 9d5e340b..a92e8142 100644
--- a/configure.ac
+++ b/configure.ac
@@ -926,6 +926,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
X509_STORE_get0_objects \
X509_OBJECT_free \
X509_OBJECT_get_type \
+ EVP_PKEY_id \
+ 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 29a7588c..0d82cf25 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -134,6 +134,48 @@ 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_ID)
+/**
+ * Get the PKEY type
+ *
+ * @param pkey Public key object
+ * @return The key type
+ */
+static inline int
+EVP_PKEY_id(const EVP_PKEY *pkey)
+{
+ return pkey ? pkey->type : EVP_PKEY_NONE;
+}
+#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 a082c3cd..1c73641c 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1072,7 +1072,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);
@@ -1677,13 +1677,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.11.0
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH 3/7] OpenSSL: don't use direct access to the internal of RSA
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 2/7] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
@ 2017-05-19 10:38 ` Emmanuel Deloget
2017-06-11 20:09 ` Steffan Karger
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 4/7] OpenSSL: don't use direct access to the internal of DSA Emmanuel Deloget
` (4 subsequent siblings)
6 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:38 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
configure.ac | 3 ++
src/openvpn/openssl_compat.h | 84 ++++++++++++++++++++++++++++++++++++++++++++
src/openvpn/ssl_openssl.c | 24 ++++++++-----
3 files changed, 103 insertions(+), 8 deletions(-)
diff --git a/configure.ac b/configure.ac
index a92e8142..e4c053c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -929,6 +929,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
EVP_PKEY_id \
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 0d82cf25..29cd13a4 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -176,6 +176,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 1c73641c..48479c0d 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -975,8 +975,8 @@ 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;
+ const RSA_METHOD *meth = RSA_get_method(rsa);
+ RSA_meth_free((RSA_METHOD *)meth);
return 1;
}
@@ -1075,8 +1075,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;
@@ -1677,11 +1680,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.11.0
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH 4/7] OpenSSL: don't use direct access to the internal of DSA
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 2/7] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 3/7] OpenSSL: don't use direct access to the internal of RSA Emmanuel Deloget
@ 2017-05-19 10:38 ` Emmanuel Deloget
2017-06-11 20:11 ` Steffan Karger
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 5/7] OpenSSL: don't use direct access to the internal of EVP_MD_CTX Emmanuel Deloget
` (3 subsequent siblings)
6 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:38 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
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 e4c053c8..d2dc1ffd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -932,6 +932,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 29cd13a4..fdfc4a27 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -260,6 +260,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 48479c0d..242ab397 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1691,11 +1691,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.11.0
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH 5/7] OpenSSL: don't use direct access to the internal of EVP_MD_CTX
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
` (2 preceding siblings ...)
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 4/7] OpenSSL: don't use direct access to the internal of DSA Emmanuel Deloget
@ 2017-05-19 10:38 ` Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 6/7] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX Emmanuel Deloget
` (2 subsequent siblings)
6 siblings, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:38 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
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 d2dc1ffd..9c7074d1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -920,6 +920,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 9b113d7b..8f03e2ba 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -508,6 +508,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 942684ce..d6741523 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 881a2d13..fd599f40 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>
@@ -844,13 +845,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);
}
@@ -858,7 +870,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 ae4a638f..2a66d9b8 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 68d06876..5a997750 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -1388,7 +1388,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);
@@ -1396,11 +1396,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 fdfc4a27..8305ec5b 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 f8682d17..21899bb9 100644
--- a/src/openvpn/openvpn.h
+++ b/src/openvpn/openvpn.h
@@ -473,7 +473,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 bcef0ef4..908b650f 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -724,7 +724,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)
@@ -738,14 +739,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.11.0
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH 6/7] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
` (3 preceding siblings ...)
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 5/7] OpenSSL: don't use direct access to the internal of EVP_MD_CTX Emmanuel Deloget
@ 2017-05-19 10:38 ` Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 7/7] OpenSSL: don't use direct access to the internal of HMAC_CTX Emmanuel Deloget
2017-06-11 19:36 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Steffan Karger
6 siblings, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:38 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
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 9c7074d1..8a9a3ff3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -920,6 +920,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 50e6a734..893879cf 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -830,7 +830,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);
@@ -879,7 +879,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 8f03e2ba..3a911a47 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -301,6 +301,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 d6741523..4d38aadc 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 fd599f40..0644f1c3 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -651,6 +651,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,
@@ -658,8 +671,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 8305ec5b..d1be9d78 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.11.0
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [Openvpn-devel] [PATCH 7/7] OpenSSL: don't use direct access to the internal of HMAC_CTX
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
` (4 preceding siblings ...)
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 6/7] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX Emmanuel Deloget
@ 2017-05-19 10:38 ` Emmanuel Deloget
2017-06-11 19:36 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Steffan Karger
6 siblings, 0 replies; 92+ messages in thread
From: Emmanuel Deloget @ 2017-05-19 10:38 UTC (permalink / raw)
To: openvpn-devel
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 <logout@...260...>
---
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 8a9a3ff3..7875c4fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -922,6 +922,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 893879cf..a80c3f7f 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -854,7 +854,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,
@@ -885,7 +885,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 3a911a47..3dc75ab9 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -584,6 +584,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 4d38aadc..f0698f61 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 0644f1c3..b64f7f04 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -911,6 +911,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,
@@ -918,8 +931,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);
@@ -930,7 +941,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 0c436812..4a4e8b9b 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 d1be9d78..3c93bfaa 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 3d5e8241..55cc457d 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -1607,8 +1607,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;
@@ -1617,8 +1617,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));
@@ -1626,36 +1626,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.11.0
^ permalink raw reply related [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] OpenSSL 1.1 patch set - status?
2017-05-19 10:37 ` Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
@ 2017-05-19 11:41 ` Gert Doering
2017-06-08 15:57 ` Emmanuel Deloget
1 sibling, 1 reply; 92+ messages in thread
From: Gert Doering @ 2017-05-19 11:41 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: openvpn-devel
[-- Attachment #1: Type: text/plain, Size: 961 bytes --]
Hi,
On Fri, May 19, 2017 at 12:37:17PM +0200, Emmanuel Deloget wrote:
> > I'm wondering where this got stuck - are you waiting for us to move
> > forward (like, missing review of parts of the patch set), or are we
> > waiting for you, and you've been busy?
>
> Problem is that I'm working in a more-than-full-time manner on
> way-too-many-other subjects :)
Thanks for quickly sending us the current patch set. Now it's on us again.
(And yes, we fully understand the "too many projects, too many complaining
customers, angry wife as well, and too little time" thing :) )
Over to Steffan now - I'm so happy that I do not have to understand
OpenSSL code... ;-)
gert
--
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@...1296...
fax: +49-89-35655025 gert@...1297...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 630 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] OpenSSL 1.1 patch set - status?
2017-05-19 11:41 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
@ 2017-06-08 15:57 ` Emmanuel Deloget
2017-06-08 16:11 ` Steffan Karger
0 siblings, 1 reply; 92+ messages in thread
From: Emmanuel Deloget @ 2017-06-08 15:57 UTC (permalink / raw)
To: Gert Doering <gert@; +Cc: openvpn-devel, Steffan Karger <steffan@
[-- Attachment #1: Type: text/plain, Size: 1319 bytes --]
Hi Gert,
On Fri, May 19, 2017 at 1:41 PM, Gert Doering <gert@...1296...> wrote:
> Hi,
>
> On Fri, May 19, 2017 at 12:37:17PM +0200, Emmanuel Deloget wrote:
> > > I'm wondering where this got stuck - are you waiting for us to move
> > > forward (like, missing review of parts of the patch set), or are we
> > > waiting for you, and you've been busy?
> >
> > Problem is that I'm working in a more-than-full-time manner on
> > way-too-many-other subjects :)
>
> Thanks for quickly sending us the current patch set. Now it's on us again.
>
If there is anything bad, please tell me - I should be able to do another
round if needed :)
>
> (And yes, we fully understand the "too many projects, too many complaining
> customers, angry wife as well, and too little time" thing :) )
>
>
Yeah. It seems that "somebody" limited the day length to a small value
that fit on a 5 bit word. I'm wondering if this "person" was told about
uint32_t...
>
> Over to Steffan now - I'm so happy that I do not have to understand
> OpenSSL code... ;-)
>
Good thing is : there is nothing complex in the changes I made. I'm pretty
sure you'll be able to understand both the changes and what the original
code does :)
>
> gert
>
BR,
-- Emmanuel Deloget
[-- Attachment #2: Type: text/html, Size: 3050 bytes --]
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] OpenSSL 1.1 patch set - status?
2017-06-08 15:57 ` Emmanuel Deloget
@ 2017-06-08 16:11 ` Steffan Karger
0 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-06-08 16:11 UTC (permalink / raw)
To: Emmanuel Deloget <logout@; +Cc: Gert Doering <gert@
Hi,
On 8 June 2017 at 17:57, Emmanuel Deloget <logout@...260...> wrote:
> On Fri, May 19, 2017 at 1:41 PM, Gert Doering <gert@...1296...> wrote:
>> On Fri, May 19, 2017 at 12:37:17PM +0200, Emmanuel Deloget wrote:
>> > > I'm wondering where this got stuck - are you waiting for us to move
>> > > forward (like, missing review of parts of the patch set), or are we
>> > > waiting for you, and you've been busy?
>> >
>> > Problem is that I'm working in a more-than-full-time manner on
>> > way-too-many-other subjects :)
>>
>> Thanks for quickly sending us the current patch set. Now it's on us
>> again.
>
> If there is anything bad, please tell me - I should be able to do another
> round if needed :)
>
>> (And yes, we fully understand the "too many projects, too many complaining
>> customers, angry wife as well, and too little time" thing :) )
>
> Yeah. It seems that "somebody" limited the day length to a small value that
> fit on a 5 bit word. I'm wondering if this "person" was told about
> uint32_t...
>
>> Over to Steffan now - I'm so happy that I do not have to understand
>> OpenSSL code... ;-)
>
> Good thing is : there is nothing complex in the changes I made. I'm pretty
> sure you'll be able to understand both the changes and what the original
> code does :)
This is probably the most polite bump mail I've ever seen :-p
Just so you know: I haven't forgotten about these - they are
confronting me with my back log each time I open my mailbox... I'll
get to it at some point, but in the mean time (as always) other
reviewers are of course welcome to look at them too!
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
` (5 preceding siblings ...)
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 7/7] OpenSSL: don't use direct access to the internal of HMAC_CTX Emmanuel Deloget
@ 2017-06-11 19:36 ` Steffan Karger
6 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-06-11 19:36 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 19-05-17 12:38, Emmanuel Deloget wrote:
> 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).
>
> We double-check the certificate purpose using "direct access" to the
> internal of the certificate object (of course, this is not a real
> direct access, but we still fetch ASN1 strings within the X509 object
> and we check the internal value of these strings). This allow us to
> warn the user if there is a discrepancy between the X509_check_purpose()
> return value and our internal, less strict check.
Very nice that you found a way out of this!
> 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 <logout@...260...>
> ---
> configure.ac | 1 +
> src/openvpn/openssl_compat.h | 15 ++++++++++
> src/openvpn/ssl_openssl.c | 3 +-
> src/openvpn/ssl_verify_openssl.c | 64 ++++++++++++++++++++++++++++++++++------
> 4 files changed, 73 insertions(+), 10 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 7d3fce5b..9d5e340b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -922,6 +922,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 92f014d5..29a7588c 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 645ccf51..a082c3cd 100644
> --- a/src/openvpn/ssl_openssl.c
> +++ b/src/openvpn/ssl_openssl.c
> @@ -1070,7 +1070,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 9b1533bc..4785f314 100644
> --- a/src/openvpn/ssl_verify_openssl.c
> +++ b/src/openvpn/ssl_verify_openssl.c
> @@ -294,18 +294,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;
> }
>
> @@ -578,13 +580,57 @@ 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
> + */
> + result_t result = X509_check_purpose((X509 *)peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ?
> + SUCCESS : FAILURE;
Instead of casting away const, I think we should remove the 'const'
qualifier from the function argument. The caller has a non-const
peer_cert anyway, and casting away const should really be avoided.
> + /*
> + * old versions of OpenSSL allow us to make the less strict check we used to
> + * do. If this less strict check pass, warn user that this might not be the
> + * case when its distribution will update to OpenSSL 1.1
> + */
> + if (result == FAILURE)
> + {
> + ASN1_BIT_STRING *ns;
> + ns = X509_get_ext_d2i((X509 *)peer_cert, NID_netscape_cert_type, NULL, NULL);
> + result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_CLIENT)) ? SUCCESS : FAILURE;
> + if (result == SUCCESS)
> + {
> + msg(M_WARN, "X509: Certificate is a client certificate yet it's purpose "
> + "cannot be verified (check may fail in the future)");
> + }
This seems to introduce a memory leak: ns should be free'd using
ASN1_BIT_STRING_free().
> + }
> + return result;
> }
> 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
> + */
> + result_t result = X509_check_purpose((X509 *)peer_cert, X509_PURPOSE_SSL_SERVER, 0) ?
> + SUCCESS : FAILURE;
> +
> + /*
> + * old versions of OpenSSL allow us to make the less strict check we used to
> + * do. If this less strict check pass, warn user that this might not be the
> + * case when its distribution will update to OpenSSL 1.1
> + */
> + if (result == FAILURE)
> + {
> + ASN1_BIT_STRING *ns;
> + ns = X509_get_ext_d2i((X509 *)peer_cert, NID_netscape_cert_type, NULL, NULL);
> + result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_SERVER)) ? SUCCESS : FAILURE;
> + if (result == SUCCESS)
> + {
> + msg(M_WARN, "X509: Certificate is a server certificate yet it's purpose "
> + "cannot be verified (check may fail in the future)");
> + }
> + }
> + return result;
> }
>
> return FAILURE;
>
Could you send a follow-up patch with these issues fixed?
Thanks,
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH 2/7] OpenSSL: don't use direct access to the internal of EVP_PKEY
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 2/7] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
@ 2017-06-11 19:40 ` Steffan Karger
0 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-06-11 19:40 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 19-05-17 12:38, Emmanuel Deloget wrote:
> 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 <logout@...260...>
> ---
> configure.ac | 3 +++
> src/openvpn/openssl_compat.h | 42 ++++++++++++++++++++++++++++++++++++++++++
> src/openvpn/ssl_openssl.c | 6 +++---
> 3 files changed, 48 insertions(+), 3 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 9d5e340b..a92e8142 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -926,6 +926,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
> X509_STORE_get0_objects \
> X509_OBJECT_free \
> X509_OBJECT_get_type \
> + EVP_PKEY_id \
> + 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 29a7588c..0d82cf25 100644
> --- a/src/openvpn/openssl_compat.h
> +++ b/src/openvpn/openssl_compat.h
> @@ -134,6 +134,48 @@ 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_ID)
> +/**
> + * Get the PKEY type
> + *
> + * @param pkey Public key object
> + * @return The key type
> + */
> +static inline int
> +EVP_PKEY_id(const EVP_PKEY *pkey)
> +{
> + return pkey ? pkey->type : EVP_PKEY_NONE;
> +}
> +#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 a082c3cd..1c73641c 100644
> --- a/src/openvpn/ssl_openssl.c
> +++ b/src/openvpn/ssl_openssl.c
> @@ -1072,7 +1072,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);
> @@ -1677,13 +1677,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",
>
This looks good to me - ACK.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH 3/7] OpenSSL: don't use direct access to the internal of RSA
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 3/7] OpenSSL: don't use direct access to the internal of RSA Emmanuel Deloget
@ 2017-06-11 20:09 ` Steffan Karger
0 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-06-11 20:09 UTC (permalink / raw)
To: openvpn-devel
Hi,
Patch looks good in general, but some minor remarks:
On 19-05-17 12:38, Emmanuel Deloget wrote:
> 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 <logout@...260...>
> ---
> configure.ac | 3 ++
> src/openvpn/openssl_compat.h | 84 ++++++++++++++++++++++++++++++++++++++++++++
> src/openvpn/ssl_openssl.c | 24 ++++++++-----
> 3 files changed, 103 insertions(+), 8 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index a92e8142..e4c053c8 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -929,6 +929,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
> EVP_PKEY_id \
> 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 0d82cf25..29cd13a4 100644
> --- a/src/openvpn/openssl_compat.h
> +++ b/src/openvpn/openssl_compat.h
> @@ -176,6 +176,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 1c73641c..48479c0d 100644
> --- a/src/openvpn/ssl_openssl.c
> +++ b/src/openvpn/ssl_openssl.c
> @@ -975,8 +975,8 @@ 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;
> + const RSA_METHOD *meth = RSA_get_method(rsa);
> + RSA_meth_free((RSA_METHOD *)meth);
Casting away const is safe here, but I'd like to make that a bit more
obvious. How about renaming 'rsa_finish()' to something like
'openvpn_extkey_rsa_finish' to make clear that this function is specific
for management external key. Also, add a comment to mention that 'meth'
was allocated in 'tls_ctx_use_external_private_key()' and is safe to fee
here.
> return 1;
> }
>
> @@ -1075,8 +1075,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;
> @@ -1677,11 +1680,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));
> + }
This would be somewhat nicer to partly implement in an RSA_bits() in
openssl_compat.h (mimicing OpenSSL 1.1's RSA_bits()).
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
* Re: [Openvpn-devel] [PATCH 4/7] OpenSSL: don't use direct access to the internal of DSA
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 4/7] OpenSSL: don't use direct access to the internal of DSA Emmanuel Deloget
@ 2017-06-11 20:11 ` Steffan Karger
0 siblings, 0 replies; 92+ messages in thread
From: Steffan Karger @ 2017-06-11 20:11 UTC (permalink / raw)
To: openvpn-devel
Hi,
On 19-05-17 12:38, Emmanuel Deloget wrote:
> 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 <logout@...260...>
> ---
> 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 e4c053c8..d2dc1ffd 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -932,6 +932,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 29cd13a4..fdfc4a27 100644
> --- a/src/openvpn/openssl_compat.h
> +++ b/src/openvpn/openssl_compat.h
> @@ -260,6 +260,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 48479c0d..242ab397 100644
> --- a/src/openvpn/ssl_openssl.c
> +++ b/src/openvpn/ssl_openssl.c
> @@ -1691,11 +1691,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));
> + }
Similar to 3/7: a DSA_bits() in openssl_compat.h is somewhat nicer.
-Steffan
^ permalink raw reply [flat|nested] 92+ messages in thread
end of thread, other threads:[~2017-06-11 20:11 UTC | newest]
Thread overview: 92+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-17 22:00 [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 01/15] OpenSSL: don't use direct access to the internal of SSL_CTX logout
2017-02-22 20:27 ` Steffan Karger
2017-02-22 21:13 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-23 8:03 ` [Openvpn-devel] [RFC PATCH v1 01/15] " Gert Doering
2017-02-23 9:23 ` Gert Doering
2017-02-23 9:31 ` Emmanuel Deloget
2017-02-23 9:36 ` Steffan Karger
2017-02-23 10:35 ` [Openvpn-devel] [PATCH] OpenSSL: 1.1 fallout - fix configure on old autoconf Steffan Karger
2017-02-23 10:59 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 02/15] OpenSSL: don't use direct access to the internal of X509_STORE logout
2017-02-22 20:36 ` Steffan Karger
2017-02-22 21:14 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 03/15] OpenSSL: don't use direct access to the internal of X509_OBJECT logout
2017-02-22 20:50 ` Steffan Karger
2017-02-22 21:14 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD logout
2017-02-22 22:13 ` Steffan Karger
2017-02-23 9:39 ` Emmanuel Deloget
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 05/15] OpenSSL: don't use direct access to the internal of X509 logout
2017-03-02 20:36 ` Steffan Karger
2017-03-02 21:26 ` Gert Doering
2017-03-04 15:13 ` Steffan Karger
2017-03-04 16:22 ` Emmanuel Deloget
2017-03-04 22:38 ` David Sommerseth
2017-03-27 15:49 ` Emmanuel Deloget
2017-03-28 8:43 ` Emmanuel Deloget
2017-03-28 8:49 ` Gert Doering
2017-05-18 20:49 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
2017-05-19 10:37 ` Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 2/7] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
2017-06-11 19:40 ` Steffan Karger
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 3/7] OpenSSL: don't use direct access to the internal of RSA Emmanuel Deloget
2017-06-11 20:09 ` Steffan Karger
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 4/7] OpenSSL: don't use direct access to the internal of DSA Emmanuel Deloget
2017-06-11 20:11 ` Steffan Karger
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 5/7] OpenSSL: don't use direct access to the internal of EVP_MD_CTX Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 6/7] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX Emmanuel Deloget
2017-05-19 10:38 ` [Openvpn-devel] [PATCH 7/7] OpenSSL: don't use direct access to the internal of HMAC_CTX Emmanuel Deloget
2017-06-11 19:36 ` [Openvpn-devel] [PATCH 1/7] OpenSSL: don't use direct access to the internal of X509 Steffan Karger
2017-05-19 11:41 ` [Openvpn-devel] OpenSSL 1.1 patch set - status? Gert Doering
2017-06-08 15:57 ` Emmanuel Deloget
2017-06-08 16:11 ` Steffan Karger
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 07/15] OpenSSL: don't use direct access to the internal of RSA logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 08/15] OpenSSL: don't use direct access to the internal of DSA logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 09/15] OpenSSL: don't use direct access to the internal of X509_STORE_CTX logout
2017-02-21 21:30 ` Steffan Karger
2017-02-22 14:47 ` Christian Hesse
2017-02-22 15:34 ` Steffan Karger
2017-02-22 16:07 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 10/15] OpenSSL: don't use direct access to the internal of EVP_MD_CTX logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 11/15] OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 12/15] OpenSSL: don't use direct access to the internal of HMAC_CTX logout
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 13/15] OpenSSL: SSLeay symbols are no longer available in OpenSSL 1.1 logout
2017-03-02 20:39 ` Steffan Karger
2017-03-05 12:21 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 14/15] OpenSSL: check for the SSL reason, not the full error logout
2017-02-19 12:36 ` Steffan Karger
2017-02-19 17:52 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-02-17 22:00 ` [Openvpn-devel] [RFC PATCH v1 15/15] OpenSSL: constify getbio() parameters logout
2017-02-19 12:03 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Steffan Karger
2017-02-19 14:58 ` David Sommerseth
2017-02-19 15:09 ` Steffan Karger
2017-02-19 15:01 ` Emmanuel Deloget
2017-02-19 17:49 ` Gert Doering
2017-02-20 11:45 ` Emmanuel Deloget
2017-02-20 12:29 ` Christian Hesse
2017-02-20 13:33 ` Emmanuel Deloget
2017-02-20 13:53 ` Emmanuel Deloget
2017-02-20 14:52 ` Emmanuel Deloget
2017-02-20 15:02 ` Christian Hesse
2017-02-20 15:08 ` Christian Hesse
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 " Emmanuel Deloget
2017-02-23 20:57 ` Christian Hesse
2017-02-24 12:13 ` Christian Hesse
2017-02-24 21:49 ` Christian Hesse
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 04/15] OpenSSL: don't use direct access to the internal of RSA_METHOD Emmanuel Deloget
2017-03-02 20:01 ` Steffan Karger
2017-03-05 9:53 ` [Openvpn-devel] [PATCH applied] " Gert Doering
2017-03-05 10:29 ` Steffan Karger
2017-03-05 12:08 ` Emmanuel Deloget
2017-03-05 12:26 ` Gert Doering
2017-02-23 14:35 ` [Openvpn-devel] [PATCH v3 07/15] OpenSSL: don't use direct access to the internal of RSA Emmanuel Deloget
2017-02-20 12:37 ` [Openvpn-devel] [RFC PATCH v1 00/15] Add support for OpenSSL 1.1.x Gert Doering
2017-02-20 13:38 ` Emmanuel Deloget
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 " Emmanuel Deloget
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 06/15] OpenSSL: don't use direct access to the internal of EVP_PKEY Emmanuel Deloget
2017-02-20 14:32 ` [Openvpn-devel] [RFC PATCH v2 15/15] OpenSSL: use EVP_CipherInit_ex() instead of EVP_CipherInit() Emmanuel Deloget
2017-03-02 20:44 ` Steffan Karger
2017-03-05 12:21 ` [Openvpn-devel] [PATCH applied] " Gert Doering
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.