kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 384bc8fdd6a8a49a4764060617839311a1175243
parent 48495feb43be8a172ec78a666698b6734e13e5dd
Author: Joris Vink <joris@coders.se>
Date:   Wed,  6 May 2015 10:59:43 +0200

Default to only TLSv1.2 from now on.

Add configuration setting tls_version to specify if you
either want TLSv1.2 or TLSv1.0 or both.

The configuration options ssl_cipher and ssl_dhparam
have changed name to tls_cipher and tls_dhparam. There is
no fallback so you might have to update your configs.

Diffstat:
conf/kore.conf.example | 13++++++++++---
examples/cpp/conf/cpp.conf | 2+-
examples/generic/conf/generic.conf | 2+-
examples/headers/conf/headers.conf | 2+-
examples/integers/conf/integers.conf | 2+-
examples/json_yajl/conf/json_yajl.conf | 2+-
examples/ktunnel/conf/ktunnel.conf | 2+-
examples/parameters/conf/parameters.conf | 2+-
examples/pgsql/conf/pgsql.conf | 2+-
examples/tasks/conf/tasks.conf | 2+-
examples/video_stream/conf/video_stream.conf | 2+-
examples/websocket/conf/websocket.conf | 2+-
includes/kore.h | 13+++++++++----
src/cli.c | 2+-
src/config.c | 62++++++++++++++++++++++++++++++++++++++++----------------------
src/domain.c | 38+++++++++++++++++++++++++++++---------
src/kore.c | 10+++++-----
17 files changed, 105 insertions(+), 55 deletions(-)

