Date: Wednesday, June 21, 2017 @ 10:40:07 Author: eworm Revision: 299112
upgpkg: openvpn 2.4.3-1 new upstream release with security fixes Modified: openvpn/trunk/PKGBUILD Deleted: openvpn/trunk/0004-openssl-1-1-0.patch --------------------------+ 0004-openssl-1-1-0.patch | 1614 --------------------------------------------- PKGBUILD | 18 2 files changed, 7 insertions(+), 1625 deletions(-) Deleted: 0004-openssl-1-1-0.patch =================================================================== --- 0004-openssl-1-1-0.patch 2017-06-21 10:23:04 UTC (rev 299111) +++ 0004-openssl-1-1-0.patch 2017-06-21 10:40:07 UTC (rev 299112) @@ -1,1614 +0,0 @@ -From 17d1ab90c228b1efbe774357bd3265b2af006899 Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:23 +0200 -Subject: [PATCH 1/8] OpenSSL: don't use direct access to the internal of - X509 - -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. - -We use these changes to make peer_cert a non-const parameter to -x509_verify_ns_cert_type(). The underlying library waits for a -non-const pointer, and forcing it to be a const pointer does not make -much sense (please note that this has an effect on the mbedtls part -too). - -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 <log...@free.fr> -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-2-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14792.html -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - configure.ac | 1 + - src/openvpn/openssl_compat.h | 15 +++++++++ - src/openvpn/ssl_openssl.c | 3 +- - src/openvpn/ssl_verify_backend.h | 2 +- - src/openvpn/ssl_verify_mbedtls.c | 2 +- - src/openvpn/ssl_verify_openssl.c | 68 ++++++++++++++++++++++++++++++++++------ - 6 files changed, 78 insertions(+), 13 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 334247df..c30bf3d5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -921,6 +921,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 811d559c..612bfa56 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -73,6 +73,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 1fa46e18..89c3b014 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_backend.h b/src/openvpn/ssl_verify_backend.h -index 35660532..978e54fd 100644 ---- a/src/openvpn/ssl_verify_backend.h -+++ b/src/openvpn/ssl_verify_backend.h -@@ -210,7 +210,7 @@ void x509_setenv_track(const struct x509_track *xt, struct env_set *es, - * the expected bit set. \c FAILURE if the certificate does - * not have NS cert type verification or the wrong bit set. - */ --result_t x509_verify_ns_cert_type(const openvpn_x509_cert_t *cert, const int usage); -+result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *cert, const int usage); - - /* - * Verify X.509 key usage extension field. -diff --git a/src/openvpn/ssl_verify_mbedtls.c b/src/openvpn/ssl_verify_mbedtls.c -index d80b7a53..27c5c3e1 100644 ---- a/src/openvpn/ssl_verify_mbedtls.c -+++ b/src/openvpn/ssl_verify_mbedtls.c -@@ -410,7 +410,7 @@ x509_setenv(struct env_set *es, int cert_depth, mbedtls_x509_crt *cert) - } - - result_t --x509_verify_ns_cert_type(const mbedtls_x509_crt *cert, const int usage) -+x509_verify_ns_cert_type(mbedtls_x509_crt *cert, const int usage) - { - if (usage == NS_CERT_CHECK_NONE) - { -diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c -index 5d897b6d..31c16389 100644 ---- a/src/openvpn/ssl_verify_openssl.c -+++ b/src/openvpn/ssl_verify_openssl.c -@@ -293,18 +293,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; - } - -@@ -569,7 +571,7 @@ x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert) - } - - result_t --x509_verify_ns_cert_type(const openvpn_x509_cert_t *peer_cert, const int usage) -+x509_verify_ns_cert_type(openvpn_x509_cert_t *peer_cert, const int usage) - { - if (usage == NS_CERT_CHECK_NONE) - { -@@ -577,13 +579,59 @@ 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 weird thing that -+ * prevent it to take a const argument -+ */ -+ result_t result = X509_check_purpose(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(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)"); -+ } -+ ASN1_BIT_STRING_free(ns); -+ } -+ 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 weird thing that -+ * prevent it to take a const argument -+ */ -+ result_t result = X509_check_purpose(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(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)"); -+ } -+ ASN1_BIT_STRING_free(ns); -+ } -+ return result; - } - - return FAILURE; -From b8ca5bc3593e539d0735a74b55ed41a792e55033 Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:24 +0200 -Subject: [PATCH 2/8] OpenSSL: don't use direct access to the internal of - EVP_PKEY - -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 <log...@free.fr> -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-3-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14795.html -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - 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 c30bf3d5..43f332b2 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -925,6 +925,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 612bfa56..60498595 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -133,6 +133,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 89c3b014..c84372d6 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", -From f7780af6f1aaffcbbfb8b4dde0f2af052f84b28a Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:25 +0200 -Subject: [PATCH 3/8] OpenSSL: don't use direct access to the internal of RSA - -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 <log...@free.fr> -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-4-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14790.html -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - configure.ac | 4 ++ - src/openvpn/openssl_compat.h | 100 +++++++++++++++++++++++++++++++++++++++++++ - src/openvpn/ssl_openssl.c | 24 +++++++---- - 3 files changed, 119 insertions(+), 9 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 43f332b2..e9ac5a6e 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -928,6 +928,10 @@ 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_bits \ -+ 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 60498595..e3f20b73 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -175,6 +175,106 @@ 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_BITS) -+/** -+ * Number of significant RSA bits -+ * -+ * @param rsa The RSA object ; shall not be NULL -+ * @return The number of RSA bits or 0 on error -+ */ -+static inline int -+RSA_bits(const RSA *rsa) -+{ -+ const BIGNUM *n = NULL; -+ RSA_get0_key(rsa, &n, NULL, NULL); -+ return n ? BN_num_bits(n) : 0; -+} -+#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 c84372d6..da801ed5 100644 ---- a/src/openvpn/ssl_openssl.c -+++ b/src/openvpn/ssl_openssl.c -@@ -973,10 +973,13 @@ rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i - - /* called at RSA_free */ - static int --rsa_finish(RSA *rsa) -+openvpn_extkey_rsa_finish(RSA *rsa) - { -- RSA_meth_free(rsa->meth); -- rsa->meth = NULL; -+ /* meth was allocated in tls_ctx_use_external_private_key() ; since -+ * this function is called when the parent RSA object is destroyed, -+ * it is no longer used after this point so kill it. */ -+ const RSA_METHOD *meth = RSA_get_method(rsa); -+ RSA_meth_free((RSA_METHOD *)meth); - return 1; - } - -@@ -1058,7 +1061,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, - 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_set_finish(rsa_meth, openvpn_extkey_rsa_finish); - RSA_meth_set0_app_data(rsa_meth, NULL); - - /* allocate RSA object */ -@@ -1075,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; -@@ -1677,11 +1683,11 @@ 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) - { -+ RSA *rsa = EVP_PKEY_get0_RSA(pkey); - openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", -- BN_num_bits(pkey->pkey.rsa->n)); -+ RSA_bits(rsa)); - } - else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL - && pkey->pkey.dsa->p != NULL) -From c07c0358b553c519ed9d80e2e0a9ba48ca8850e4 Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:26 +0200 -Subject: [PATCH 4/8] OpenSSL: don't use direct access to the internal of DSA - -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 <log...@free.fr> -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-5-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14791.html -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - configure.ac | 2 ++ - src/openvpn/openssl_compat.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ - src/openvpn/ssl_openssl.c | 6 +++--- - 3 files changed, 49 insertions(+), 3 deletions(-) - -diff --git a/configure.ac b/configure.ac -index e9ac5a6e..52348780 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -932,6 +932,8 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then - RSA_bits \ - RSA_get0_key \ - RSA_set0_key \ -+ DSA_get0_pqg \ -+ DSA_bits \ - 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 e3f20b73..729fab6c 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -275,6 +275,50 @@ RSA_bits(const RSA *rsa) - } - #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_DSA_BITS) -+/** -+ * Number of significant DSA bits -+ * -+ * @param rsa The DSA object ; shall not be NULL -+ * @return The number of DSA bits or 0 on error -+ */ -+static inline int -+DSA_bits(const DSA *dsa) -+{ -+ const BIGNUM *p = NULL; -+ DSA_get0_pqg(dsa, &p, NULL, NULL); -+ return p ? BN_num_bits(p) : 0; -+} -+#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 da801ed5..11f4a567 100644 ---- a/src/openvpn/ssl_openssl.c -+++ b/src/openvpn/ssl_openssl.c -@@ -1689,11 +1689,11 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) - openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", - RSA_bits(rsa)); - } -- 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) - { -+ DSA *dsa = EVP_PKEY_get0_DSA(pkey); - openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", -- BN_num_bits(pkey->pkey.dsa->p)); -+ DSA_bits(dsa)); - } - EVP_PKEY_free(pkey); - } -From 3fd07c31fe8878dc75e760d151d291379c0f8743 Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:30 +0200 -Subject: [PATCH 5/8] OpenSSL: force meth->name as non-const when we free() - it - -We are in control of meth->name (we string_alloc() it in RSA_meth_new()) -so we know that we can free() it when it's no longer needed. Yet we have -to force the value to be non-const to avoid a compiler warning -- due to -the fact that OpenSSL defines the value as a const char*, regardless of -its origin. - -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-9-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14798.html - -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - src/openvpn/openssl_compat.h | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h -index 729fab6c..eeacb525 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -349,7 +349,13 @@ RSA_meth_free(RSA_METHOD *meth) - { - if (meth) - { -- free(meth->name); -+ /* OpenSSL defines meth->name to be a const pointer, yet we -+ * feed it with an allocated string (from RSA_meth_new()). -+ * Thus we are allowed to free it here. In order to avoid a -+ * "passing 'const char *' to parameter of type 'void *' discards -+ * qualifiers" warning, we force the pointer to be a non-const value. -+ */ -+ free((char *)meth->name); - free(meth); - } - } -From c481ef002803f360743c72727ae3ca971ce59a5d Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:27 +0200 -Subject: [PATCH 6/8] OpenSSL: don't use direct access to the internal of - EVP_MD_CTX - -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 <log...@free.fr> -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-6-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14793.html -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - 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 | 43 ++++++++++++++++++++++++ - src/openvpn/openvpn.h | 2 +- - src/openvpn/push.c | 11 ++++--- - 9 files changed, 143 insertions(+), 52 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 52348780..f971e54a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -919,6 +919,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 e2d2c96f..f1da0432 100644 ---- a/src/openvpn/crypto_backend.h -+++ b/src/openvpn/crypto_backend.h -@@ -507,6 +507,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 e6388dd5..03cc1308 100644 ---- a/src/openvpn/crypto_mbedtls.c -+++ b/src/openvpn/crypto_mbedtls.c -@@ -765,6 +765,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 ee20902f..3a5a26f8 100644 ---- a/src/openvpn/crypto_openssl.c -+++ b/src/openvpn/crypto_openssl.c -@@ -41,6 +41,7 @@ - #include "integer.h" - #include "crypto.h" - #include "crypto_backend.h" -+#include "openssl_compat.h" - - #include <openssl/des.h> - #include <openssl/err.h> -@@ -843,13 +844,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); - } -@@ -857,7 +869,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 e578c85d..c553f939 100644 ---- a/src/openvpn/httpdigest.c -+++ b/src/openvpn/httpdigest.c -@@ -80,27 +80,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); - } - -@@ -122,40 +123,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 d286c197..df108b08 100644 ---- a/src/openvpn/misc.c -+++ b/src/openvpn/misc.c -@@ -1387,7 +1387,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); -@@ -1395,11 +1395,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 eeacb525..3d8fad10 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -45,6 +45,49 @@ - #include <openssl/ssl.h> - #include <openssl/x509.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 c01e8a2c..9262e68b 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 441d303e..5947a31f 100644 ---- a/src/openvpn/push.c -+++ b/src/openvpn/push.c -@@ -723,7 +723,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) -@@ -737,14 +738,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; -From 6cbd48a3ead23f004f25943d067fa668efdc580e Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:28 +0200 -Subject: [PATCH 7/8] OpenSSL: don't use direct access to the internal of - EVP_CIPHER_CTX - -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 <log...@free.fr> -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-7-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14796.html -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - 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 f971e54a..07fc3392 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -919,6 +919,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 b6d0d550..f7c4d60a 100644 ---- a/src/openvpn/crypto.c -+++ b/src/openvpn/crypto.c -@@ -829,7 +829,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); - -@@ -878,7 +878,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 f1da0432..9679ee9b 100644 ---- a/src/openvpn/crypto_backend.h -+++ b/src/openvpn/crypto_backend.h -@@ -300,6 +300,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 03cc1308..5f16a1f0 100644 ---- a/src/openvpn/crypto_mbedtls.c -+++ b/src/openvpn/crypto_mbedtls.c -@@ -508,6 +508,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 3a5a26f8..f4470fc0 100644 ---- a/src/openvpn/crypto_openssl.c -+++ b/src/openvpn/crypto_openssl.c -@@ -650,6 +650,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, -@@ -657,8 +670,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 3d8fad10..c9e2692b 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -88,6 +88,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 -From aba98e9050eb54d72d921e70bcd422cb892b9c6c Mon Sep 17 00:00:00 2001 -From: Emmanuel Deloget <log...@free.fr> -Date: Mon, 12 Jun 2017 15:43:29 +0200 -Subject: [PATCH 8/8] OpenSSL: don't use direct access to the internal of - HMAC_CTX - -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 <log...@free.fr> -Acked-by: Steffan Karger <steffan.kar...@fox-it.com> -Message-Id: <20170612134330.20971-8-log...@free.fr> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14797.html -Signed-off-by: Gert Doering <g...@greenie.muc.de> ---- - 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 07fc3392..56ce5f82 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -921,6 +921,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 f7c4d60a..191fee8e 100644 ---- a/src/openvpn/crypto.c -+++ b/src/openvpn/crypto.c -@@ -853,7 +853,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, -@@ -884,7 +884,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 9679ee9b..b7f519b5 100644 ---- a/src/openvpn/crypto_backend.h -+++ b/src/openvpn/crypto_backend.h -@@ -583,6 +583,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 5f16a1f0..24bc3158 100644 ---- a/src/openvpn/crypto_mbedtls.c -+++ b/src/openvpn/crypto_mbedtls.c -@@ -840,6 +840,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 f4470fc0..a55e65c1 100644 ---- a/src/openvpn/crypto_openssl.c -+++ b/src/openvpn/crypto_openssl.c -@@ -910,6 +910,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, -@@ -917,8 +930,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); - -@@ -929,7 +940,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 69b7d426..16d60d2c 100644 ---- a/src/openvpn/ntlm.c -+++ b/src/openvpn/ntlm.c -@@ -85,13 +85,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 c9e2692b..c765f0bb 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -116,6 +116,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 cc7b1830..c658f377 100644 ---- a/src/openvpn/ssl.c -+++ b/src/openvpn/ssl.c -@@ -1606,8 +1606,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; - -@@ -1616,8 +1616,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)); -@@ -1625,36 +1625,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)); Modified: PKGBUILD =================================================================== --- PKGBUILD 2017-06-21 10:23:04 UTC (rev 299111) +++ PKGBUILD 2017-06-21 10:40:07 UTC (rev 299112) @@ -2,8 +2,8 @@ # Maintainer: Christian Hesse <m...@eworm.de> pkgname=openvpn -pkgver=2.4.2 -pkgrel=2 +pkgver=2.4.3 +pkgrel=1 pkgdesc='An easy-to-use, robust and highly configurable VPN (Virtual Private Network)' arch=('i686' 'x86_64') url='http://openvpn.net/index.php/open-source.html' @@ -13,19 +13,15 @@ license=('custom') install=openvpn.install validpgpkeys=('6D04F8F1B0173111F499795E29584D9F40864578' # Samuli Seppänen <sam...@openvpn.net> - '7ACD56B74144925C6214329757DB9DAB613B8DA1') # David Sommerseth (OpenVPN Technologies, Inc) <dav...@openvpn.net> -source=("https://swupdate.openvpn.net/community/releases/openvpn-${pkgver}.tar.xz"{,.asc} - '0004-openssl-1-1-0.patch') -sha256sums=('df5c4f384b7df6b08a2f6fa8a84b9fd382baf59c2cef1836f82e2a7f62f1bff9' - 'SKIP' - '75259cb14ed8237c2ca5618eca902ed39f720df166e732911e21dd5abcc68b3e') + '7ACD56B74144925C6214329757DB9DAB613B8DA1' # David Sommerseth (OpenVPN Technologies, Inc) <dav...@openvpn.net> + 'F554A3687412CFFEBDEFE0A312F5F7B42F2B01E7') # OpenVPN - Security Mailing List <secur...@openvpn.net> +source=("https://swupdate.openvpn.net/community/releases/openvpn-${pkgver}.tar.xz"{,.asc}) +sha256sums=('7aa86167a5b8923e54e8795b814ed77288c793671f59fd830d9ab76d4b480571' + 'SKIP') prepare() { cd "${srcdir}"/${pkgname}-${pkgver} - # allow to build against openssl 1.1.0 - patch -Np1 < "${srcdir}"/0004-openssl-1-1-0.patch - # regenerate configure script autoreconf -fi }