Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tls: add version-specific cipher suite options #3907

Merged
merged 9 commits into from Feb 28, 2022
3 changes: 2 additions & 1 deletion cmake/openssl_functions.cmake
Expand Up @@ -41,7 +41,8 @@ function (openssl_set_defines)
X509_get_extension_flags
DH_set0_pqg
BN_get_rfc3526_prime_2048
SSL_CTX_set_num_tickets)
SSL_CTX_set_num_tickets
SSL_CTX_set_ciphersuites)

foreach (symbol ${symbol_list})
string(TOUPPER ${symbol} SYMBOL_UPPERCASE)
Expand Down
3 changes: 2 additions & 1 deletion configure.ac
Expand Up @@ -1047,6 +1047,7 @@ CPPFLAGS_SAVE="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $OPENSSL_CFLAGS"

AC_CHECK_DECLS([SSL_CTX_get0_param],[], [], [[#include <openssl/ssl.h>]])
AC_CHECK_DECLS([SSL_CTX_set_ciphersuites],[], [], [[#include <openssl/ssl.h>]])
AC_CHECK_DECLS([X509_STORE_CTX_get0_cert],[], [], [[#include <openssl/ssl.h>]])
AC_CHECK_DECLS([X509_get_extension_flags], [], [], [[#include <openssl/x509v3.h>]])
AC_CHECK_DECLS([EVP_MD_CTX_reset], [], [], [[#include <openssl/evp.h>]])
Expand Down Expand Up @@ -1382,7 +1383,7 @@ if test "x$enable_http" != "xno" && test "x$with_libcurl" != "xno"; then
if test "$enable_http" = "yes"; then
old_CFLAGS=$CFLAGS
CFLAGS=$LIBCURL_CFLAGS
AC_CHECK_DECLS([CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1, CURL_SSLVERSION_TLSv1_2, CURL_SSLVERSION_TLSv1_3],
AC_CHECK_DECLS([CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1, CURL_SSLVERSION_TLSv1_2, CURL_SSLVERSION_TLSv1_3, CURLOPT_TLS13_CIPHERS],
[], [],
[[#include <curl/curl.h>]])
CFLAGS=$old_CFLAGS
Expand Down
49 changes: 41 additions & 8 deletions lib/tlscontext.c
Expand Up @@ -59,6 +59,7 @@ struct _TLSContext
gchar *crl_dir;
gchar *ca_file;
gchar *cipher_suite;
gchar *tls13_cipher_suite;
gchar *ecdh_curve_list;
gchar *sni;
SSL_CTX *ssl_ctx;
Expand Down Expand Up @@ -648,6 +649,20 @@ tls_context_setup_dh(TLSContext *self)
return ctx_dh_success;
}

static gboolean
tls_context_setup_cipher_suite(TLSContext *self)
{
if (self->cipher_suite && !SSL_CTX_set_cipher_list(self->ssl_ctx, self->cipher_suite))
return FALSE;

#if SYSLOG_NG_HAVE_DECL_SSL_CTX_SET_CIPHERSUITES
if (self->tls13_cipher_suite && !SSL_CTX_set_ciphersuites(self->ssl_ctx, self->tls13_cipher_suite))
return FALSE;
#endif

return TRUE;
}

static PKCS12 *
_load_pkcs12_file(TLSContext *self, const gchar *pkcs12_file)
{
Expand Down Expand Up @@ -808,11 +823,8 @@ tls_context_setup_context(TLSContext *self)
if (!tls_context_setup_dh(self))
goto error;

if (self->cipher_suite)
{
if (!SSL_CTX_set_cipher_list(self->ssl_ctx, self->cipher_suite))
goto error;
}
if (!tls_context_setup_cipher_suite(self))
goto error;

return TLS_CONTEXT_SETUP_OK;

Expand Down Expand Up @@ -891,6 +903,7 @@ _tls_context_free(TLSContext *self)
g_free(self->crl_dir);
g_free(self->ca_file);
g_free(self->cipher_suite);
g_free(self->tls13_cipher_suite);
g_free(self->ecdh_curve_list);
g_free(self->sni);
g_free(self->keylog_file_path);
Expand Down Expand Up @@ -1061,16 +1074,16 @@ tls_context_set_key_file(TLSContext *self, const gchar *key_file)
}

gboolean
tls_context_set_keylog_file(TLSContext *self, gchar *keylog_file_path)
tls_context_set_keylog_file(TLSContext *self, gchar *keylog_file_path, GError **error)
{
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
g_free(self->keylog_file_path);
msg_warning_once("WARNING: TLS keylog file has been set up, it should only be used during debugging sessions.",
evt_tag_str("keylog-file", keylog_file_path));
MrAnno marked this conversation as resolved.
Show resolved Hide resolved
msg_warning_once("WARNING: TLS keylog file has been set up, it should only be used during debugging sessions");
self->keylog_file_path = g_strdup(keylog_file_path);
SSL_CTX_set_keylog_callback(self->ssl_ctx, _dump_tls_keylog);
return TRUE;
#else
g_set_error(error, TLSCONTEXT_ERROR, TLSCONTEXT_UNSUPPORTED, "keylog-file() requires OpenSSL >= v1.1.1");
return FALSE;
#endif
}
Expand Down Expand Up @@ -1117,6 +1130,20 @@ tls_context_set_cipher_suite(TLSContext *self, const gchar *cipher_suite)
self->cipher_suite = g_strdup(cipher_suite);
}

gboolean
tls_context_set_tls13_cipher_suite(TLSContext *self, const gchar *tls13_cipher_suite, GError **error)
{
#if SYSLOG_NG_HAVE_DECL_SSL_CTX_SET_CIPHERSUITES
g_free(self->tls13_cipher_suite);
self->tls13_cipher_suite = g_strdup(tls13_cipher_suite);
return TRUE;
#else
g_set_error(error, TLSCONTEXT_ERROR, TLSCONTEXT_UNSUPPORTED,
"Setting TLS 1.3 ciphers is not supported with the OpenSSL version syslog-ng was compiled with");
return FALSE;
#endif
}

void
tls_context_set_ecdh_curve_list(TLSContext *self, const gchar *ecdh_curve_list)
{
Expand Down Expand Up @@ -1302,3 +1329,9 @@ tls_context_get_key_file(TLSContext *self)
{
return self->key_file;
}

GQuark
tls_context_error_quark(void)
{
return g_quark_from_static_string("tls-context-error-quark");
}
12 changes: 11 additions & 1 deletion lib/tlscontext.h
Expand Up @@ -92,6 +92,15 @@ typedef struct _TLSSession
} peer_info;
} TLSSession;


#define TLSCONTEXT_ERROR tls_context_error_quark()
GQuark tls_context_error_quark(void);

enum TLSContextError
{
TLSCONTEXT_UNSUPPORTED,
};

#define TMI_ALLOW_COMPRESS 0x1

void tls_session_set_verifier(TLSSession *self, TLSVerifier *verifier);
Expand All @@ -118,12 +127,13 @@ gint tls_context_get_verify_mode(const TLSContext *self);
void tls_context_set_verify_mode(TLSContext *self, gint verify_mode);
void tls_context_set_key_file(TLSContext *self, const gchar *key_file);
void tls_context_set_cert_file(TLSContext *self, const gchar *cert_file);
gboolean tls_context_set_keylog_file(TLSContext *self, gchar *keylog_file_path);
gboolean tls_context_set_keylog_file(TLSContext *self, gchar *keylog_file_path, GError **error);
void tls_context_set_pkcs12_file(TLSContext *self, const gchar *pkcs12_file);
void tls_context_set_ca_dir(TLSContext *self, const gchar *ca_dir);
void tls_context_set_crl_dir(TLSContext *self, const gchar *crl_dir);
void tls_context_set_ca_file(TLSContext *self, const gchar *ca_file);
void tls_context_set_cipher_suite(TLSContext *self, const gchar *cipher_suite);
gboolean tls_context_set_tls13_cipher_suite(TLSContext *self, const gchar *tls13_cipher_suite, GError **error);
void tls_context_set_ecdh_curve_list(TLSContext *self, const gchar *ecdh_curve_list);
void tls_context_set_dhparam_file(TLSContext *self, const gchar *dhparam_file);
void tls_context_set_sni(TLSContext *self, const gchar *sni);
Expand Down
35 changes: 29 additions & 6 deletions modules/afsocket/afsocket-grammar.ym
Expand Up @@ -187,6 +187,8 @@ systemd_syslog_grammar_set_source_driver(SystemDSyslogSourceDriver *sd)
%token KW_TRUSTED_KEYS
%token KW_TRUSTED_DN
%token KW_CIPHER_SUITE
%token KW_TLS12_AND_OLDER
%token KW_TLS13
%token KW_ECDH_CURVE_LIST
%token KW_SSL_OPTIONS
%token KW_SNI
Expand Down Expand Up @@ -806,9 +808,10 @@ tls_option
}
| KW_KEYLOG_FILE '(' string ')'
{
CHECK_ERROR(tls_context_set_keylog_file(last_tls_context, $3), @3, "keylog_file() requires OpenSSL >= v1.1.1");
free($3);
}
GError *error = NULL;
CHECK_ERROR_GERROR(tls_context_set_keylog_file(last_tls_context, $3, &error), @3, error, "Error setting keylog-file()");
free($3);
}
| KW_CERT_FILE '(' path_check ')'
{
tls_context_set_cert_file(last_tls_context, $3);
Expand Down Expand Up @@ -847,11 +850,13 @@ tls_option
{
tls_session_set_trusted_dn(last_tls_context, $3);
}
| KW_CIPHER_SUITE '(' string ')'
{
| KW_CIPHER_SUITE '(' tls_cipher_suites ')'
| KW_CIPHER_SUITE '(' string ')'
{
/* compat for specifying TLS 1.2-or-older ciphers */
tls_context_set_cipher_suite(last_tls_context, $3);
free($3);
}
}
| KW_ECDH_CURVE_LIST '(' string ')'
{
tls_context_set_ecdh_curve_list(last_tls_context, $3);
Expand All @@ -870,6 +875,24 @@ tls_option
}
;

tls_cipher_suites
: tls_cipher_suite tls_cipher_suites
|
;

tls_cipher_suite
: KW_TLS12_AND_OLDER '(' string ')'
{
tls_context_set_cipher_suite(last_tls_context, $3);
free($3);
}
| KW_TLS13 '(' string ')'
{
GError *error = NULL;
CHECK_ERROR_GERROR(tls_context_set_tls13_cipher_suite(last_tls_context, $3, &error), @3, error, "Error setting cipher-suite(tls13())");
free($3);
}
;

socket_option
: KW_SO_SNDBUF '(' nonnegative_integer ')'
Expand Down
2 changes: 2 additions & 0 deletions modules/afsocket/afsocket-parser.c
Expand Up @@ -56,6 +56,8 @@ static CfgLexerKeyword afsocket_keywords[] =
{ "trusted_keys", KW_TRUSTED_KEYS },
{ "trusted_dn", KW_TRUSTED_DN },
{ "cipher_suite", KW_CIPHER_SUITE },
{ "tls12_and_older", KW_TLS12_AND_OLDER },
{ "tls13", KW_TLS13 },
{ "ecdh_curve_list", KW_ECDH_CURVE_LIST },
{ "curve_list", KW_ECDH_CURVE_LIST, KWS_OBSOLETE, "ecdh_curve_list"},
{ "ssl_options", KW_SSL_OPTIONS },
Expand Down
1 change: 1 addition & 0 deletions modules/http/CMakeLists.txt
Expand Up @@ -57,6 +57,7 @@ curl_detect_compile_option(CURL_SSLVERSION_TLSv1_0)
curl_detect_compile_option(CURL_SSLVERSION_TLSv1_1)
curl_detect_compile_option(CURL_SSLVERSION_TLSv1_2)
curl_detect_compile_option(CURL_SSLVERSION_TLSv1_3)
curl_detect_compile_option(CURLOPT_TLS13_CIPHERS)

install(FILES ${HTTP_MODULE_DEV_HEADERS} DESTINATION include/syslog-ng/modules/http/)

Expand Down
22 changes: 22 additions & 0 deletions modules/http/http-grammar.ym
Expand Up @@ -64,6 +64,8 @@ HttpResponseHandler last_response_handler;
%token KW_CERT_FILE
%token KW_KEY_FILE
%token KW_CIPHER_SUITE
%token KW_TLS12_AND_OLDER
%token KW_TLS13
%token KW_PROXY
%token KW_USE_SYSTEM_CERT_STORE
%token KW_SSL_VERSION
Expand Down Expand Up @@ -170,6 +172,7 @@ http_tls_option
| KW_CA_FILE '(' path_check ')' { http_dd_set_ca_file(last_driver, $3); free($3); }
| KW_CERT_FILE '(' path_check ')' { http_dd_set_cert_file(last_driver, $3); free($3); }
| KW_KEY_FILE '(' path_secret ')' { http_dd_set_key_file(last_driver, $3); free($3); }
| KW_CIPHER_SUITE '(' tls_cipher_suites ')'
| KW_CIPHER_SUITE '(' string ')' { http_dd_set_cipher_suite(last_driver, $3); free($3); }
| KW_SSL_VERSION '(' string ')' { CHECK_ERROR(http_dd_set_ssl_version(last_driver, $3), @3,
"curl: unsupported SSL version: %s", $3);
Expand All @@ -188,6 +191,25 @@ http_tls_option
| KW_PEER_VERIFY '(' yesno ')' { http_dd_set_peer_verify(last_driver, $3); }
;

tls_cipher_suites
: tls_cipher_suite tls_cipher_suites
|
;

tls_cipher_suite
: KW_TLS12_AND_OLDER '(' string ')'
{
http_dd_set_cipher_suite(last_driver, $3);
free($3);
}
| KW_TLS13 '(' string ')'
{
CHECK_ERROR(http_dd_set_tls13_cipher_suite(last_driver, $3), @3,
"Error setting cipher-suite(tls13()), specifying TLS 1.3 ciphers is not supported with this libcurl version");
free($3);
}
;

/* INCLUDE_RULES */

%%
2 changes: 2 additions & 0 deletions modules/http/http-parser.c
Expand Up @@ -43,6 +43,8 @@ static CfgLexerKeyword http_keywords[] =
{ "cert_file", KW_CERT_FILE },
{ "key_file", KW_KEY_FILE },
{ "cipher_suite", KW_CIPHER_SUITE },
{ "tls12_and_older", KW_TLS12_AND_OLDER },
{ "tls13", KW_TLS13 },
{ "proxy", KW_PROXY },
{ "use_system_cert_store", KW_USE_SYSTEM_CERT_STORE },
{ "ssl_version", KW_SSL_VERSION },
Expand Down
5 changes: 5 additions & 0 deletions modules/http/http-worker.c
Expand Up @@ -135,6 +135,11 @@ _setup_static_options_in_curl(HTTPDestinationWorker *self)
if (owner->ciphers)
curl_easy_setopt(self->curl, CURLOPT_SSL_CIPHER_LIST, owner->ciphers);

#if SYSLOG_NG_HAVE_DECL_CURLOPT_TLS13_CIPHERS
if (owner->tls13_ciphers)
curl_easy_setopt(self->curl, CURLOPT_TLS13_CIPHERS, owner->tls13_ciphers);
#endif

if (owner->proxy)
curl_easy_setopt(self->curl, CURLOPT_PROXY, owner->proxy);

Expand Down
15 changes: 15 additions & 0 deletions modules/http/http.c
Expand Up @@ -173,6 +173,20 @@ http_dd_set_cipher_suite(LogDriver *d, const gchar *ciphers)
self->ciphers = g_strdup(ciphers);
}

gboolean
http_dd_set_tls13_cipher_suite(LogDriver *d, const gchar *tls13_ciphers)
alltilla marked this conversation as resolved.
Show resolved Hide resolved
{
#if SYSLOG_NG_HAVE_DECL_CURLOPT_TLS13_CIPHERS
HTTPDestinationDriver *self = (HTTPDestinationDriver *) d;

g_free(self->tls13_ciphers);
self->tls13_ciphers = g_strdup(tls13_ciphers);
return TRUE;
#else
return FALSE;
#endif
}

void
http_dd_set_proxy(LogDriver *d, const gchar *proxy)
{
Expand Down Expand Up @@ -392,6 +406,7 @@ http_dd_free(LogPipe *s)
g_free(self->cert_file);
g_free(self->key_file);
g_free(self->ciphers);
g_free(self->tls13_ciphers);
g_free(self->proxy);
g_list_free_full(self->headers, g_free);
http_load_balancer_free(self->load_balancer);
Expand Down
2 changes: 2 additions & 0 deletions modules/http/http.h
Expand Up @@ -49,6 +49,7 @@ typedef struct
gchar *cert_file;
gchar *key_file;
gchar *ciphers;
gchar *tls13_ciphers;
gchar *proxy;
GString *body_prefix;
GString *body_suffix;
Expand Down Expand Up @@ -81,6 +82,7 @@ void http_dd_set_ca_file(LogDriver *d, const gchar *ca_file);
void http_dd_set_cert_file(LogDriver *d, const gchar *cert_file);
void http_dd_set_key_file(LogDriver *d, const gchar *key_file);
void http_dd_set_cipher_suite(LogDriver *d, const gchar *ciphers);
gboolean http_dd_set_tls13_cipher_suite(LogDriver *d, const gchar *tls13_ciphers);
void http_dd_set_proxy(LogDriver *d, const gchar *proxy);
gboolean http_dd_set_ssl_version(LogDriver *d, const gchar *value);
void http_dd_set_peer_verify(LogDriver *d, gboolean verify);
Expand Down
16 changes: 16 additions & 0 deletions modules/mqtt/mqtt-grammar.ym
Expand Up @@ -66,6 +66,8 @@ MQTTClientOptions *last_options;
%token KW_CERT_FILE
%token KW_KEY_FILE
%token KW_CIPHER_SUITE
%token KW_TLS12_AND_OLDER
%token KW_TLS13
MrAnno marked this conversation as resolved.
Show resolved Hide resolved
%token KW_USE_SYSTEM_CERT_STORE
%token KW_SSL_VERSION
%token KW_PEER_VERIFY
Expand Down Expand Up @@ -142,6 +144,7 @@ mqtt_tls_option
| KW_CA_FILE '(' path_check ')' { mqtt_client_options_set_ca_file(last_options, $3); free($3); }
| KW_CERT_FILE '(' path_check ')' { mqtt_client_options_set_cert_file(last_options, $3); free($3); }
| KW_KEY_FILE '(' path_secret ')' { mqtt_client_options_set_key_file(last_options, $3); free($3); }
| KW_CIPHER_SUITE '(' tls_cipher_suites ')'
| KW_CIPHER_SUITE '(' string ')' { mqtt_client_options_set_cipher_suite(last_options, $3); free($3); }
| KW_SSL_VERSION '(' string ')' { CHECK_ERROR(mqtt_client_options_set_ssl_version(last_options, $3), @3,
"mqtt: unsupported SSL version: %s", $3);
Expand All @@ -150,6 +153,19 @@ mqtt_tls_option
| KW_USE_SYSTEM_CERT_STORE '(' yesno ')' { mqtt_client_options_use_system_cert_store(last_options, $3); }
;

tls_cipher_suites
: tls_cipher_suite tls_cipher_suites
|
;

tls_cipher_suite
: KW_TLS12_AND_OLDER '(' string ')'
{
mqtt_client_options_set_cipher_suite(last_options, $3);
free($3);
}
;

/* INCLUDE_RULES */

%%
2 changes: 2 additions & 0 deletions modules/mqtt/mqtt-parser.c
Expand Up @@ -48,6 +48,8 @@ static CfgLexerKeyword mqtt_keywords[] =
{ "cert_file", KW_CERT_FILE },
{ "key_file", KW_KEY_FILE },
{ "cipher_suite", KW_CIPHER_SUITE },
{ "tls12_and_older", KW_TLS12_AND_OLDER },
{ "tls13", KW_TLS13 },
{ "peer_verify", KW_PEER_VERIFY },
{ "use_system_cert_store", KW_USE_SYSTEM_CERT_STORE },
{ "ssl_version", KW_SSL_VERSION },
Expand Down