diff --git a/conf/kore.conf.example b/conf/kore.conf.example @@ -80,12 +80,19 @@ validator v_regex regex ^/test/[a-z]*$ validator v_number regex ^[0-9]*$ validator v_session function v_session_validate -# Specify the SSL ciphers that will be used. -#ssl_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA +# Specify what TLS version to be used. Default is TLSv1.2 +# Allowed values: +# 1.2 for TLSv1.2 (default) +# 1.0 for TLSv1.0 +# both for TLSv1.0 and TLSv1.2 +#tls_version 1.2 + +# Specify the TLS ciphers that will be used. +#tls_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA # If you wish to use EDH / ECDH specify a file containing # a generated DH key (See OpenSSL dhparam). -#ssl_dhparam dh2048.pem +#tls_dhparam dh2048.pem # Specify the amount of seconds a SPDY connection is kept open. # You can keep it open indefinately by setting this to 0. diff --git a/examples/cpp/conf/cpp.conf b/examples/cpp/conf/cpp.conf @@ -2,7 +2,7 @@ bind 127.0.0.1 8888 load ./cpp.so -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem domain 127.0.0.1 { certfile cert/server.crt diff --git a/examples/generic/conf/generic.conf b/examples/generic/conf/generic.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./generic.so example_load -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem validator v_example function v_example_func validator v_regex regex ^/test/[a-z]*$ diff --git a/examples/headers/conf/headers.conf b/examples/headers/conf/headers.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./headers.so -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem domain 127.0.0.1 { certfile cert/server.crt diff --git a/examples/integers/conf/integers.conf b/examples/integers/conf/integers.conf @@ -6,7 +6,7 @@ load ./integers.so workers 2 worker_max_connections 5000 -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem validator v_id regex ^-?[0-9]*$ diff --git a/examples/json_yajl/conf/json_yajl.conf b/examples/json_yajl/conf/json_yajl.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./json_yajl.so -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem domain 127.0.0.1 { certfile cert/server.crt diff --git a/examples/ktunnel/conf/ktunnel.conf b/examples/ktunnel/conf/ktunnel.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./ktunnel.so -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem # Regexes here are incorrect. validator v_host regex ^.*$ diff --git a/examples/parameters/conf/parameters.conf b/examples/parameters/conf/parameters.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./parameters.so -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem # The validator used to validate the 'id' parameter # defined below. We'll use a simple regex to make sure diff --git a/examples/pgsql/conf/pgsql.conf b/examples/pgsql/conf/pgsql.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./pgsql.so init -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem http_keepalive_time 0 diff --git a/examples/tasks/conf/tasks.conf b/examples/tasks/conf/tasks.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./tasks.so -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem validator v_user regex ^[a-z]*$ diff --git a/examples/video_stream/conf/video_stream.conf b/examples/video_stream/conf/video_stream.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./video_stream.so init -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem spdy_idle_time 600 http_keepalive_time 600 diff --git a/examples/websocket/conf/websocket.conf b/examples/websocket/conf/websocket.conf @@ -3,7 +3,7 @@ bind 127.0.0.1 8888 load ./websocket.so -ssl_dhparam dh2048.pem +tls_dhparam dh2048.pem websocket_maxframe 65536 websocket_timeout 20 diff --git a/includes/kore.h b/includes/kore.h @@ -57,6 +57,10 @@ extern int daemon(int, int); #define KORE_VERSION_PATCH 3 #define KORE_VERSION_STATE "rc1" +#define KORE_TLS_VERSION_1_2 0 +#define KORE_TLS_VERSION_1_0 1 +#define KORE_TLS_VERSION_BOTH 2 + #define errno_s strerror(errno) #define ssl_errno_s ERR_error_string(ERR_get_error(), NULL) @@ -351,8 +355,9 @@ extern char *chroot_path; extern char *runas_user; extern char *kore_pidfile; extern char *config_file; -extern char *kore_ssl_cipher_list; -extern DH *ssl_dhparam; +extern char *kore_tls_cipher_list; +extern int tls_version; +extern DH *tls_dhparam; extern u_int8_t nlisteners; extern u_int64_t spdy_idle_time; @@ -416,9 +421,9 @@ u_int64_t kore_timer_run(u_int64_t); void kore_timer_add(void (*cb)(u_int64_t, u_int64_t), u_int64_t, int); -int kore_ssl_sni_cb(SSL *, int *, void *); +int kore_tls_sni_cb(SSL *, int *, void *); int kore_server_bind(const char *, const char *); -int kore_ssl_npn_cb(SSL *, const u_char **, unsigned int *, void *); +int kore_tls_npn_cb(SSL *, const u_char **, unsigned int *, void *); void kore_connection_init(void); struct connection *kore_connection_new(void *); diff --git a/src/cli.c b/src/cli.c @@ -161,7 +161,7 @@ static const char *config_data = "bind\t\t127.0.0.1 8888\n" "load\t\t./%s.so\n" #if !defined(KORE_BENCHMARK) - "ssl_dhparam\tdh2048.pem\n" + "tls_dhparam\tdh2048.pem\n" #endif "\n" "domain 127.0.0.1 {\n" diff --git a/src/config.c b/src/config.c @@ -46,9 +46,9 @@ static int configure_rlimit_nofiles(char **); static int configure_max_connections(char **); static int configure_accept_treshold(char **); static int configure_set_affinity(char **); -static int configure_ssl_cipher(char **); -static int configure_ssl_dhparam(char **); -static int configure_ssl_no_compression(char **); +static int configure_tls_version(char **); +static int configure_tls_cipher(char **); +static int configure_tls_dhparam(char **); static int configure_spdy_idle_time(char **); static int configure_http_header_max(char **); static int configure_http_body_max(char **); @@ -84,9 +84,9 @@ static struct { { "load", configure_load }, { "static", configure_handler }, { "dynamic", configure_handler }, - { "ssl_cipher", configure_ssl_cipher }, - { "ssl_dhparam", configure_ssl_dhparam }, - { "ssl_no_compression", configure_ssl_no_compression }, + { "tls_version", configure_tls_version }, + { "tls_cipher", configure_tls_cipher }, + { "tls_dhparam", configure_tls_dhparam }, { "spdy_idle_time", configure_spdy_idle_time }, { "domain", configure_domain }, { "chroot", configure_chroot }, @@ -220,6 +220,11 @@ kore_parse_config_file(char *fpath) } } + if (config_names[i].name == NULL) { + printf("unknown configuration option on line %d\n", + lineno); + } + lineno++; } @@ -258,22 +263,42 @@ configure_load(char **argv) } static int -configure_ssl_cipher(char **argv) +configure_tls_version(char **argv) { if (argv[1] == NULL) return (KORE_RESULT_ERROR); - if (strcmp(kore_ssl_cipher_list, KORE_DEFAULT_CIPHER_LIST)) { - kore_debug("duplicate ssl_cipher directive specified"); + if (!strcmp(argv[1], "1.2")) { + tls_version = KORE_TLS_VERSION_1_2; + } else if (!strcmp(argv[1], "1.0")) { + tls_version = KORE_TLS_VERSION_1_0; + } else if (!strcmp(argv[1], "both")) { + tls_version = KORE_TLS_VERSION_BOTH; + } else { + printf("unknown value for tls_version: %s\n", argv[1]); return (KORE_RESULT_ERROR); } - kore_ssl_cipher_list = kore_strdup(argv[1]); return (KORE_RESULT_OK); } static int -configure_ssl_dhparam(char **argv) +configure_tls_cipher(char **argv) +{ + if (argv[1] == NULL) + return (KORE_RESULT_ERROR); + + if (strcmp(kore_tls_cipher_list, KORE_DEFAULT_CIPHER_LIST)) { + kore_debug("duplicate tls_cipher directive specified"); + return (KORE_RESULT_ERROR); + } + + kore_tls_cipher_list = kore_strdup(argv[1]); + return (KORE_RESULT_OK); +} + +static int +configure_tls_dhparam(char **argv) { #if !defined(KORE_BENCHMARK) BIO *bio; @@ -281,8 +306,8 @@ configure_ssl_dhparam(char **argv) if (argv[1] == NULL) return (KORE_RESULT_ERROR); - if (ssl_dhparam != NULL) { - kore_debug("duplicate ssl_dhparam directive specified"); + if (tls_dhparam != NULL) { + kore_debug("duplicate tls_dhparam directive specified"); return (KORE_RESULT_ERROR); } @@ -291,10 +316,10 @@ configure_ssl_dhparam(char **argv) return (KORE_RESULT_ERROR); } - ssl_dhparam = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + tls_dhparam = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); - if (ssl_dhparam == NULL) { + if (tls_dhparam == NULL) { printf("PEM_read_bio_DHparams(): %s\n", ssl_errno_s); return (KORE_RESULT_ERROR); } @@ -303,13 +328,6 @@ configure_ssl_dhparam(char **argv) } static int -configure_ssl_no_compression(char **argv) -{ - printf("ssl_no_compression is deprecated, and always on by default\n"); - return (KORE_RESULT_OK); -} - -static int configure_spdy_idle_time(char **argv) { int err; diff --git a/src/domain.c b/src/domain.c @@ -22,7 +22,8 @@ struct kore_domain_h domains; struct kore_domain *primary_dom = NULL; -DH *ssl_dhparam = NULL; +DH *tls_dhparam = NULL; +int tls_version = KORE_TLS_VERSION_1_2; static void domain_load_crl(struct kore_domain *); @@ -69,13 +70,28 @@ kore_domain_sslstart(struct kore_domain *dom) #if !defined(KORE_BENCHMARK) STACK_OF(X509_NAME) *certs; X509_STORE *store; + const SSL_METHOD *method; #if !defined(OPENSSL_NO_EC) EC_KEY *ecdh; #endif kore_debug("kore_domain_sslstart(%s)", dom->domain); - dom->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); + switch (tls_version) { + case KORE_TLS_VERSION_1_2: + method = TLSv1_2_server_method(); + break; + case KORE_TLS_VERSION_1_0: + method = TLSv1_server_method(); + break; + case KORE_TLS_VERSION_BOTH: + method = SSLv23_server_method(); + break; + default: + fatal("unknown tls_version: %d", tls_version); + } + + dom->ssl_ctx = SSL_CTX_new(method); if (dom->ssl_ctx == NULL) fatal("kore_domain_sslstart(): SSL_ctx_new(): %s", ssl_errno_s); if (!SSL_CTX_use_certificate_chain_file(dom->ssl_ctx, dom->certfile)) { @@ -92,10 +108,10 @@ kore_domain_sslstart(struct kore_domain *dom) if (!SSL_CTX_check_private_key(dom->ssl_ctx)) fatal("Public/Private key for %s do not match", dom->domain); - if (ssl_dhparam == NULL) + if (tls_dhparam == NULL) fatal("No DH parameters given"); - SSL_CTX_set_tmp_dh(dom->ssl_ctx, ssl_dhparam); + SSL_CTX_set_tmp_dh(dom->ssl_ctx, tls_dhparam); SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_DH_USE); #if !defined(OPENSSL_NO_EC) @@ -142,14 +158,18 @@ kore_domain_sslstart(struct kore_domain *dom) #endif SSL_CTX_set_mode(dom->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); - SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_SSLv2); - SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_SSLv3); + if (tls_version == KORE_TLS_VERSION_BOTH) { + SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_SSLv2); + SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_SSLv3); + SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_TLSv1_1); + } + SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - SSL_CTX_set_cipher_list(dom->ssl_ctx, kore_ssl_cipher_list); + SSL_CTX_set_cipher_list(dom->ssl_ctx, kore_tls_cipher_list); - SSL_CTX_set_tlsext_servername_callback(dom->ssl_ctx, kore_ssl_sni_cb); + SSL_CTX_set_tlsext_servername_callback(dom->ssl_ctx, kore_tls_sni_cb); SSL_CTX_set_next_protos_advertised_cb(dom->ssl_ctx, - kore_ssl_npn_cb, NULL); + kore_tls_npn_cb, NULL); kore_mem_free(dom->certfile); kore_mem_free(dom->certkey); diff --git a/src/kore.c b/src/kore.c @@ -36,7 +36,7 @@ char *runas_user = NULL; char *chroot_path = NULL; u_int32_t kore_socket_backlog = 5000; char *kore_pidfile = KORE_PIDFILE_DEFAULT; -char *kore_ssl_cipher_list = KORE_DEFAULT_CIPHER_LIST; +char *kore_tls_cipher_list = KORE_DEFAULT_CIPHER_LIST; static void usage(void); static void version(void); @@ -169,9 +169,9 @@ main(int argc, char *argv[]) #if !defined(KORE_BENCHMARK) int -kore_ssl_npn_cb(SSL *ssl, const u_char **data, unsigned int *len, void *arg) +kore_tls_npn_cb(SSL *ssl, const u_char **data, unsigned int *len, void *arg) { - kore_debug("kore_ssl_npn_cb(): sending protocols"); + kore_debug("kore_tls_npn_cb(): sending protocols"); *data = (const unsigned char *)KORE_SSL_PROTO_STRING; *len = strlen(KORE_SSL_PROTO_STRING); @@ -180,13 +180,13 @@ kore_ssl_npn_cb(SSL *ssl, const u_char **data, unsigned int *len, void *arg) } int -kore_ssl_sni_cb(SSL *ssl, int *ad, void *arg) +kore_tls_sni_cb(SSL *ssl, int *ad, void *arg) { struct kore_domain *dom; const char *sname; sname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - kore_debug("kore_ssl_sni_cb(): received host %s", sname); + kore_debug("kore_tls_sni_cb(): received host %s", sname); if (sname != NULL && (dom = kore_domain_lookup(sname)) != NULL) { kore_debug("kore_ssl_sni_cb(): Using %s CTX", sname);