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 b49622bb1a037bd5c4f7460cdb454c37fc2cde0f
parent 523bc521c734cb3b3b3b3977d5c27adaaadd3a66
Author: Joris Vink <joris@coders.se>
Date:   Sat, 18 Oct 2014 02:32:05 +0200

Add CRL support.

Allow Kore to use per domain CRLs when requiring client certificates.
The require_client_cert configuration option has been renamed to a more
sane client_certificates and can optionally take a second argument
which is the CRL in pem format.

You'll need a restart in case the CRLs get updated.

Diffstat:
conf/kore.conf.example | 8++++----
includes/kore.h | 2++
src/config.c | 11+++++++----
src/domain.c | 42+++++++++++++++++++++++++++++++++++++++++-
src/worker.c | 2++
5 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/conf/kore.conf.example b/conf/kore.conf.example @@ -116,9 +116,9 @@ authentication auth_example { # # accesslog # - File where all requests are logged. -# require_client_cert -# - Asks the client to present a certificate -# matching the CA given to require_client_cert +# client_certificates [CA] [optional CRL] +# - Require client certificates to be sent for the given +# CA with an optional CRL file. # # Handlers # @@ -176,7 +176,7 @@ domain localhost { # certfile cert/other/server.crt # certkey cert/other/server.key # accesslog /var/log/other_kore_access.log -# require_client_cert cert/other/ca.crt +# client_certificates cert/other/ca.crt # static /css/style.css serve_style_css # static / serve_index diff --git a/includes/kore.h b/includes/kore.h @@ -263,6 +263,7 @@ struct kore_domain { char *certfile; char *certkey; char *cafile; + char *crlfile; int accesslog; SSL_CTX *ssl_ctx; TAILQ_HEAD(, kore_module_handle) handlers; @@ -436,6 +437,7 @@ void kore_module_onload(void); int kore_module_loaded(void); void kore_domain_closelogs(void); void *kore_module_getsym(const char *); +void kore_domain_load_crl(void); void kore_module_load(const char *, const char *); void kore_domain_sslstart(struct kore_domain *); int kore_module_handler_new(const char *, const char *, diff --git a/src/config.c b/src/config.c @@ -55,7 +55,7 @@ static int configure_http_keepalive_time(char **); static int configure_validator(char **); static int configure_params(char **); static int configure_validate(char **); -static int configure_require_client_cert(char **); +static int configure_client_certificates(char **); static int configure_authentication(char **); static int configure_authentication_uri(char **); static int configure_authentication_type(char **); @@ -92,7 +92,7 @@ static struct { { "accesslog", configure_accesslog }, { "certfile", configure_certfile }, { "certkey", configure_certkey }, - { "require_client_cert", configure_require_client_cert }, + { "client_certificates", configure_client_certificates }, { "http_header_max", configure_http_header_max }, { "http_body_max", configure_http_body_max }, { "http_hsts_enable", configure_http_hsts_enable }, @@ -370,10 +370,10 @@ configure_handler(char **argv) } static int -configure_require_client_cert(char **argv) +configure_client_certificates(char **argv) { if (current_domain == NULL) { - printf("missing domain page require_client_cert\n"); + printf("missing domain for require_client_cert\n"); return (KORE_RESULT_ERROR); } @@ -389,6 +389,9 @@ configure_require_client_cert(char **argv) } current_domain->cafile = kore_strdup(argv[1]); + if (argv[2] != NULL) + current_domain->crlfile = kore_strdup(argv[2]); + return (KORE_RESULT_OK); } diff --git a/src/domain.c b/src/domain.c @@ -24,6 +24,8 @@ struct kore_domain_h domains; struct kore_domain *primary_dom = NULL; DH *ssl_dhparam = NULL; +static void domain_load_crl(struct kore_domain *); + void kore_domain_init(void) { @@ -61,7 +63,6 @@ kore_domain_sslstart(struct kore_domain *dom) { #if !defined(KORE_BENCHMARK) STACK_OF(X509_NAME) *certs; - #if !defined(OPENSSL_NO_EC) EC_KEY *ecdh; #endif @@ -164,3 +165,42 @@ kore_domain_closelogs(void) TAILQ_FOREACH(dom, &domains, list) close(dom->accesslog); } + +void +kore_domain_load_crl(void) +{ + struct kore_domain *dom; + + TAILQ_FOREACH(dom, &domains, list) + domain_load_crl(dom); +} + +static void +domain_load_crl(struct kore_domain *dom) +{ + X509_STORE *store; + + ERR_clear_error(); + + if (dom->cafile == NULL) + return; + + if (dom->crlfile == NULL) { + kore_log(LOG_WARNING, "WARNING: Running without CRL"); + return; + } + + if ((store = SSL_CTX_get_cert_store(dom->ssl_ctx)) == NULL) { + kore_log(LOG_ERR, "SSL_CTX_get_cert_store(): %S", ssl_errno_s); + return; + } + + if (!X509_STORE_load_locations(store, dom->crlfile, NULL)) { + kore_log(LOG_ERR, "X509_STORE_load_locations(): %s", + ssl_errno_s); + return; + } + + X509_STORE_set_flags(store, + X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); +} diff --git a/src/worker.c b/src/worker.c @@ -229,6 +229,7 @@ kore_worker_entry(struct kore_worker *kw) net_init(); http_init(); kore_connection_init(); + kore_domain_load_crl(); TAILQ_INIT(&disconnected); TAILQ_INIT(&worker_clients); @@ -255,6 +256,7 @@ kore_worker_entry(struct kore_worker *kw) kore_module_reload(1); else if (sig_recv == SIGQUIT || sig_recv == SIGINT) quit = 1; + sig_recv = 0; }