From 6928d7fa6f6af81c1a0d568e349f5b20da0db69a Mon Sep 17 00:00:00 2001 From: Laszlo Budai Date: Sat, 7 Jan 2017 01:11:39 +0100 Subject: [PATCH 1/4] tlscontext: use getter function to access X509 verify parameter ssl_ctx_st structure is a non-exported interface (ssl/ssl_locl.h) Note, that the getter(`SSL_CTX_get0_param`) function available from version 1.0.2 but minimum supported OpenSSL version is 0.98. This is why a function with the same name is initiated when this getter is not available. Signed-off-by: Laszlo Budai --- configure.ac | 2 ++ lib/tlscontext.c | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 88f8ce24..fe2c387c 100644 --- a/configure.ac +++ b/configure.ac @@ -802,6 +802,8 @@ if test -n "$OPENSSL_LIBS" -a "$linking_mode" != "dynamic"; then LIBS=$old_LIBS fi +AC_CHECK_FUNC(SSL_CTX_get0_param, AC_DEFINE(HAVE_SSL_CTX_GET0_PARAM, 1, [SSL_CTX_get0_param is present])) + dnl dnl Right now, openssl is never linked statically as it is only used by the diff --git a/lib/tlscontext.c b/lib/tlscontext.c index 5a357eb8..309c5e2b 100644 --- a/lib/tlscontext.c +++ b/lib/tlscontext.c @@ -31,6 +31,13 @@ #include #include +#ifndef SYSLOG_NG_HAVE_SSL_CTX_GET0_PARAM +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) +{ + return ctx->param; +} +#endif + gboolean tls_get_x509_digest(X509 *x, GString *hash_string) { @@ -311,7 +318,7 @@ tls_context_setup_session(TLSContext *self) if (self->crl_dir) verify_flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL; - X509_VERIFY_PARAM_set_flags(self->ssl_ctx->param, verify_flags); + X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(self->ssl_ctx), verify_flags); switch (self->verify_mode) { -- 2.11.0 From 372803d7a10441c65cb44c7b889f44e3cc2aa644 Mon Sep 17 00:00:00 2001 From: Laszlo Budai Date: Sat, 7 Jan 2017 01:11:43 +0100 Subject: [PATCH 2/4] tlscontext: use SSL_CTX_get0_error_depth instead of direct member access Signed-off-by: Laszlo Budai --- lib/tlscontext.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/tlscontext.c b/lib/tlscontext.c index 309c5e2b..7e88e841 100644 --- a/lib/tlscontext.c +++ b/lib/tlscontext.c @@ -142,14 +142,15 @@ tls_session_verify(TLSSession *self, int ok, X509_STORE_CTX *ctx) if (self->ctx->verify_mode & TVM_UNTRUSTED) return 1; + int ctx_error_depth = X509_STORE_CTX_get_error_depth(ctx); /* accept certificate if its fingerprint matches, again regardless whether x509 certificate validation was successful */ - if (ok && ctx->error_depth == 0 && !tls_session_verify_fingerprint(ctx)) + if (ok && ctx_error_depth == 0 && !tls_session_verify_fingerprint(ctx)) { msg_notice("Certificate valid, but fingerprint constraints were not met, rejecting", NULL); return 0; } - if (ok && ctx->error_depth != 0 && (ctx->current_cert->ex_flags & EXFLAG_CA) == 0) + if (ok && ctx_error_depth != 0 && (ctx->current_cert->ex_flags & EXFLAG_CA) == 0) { msg_notice("Invalid certificate found in chain, basicConstraints.ca is unset in non-leaf certificate", NULL); ctx->error = X509_V_ERR_INVALID_CA; @@ -157,7 +158,7 @@ tls_session_verify(TLSSession *self, int ok, X509_STORE_CTX *ctx) } /* reject certificate if it is valid, but its DN is not trusted */ - if (ok && ctx->error_depth == 0 && !tls_session_verify_dn(ctx)) + if (ok && ctx_error_depth == 0 && !tls_session_verify_dn(ctx)) { msg_notice("Certificate valid, but DN constraints were not met, rejecting", NULL); ctx->error = X509_V_ERR_CERT_UNTRUSTED; -- 2.11.0 From 551a1acbb6eb0a6f23ad41665e137a401c748c58 Mon Sep 17 00:00:00 2001 From: Laszlo Budai Date: Sat, 7 Jan 2017 01:11:47 +0100 Subject: [PATCH 3/4] openssl: support 1.1 Fixes: #1234 Signed-off-by: Laszlo Budai --- configure.ac | 6 +++-- lib/compat/Makefile.am | 6 +++-- lib/compat/openssl_support.c | 46 +++++++++++++++++++++++++++++++++ lib/compat/openssl_support.h | 53 ++++++++++++++++++++++++++++++++++++++ lib/tlscontext.c | 52 +++++++++++++++++-------------------- modules/afsocket/afinet-dest.c | 9 +++++-- modules/cryptofuncs/cryptofuncs.c | 42 ++++++++++++++++++------------ modules/dbparser/pdbtool/pdbtool.c | 1 + 8 files changed, 165 insertions(+), 50 deletions(-) create mode 100644 lib/compat/openssl_support.c create mode 100644 lib/compat/openssl_support.h diff --git a/configure.ac b/configure.ac index fe2c387c..612b3842 100644 --- a/configure.ac +++ b/configure.ac @@ -802,8 +802,10 @@ if test -n "$OPENSSL_LIBS" -a "$linking_mode" != "dynamic"; then LIBS=$old_LIBS fi -AC_CHECK_FUNC(SSL_CTX_get0_param, AC_DEFINE(HAVE_SSL_CTX_GET0_PARAM, 1, [SSL_CTX_get0_param is present])) - +AC_CHECK_DECLS([SSL_CTX_get0_param],[], [], [[#include ]]) +AC_CHECK_DECLS([X509_STORE_CTX_get0_cert],[], [], [[#include ]]) +AC_CHECK_DECLS([X509_get_extension_flags], [], [], [[#include ]]) +AC_CHECK_DECLS([EVP_MD_CTX_reset], [], [], [[#include ]]) dnl dnl Right now, openssl is never linked statically as it is only used by the diff --git a/lib/compat/Makefile.am b/lib/compat/Makefile.am index 035932ef..f068c731 100644 --- a/lib/compat/Makefile.am +++ b/lib/compat/Makefile.am @@ -8,7 +8,8 @@ compatinclude_HEADERS = \ lib/compat/pio.h \ lib/compat/socket.h \ lib/compat/string.h \ - lib/compat/time.h + lib/compat/time.h \ + lib/compat/openssl_support.h compat_sources = \ lib/compat/getutent.c \ @@ -16,6 +17,7 @@ compat_sources = \ lib/compat/memrchr.c \ lib/compat/pio.c \ lib/compat/strcasestr.c \ - lib/compat/strtok_r.c + lib/compat/strtok_r.c \ + lib/compat/openssl_support.c include lib/compat/tests/Makefile.am diff --git a/lib/compat/openssl_support.c b/lib/compat/openssl_support.c new file mode 100644 index 00000000..f4c98ec3 --- /dev/null +++ b/lib/compat/openssl_support.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002-2016 Balabit + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#include "compat/openssl_support.h" + +#if !HAVE_DECL_SSL_CTX_GET0_PARAM +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) +{ + return ctx->param; +} +#endif + +#if !HAVE_DECL_X509_STORE_CTX_GET0_CERT +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) +{ + return ctx->cert; +} +#endif + +#if !HAVE_DECL_X509_GET_EXTENSION_FLAGS +uint32_t X509_get_extension_flags(X509 *x) +{ + return x->ex_flags; +} +#endif + diff --git a/lib/compat/openssl_support.h b/lib/compat/openssl_support.h new file mode 100644 index 00000000..89e793ac --- /dev/null +++ b/lib/compat/openssl_support.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2002-2016 Balabit + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#ifndef OPENSSL_SUPPORT_H_INCLUDED +#define OPENSSL_SUPPORT_H_INCLUDED + +#include "compat/compat.h" +#include + +#if !HAVE_DECL_SSL_CTX_GET0_PARAM +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +#endif + +#if !HAVE_DECL_X509_STORE_CTX_GET0_CERT +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); +#endif + +#if !HAVE_DECL_X509_GET_EXTENSION_FLAGS +#include +uint32_t X509_get_extension_flags(X509 *x); +#endif + +#if HAVE_DECL_EVP_MD_CTX_RESET +#include +#define EVP_MD_CTX_cleanup EVP_MD_CTX_reset +#define DECLARE_EVP_MD_CTX(md_ctx) EVP_MD_CTX * md_ctx = EVP_MD_CTX_create() +#else +#define DECLARE_EVP_MD_CTX(md_ctx) EVP_MD_CTX _##md_ctx; EVP_MD_CTX * md_ctx = & _##md_ctx +#define EVP_MD_CTX_destroy(md_ctx) EVP_MD_CTX_cleanup(md_ctx) +#endif + +#endif + diff --git a/lib/tlscontext.c b/lib/tlscontext.c index 7e88e841..9670d02f 100644 --- a/lib/tlscontext.c +++ b/lib/tlscontext.c @@ -24,6 +24,7 @@ #include "tlscontext.h" #include "misc.h" #include "messages.h" +#include "compat/openssl_support.h" #include #include @@ -31,13 +32,6 @@ #include #include -#ifndef SYSLOG_NG_HAVE_SSL_CTX_GET0_PARAM -X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) -{ - return ctx->param; -} -#endif - gboolean tls_get_x509_digest(X509 *x, GString *hash_string) { @@ -150,10 +144,11 @@ tls_session_verify(TLSSession *self, int ok, X509_STORE_CTX *ctx) return 0; } - if (ok && ctx_error_depth != 0 && (ctx->current_cert->ex_flags & EXFLAG_CA) == 0) + X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); + if (ok && ctx_error_depth != 0 && (X509_get_extension_flags(current_cert) & EXFLAG_CA) == 0) { msg_notice("Invalid certificate found in chain, basicConstraints.ca is unset in non-leaf certificate", NULL); - ctx->error = X509_V_ERR_INVALID_CA; + X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA); return 0; } @@ -161,17 +156,17 @@ tls_session_verify(TLSSession *self, int ok, X509_STORE_CTX *ctx) if (ok && ctx_error_depth == 0 && !tls_session_verify_dn(ctx)) { msg_notice("Certificate valid, but DN constraints were not met, rejecting", NULL); - ctx->error = X509_V_ERR_CERT_UNTRUSTED; + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_UNTRUSTED); return 0; } /* if the crl_dir is set in the configuration file but the directory is empty ignore this error */ - if (!ok && ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL) + if (!ok && X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL) { msg_notice("CRL directory is set but no CRLs found", NULL); return 1; } - if (!ok && ctx->error == X509_V_ERR_INVALID_PURPOSE) + if (!ok && X509_STORE_CTX_get_error(ctx) == X509_V_ERR_INVALID_PURPOSE) { msg_warning("Certificate valid, but purpose is invalid", NULL); return 1; @@ -191,22 +186,23 @@ tls_session_verify_callback(int ok, X509_STORE_CTX *ctx) */ if (X509_STORE_CTX_get_current_cert(ctx) == NULL) { - switch (ctx->error) - { - case X509_V_ERR_NO_EXPLICIT_POLICY: - /* NOTE: Because we set the CHECK_POLICY_FLAG if the - certificate contains ExplicitPolicy constraint - we would get this error. But this error is because - we do not set the policy what we want to check for. - */ - ok = 1; - break; - default: - msg_notice("Error occured during certificate validation", - evt_tag_int("error", ctx->error), - NULL); - break; - } + int ctx_error = X509_STORE_CTX_get_error(ctx); + switch (ctx_error) + { + case X509_V_ERR_NO_EXPLICIT_POLICY: + /* NOTE: Because we set the CHECK_POLICY_FLAG if the + certificate contains ExplicitPolicy constraint + we would get this error. But this error is because + we do not set the policy what we want to check for. + */ + ok = 1; + break; + default: + msg_notice("Error occured during certificate validation", + evt_tag_int("error", X509_STORE_CTX_get_error(ctx)), + NULL); + break; + } } else { diff --git a/modules/afsocket/afinet-dest.c b/modules/afsocket/afinet-dest.c index 9db1ea0f..539699be 100644 --- a/modules/afsocket/afinet-dest.c +++ b/modules/afsocket/afinet-dest.c @@ -27,6 +27,7 @@ #include "messages.h" #include "misc.h" #include "gprocess.h" +#include "compat/openssl_support.h" #include #include @@ -98,9 +99,13 @@ afinet_dd_verify_callback(gint ok, X509_STORE_CTX *ctx, gpointer user_data) AFInetDestDriver *self G_GNUC_UNUSED = (AFInetDestDriver *) user_data; TransportMapperInet *transport_mapper_inet = (TransportMapperInet *) self->super.transport_mapper; - if (ok && ctx->current_cert == ctx->cert && self->hostname && (transport_mapper_inet->tls_context->verify_mode & TVM_TRUSTED)) + X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); + X509 *cert = X509_STORE_CTX_get0_cert(ctx); + + if (ok && current_cert == cert && self->hostname + && (transport_mapper_inet->tls_context->verify_mode & TVM_TRUSTED)) { - ok = tls_verify_certificate_name(ctx->cert, self->hostname); + ok = tls_verify_certificate_name(cert, self->hostname); } return ok; diff --git a/modules/cryptofuncs/cryptofuncs.c b/modules/cryptofuncs/cryptofuncs.c index a7462e3a..a34c6b62 100644 --- a/modules/cryptofuncs/cryptofuncs.c +++ b/modules/cryptofuncs/cryptofuncs.c @@ -27,6 +27,7 @@ #include "uuid.h" #include "str-format.h" #include "plugin-types.h" +#include "compat/openssl_support.h" #include static void @@ -98,36 +99,45 @@ tf_hash_prepare(LogTemplateFunction *self, gpointer s, LogTemplate *parent, gint return FALSE; } state->md = md; - if ((state->length == 0) || (state->length > md->md_size * 2)) - state->length = md->md_size * 2; + gint md_size = EVP_MD_size(md); + if ((state->length == 0) || (state->length > md_size * 2)) + state->length = md_size * 2; return TRUE; } +static guint +_hash(const EVP_MD *md, GString **argv, gint argc, guchar *hash, guint hash_size) +{ + gint i; + guint md_len; + DECLARE_EVP_MD_CTX(mdctx); + EVP_MD_CTX_init(mdctx); + EVP_DigestInit_ex(mdctx, md, NULL); + + for (i = 0; i < argc; i++) + { + EVP_DigestUpdate(mdctx, argv[i]->str, argv[i]->len); + } + + EVP_DigestFinal_ex(mdctx, hash, &md_len); + EVP_MD_CTX_cleanup(mdctx); + EVP_MD_CTX_destroy(mdctx); + + return md_len; +} + static void tf_hash_call(LogTemplateFunction *self, gpointer s, const LogTemplateInvokeArgs *args, GString *result) { TFHashState *state = (TFHashState *) s; GString **argv; gint argc; - gint i; - EVP_MD_CTX mdctx; guchar hash[EVP_MAX_MD_SIZE]; gchar hash_str[EVP_MAX_MD_SIZE * 2 + 1]; guint md_len; - argv = (GString **) args->bufs->pdata; argc = args->bufs->len; - - EVP_MD_CTX_init(&mdctx); - EVP_DigestInit_ex(&mdctx, state->md, NULL); - - for (i = 0; i < argc; i++) - { - EVP_DigestUpdate(&mdctx, argv[i]->str, argv[i]->len); - } - EVP_DigestFinal_ex(&mdctx, hash, &md_len); - EVP_MD_CTX_cleanup(&mdctx); - + md_len = _hash(state->md, argv, argc, hash, sizeof(hash)); // we fetch the entire hash in a hex format otherwise we cannot truncate at // odd character numbers format_hex_string(hash, md_len, hash_str, sizeof(hash_str)); diff --git a/modules/dbparser/pdbtool/pdbtool.c b/modules/dbparser/pdbtool/pdbtool.c index a6b51578..b9001165 100644 --- a/modules/dbparser/pdbtool/pdbtool.c +++ b/modules/dbparser/pdbtool/pdbtool.c @@ -41,6 +41,7 @@ #include "logproto/logproto-text-server.h" #include "reloc.h" #include "pathutils.h" +#include "compat/openssl_support.h" #include #include -- 2.11.0