[RFC][PATCH 1/1] Add option to use directory for trusted CAs
eero.aaltonen at vaisala.com
eero.aaltonen at vaisala.com
Fri Jul 7 15:02:15 UTC 2023
From: Eero Aaltonen <eero.aaltonen at vaisala.com>
Allow configuring trusted CAs to a directory with certificates and hash
symlinks generated with `openssl rehash`.
Signed-off-by: Eero Aaltonen <eero.aaltonen at 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
More information about the nginx-devel
mailing list