From: Eero Aaltonen <eero.aalto...@vaisala.com> Allow configuring trusted CAs to a directory with certificates and hash symlinks generated with `openssl rehash`.
Signed-off-by: Eero Aaltonen <eero.aalto...@vaisala.com> --- src/event/ngx_event_openssl.c | 24 +++++++++++++++++------- src/event/ngx_event_openssl.h | 2 +- src/http/modules/ngx_http_grpc_module.c | 1 + src/http/modules/ngx_http_proxy_module.c | 1 + src/http/modules/ngx_http_ssl_module.c | 15 +++++++++++++-- src/http/modules/ngx_http_ssl_module.h | 1 + src/http/modules/ngx_http_uwsgi_module.c | 1 + src/mail/ngx_mail_ssl_module.c | 5 +++-- src/stream/ngx_stream_proxy_module.c | 1 + src/stream/ngx_stream_ssl_module.c | 5 +++-- src/stream/ngx_stream_ssl_module.h | 1 + 11 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index d762d6b..3da406c 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -870,24 +870,31 @@ ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, - ngx_int_t depth) + ngx_str_t *ca_dir, ngx_int_t depth) { STACK_OF(X509_NAME) *list; + char *ca_file = NULL; + char *ca_path = NULL; SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback); SSL_CTX_set_verify_depth(ssl->ctx, depth); - if (cert->len == 0) { + if (cert->len == 0 && ca_dir->len == 0) { return NGX_OK; } - if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { - return NGX_ERROR; + if (ca_dir->len != 0) { + ca_path = ca_dir->data; + } + if (cert->len != 0) { + ca_file = cert->data; + if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { + return NGX_ERROR; + } } - if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL) - == 0) + if (SSL_CTX_load_verify_locations(ssl->ctx, ca_file, ca_path) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_load_verify_locations(\"%s\") failed", @@ -902,6 +909,10 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ERR_clear_error(); + if (cert->len == 0) { // TODO: load CAs from ca_dir? + return NGX_OK; + } + list = SSL_load_client_CA_file((char *) cert->data); if (list == NULL) { @@ -915,7 +926,6 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, return NGX_OK; } - ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 329760d..0a3481e 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -179,7 +179,7 @@ ngx_int_t ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, ngx_uint_t prefer_server_ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *cert, ngx_int_t depth); + ngx_str_t *cert, ngx_str_t *ca_dir, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c index 53bc547..d5728e6 100644 --- a/src/http/modules/ngx_http_grpc_module.c +++ b/src/http/modules/ngx_http_grpc_module.c @@ -35,6 +35,7 @@ typedef struct { ngx_uint_t ssl_protocols; ngx_str_t ssl_ciphers; ngx_uint_t ssl_verify_depth; + ngx_str_t ssl_ca_dir; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; ngx_str_t ssl_certificate; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index a63c3ed..6dda907 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -122,6 +122,7 @@ typedef struct { ngx_uint_t ssl_protocols; ngx_str_t ssl_ciphers; ngx_uint_t ssl_verify_depth; + ngx_str_t ssl_ca_dir; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; ngx_str_t ssl_certificate; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index a47d696..c80b614 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -182,6 +182,13 @@ static ngx_command_t ngx_http_ssl_commands[] = { offsetof(ngx_http_ssl_srv_conf_t, client_certificate), NULL }, + { ngx_string("ssl_client_ca_dir"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_ssl_srv_conf_t, client_ca_dir), + NULL }, + { ngx_string("ssl_trusted_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -609,6 +616,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf) * sscf->dhparam = { 0, NULL }; * sscf->ecdh_curve = { 0, NULL }; * sscf->client_certificate = { 0, NULL }; + * sscf->client_ca_dir = { 0, NULL }; * sscf->trusted_certificate = { 0, NULL }; * sscf->crl = { 0, NULL }; * sscf->ciphers = { 0, NULL }; @@ -690,6 +698,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate, ""); + ngx_conf_merge_str_value(conf->client_ca_dir, + prev->client_ca_dir, ""); ngx_conf_merge_str_value(conf->trusted_certificate, prev->trusted_certificate, ""); ngx_conf_merge_str_value(conf->crl, prev->crl, ""); @@ -840,14 +850,15 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) if (conf->verify) { - if (conf->client_certificate.len == 0 && conf->verify != 3) { + if (conf->verify != 3 && conf->client_certificate.len == 0 && conf->client_ca_dir.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no ssl_client_certificate for ssl_verify_client"); + "ssl_verify_client needs ssl_client_certificate or ssl_client_ca_dir"); return NGX_CONF_ERROR; } if (ngx_ssl_client_certificate(cf, &conf->ssl, &conf->client_certificate, + &conf->client_ca_dir, conf->verify_depth) != NGX_OK) { diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h index 7ab0f7e..e90b79b 100644 --- a/src/http/modules/ngx_http_ssl_module.h +++ b/src/http/modules/ngx_http_ssl_module.h @@ -43,6 +43,7 @@ typedef struct { ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; + ngx_str_t client_ca_dir; ngx_str_t trusted_certificate; ngx_str_t crl; diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c index 1334f44..7e13a08 100644 --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -52,6 +52,7 @@ typedef struct { ngx_uint_t ssl_protocols; ngx_str_t ssl_ciphers; ngx_uint_t ssl_verify_depth; + ngx_str_t ssl_ca_dir; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; ngx_str_t ssl_certificate; diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c index 7eae83e..062d4d7 100644 --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -403,14 +403,15 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) if (conf->verify) { - if (conf->client_certificate.len == 0 && conf->verify != 3) { + if (conf->verify != 3 && conf->client_certificate.len == 0 && conf->client_ca_dir.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no ssl_client_certificate for ssl_verify_client"); + "ssl_verify_client needs ssl_client_certificate or ssl_client_ca_dir"); return NGX_CONF_ERROR; } if (ngx_ssl_client_certificate(cf, &conf->ssl, &conf->client_certificate, + &conf->client_ca_dir, conf->verify_depth) != NGX_OK) { diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index 01cda7a..1ad4ceb 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -44,6 +44,7 @@ typedef struct { ngx_flag_t ssl_verify; ngx_uint_t ssl_verify_depth; + ngx_str_t ssl_ca_dir; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; ngx_str_t ssl_certificate; diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c index d8c0471..adaa825 100644 --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -761,14 +761,15 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) if (conf->verify) { - if (conf->client_certificate.len == 0 && conf->verify != 3) { + if (conf->verify != 3 && conf->client_certificate.len == 0 && conf->client_ca_dir.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no ssl_client_certificate for ssl_verify_client"); + "ssl_verify_client needs ssl_client_certificate or ssl_client_ca_dir"); return NGX_CONF_ERROR; } if (ngx_ssl_client_certificate(cf, &conf->ssl, &conf->client_certificate, + &conf->client_ca_dir, conf->verify_depth) != NGX_OK) { diff --git a/src/stream/ngx_stream_ssl_module.h b/src/stream/ngx_stream_ssl_module.h index c6e24be..607146e 100644 --- a/src/stream/ngx_stream_ssl_module.h +++ b/src/stream/ngx_stream_ssl_module.h @@ -40,6 +40,7 @@ typedef struct { ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; + ngx_str_t client_ca_dir; ngx_str_t trusted_certificate; ngx_str_t crl; -- 2.25.1 _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel