Hello, We have our own independent CA hierarchy, complete with client certificates for servers and staff. When a server (or staff member) is repurposed or decommissioned, we need to be able to revoke their certificate - we do this by maintaining sets of CRLs.
Unfortunately, due to flaws in this hierarchy, getting a complete CRL chain for each CA we have is difficult. This means client certs we would consider valid are rejected as Nginx sets 'X509_V_FLAG_CRL_CHECK_ALL' on the X509 store when the 'ssl_crl' directive is used. In the Apache world we get around this by using the 'SSLCARevocationCheck leaf' option. It would be nice to be able to control this flag, if only to work around broken CRL chains. I've noticed a variant of this problem has been discussed before (see trac issue #1094 and "[PATCH] SSL: Added crl_check_mode", March 2017) and a patch submitted. Before I knew of this, I wrote my own, roughly equivalent patch (see attached). I haven't explicitly tested the stream or mail changes, but the test suite does pass with these modules+ssl enabled. Is there any possibility of having one of these patches incorporated? Thanks, Elliot. ----------------------------- http://www.bbc.co.uk This e-mail (and any attachments) is confidential and may contain personal views which are not the views of the BBC unless specifically stated. If you have received it in error, please delete it from your system. Do not use, copy or disclose the information in any way nor act in reliance on it and notify the sender immediately. Please note that the BBC monitors e-mails sent or received. Further communication will signify your consent to this. -----------------------------
# HG changeset patch # User Elliot Thomas <elliot.tho...@bbc.co.uk> # Date 1491387954 -3600 # Wed Apr 05 11:25:54 2017 +0100 # Node ID 00b5a781cee0ab9fc407b699fae594797db96ace # Parent 29ba1d6a2da9320e68ef2b7a2516c4c424672ea8 SSL: add crl_check_all directive for controlling CRL verification. This allows the X509_V_FLAG_CRL_CHECK_ALL to be controlled, supporting 'leaf only' CRL verification in addition to full chain verification (default). This change adds *ssl_crl_check_all directives to the following modules: - ngx_http_proxy_module - ngx_http_ssl_module - ngx_http_uwsgi_module - ngx_mail_ssl_module - ngx_stream_proxy_module - ngx_stream_ssl_module diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Tue Apr 04 18:01:57 2017 +0300 +++ b/src/event/ngx_event_openssl.c Wed Apr 05 11:25:54 2017 +0100 @@ -737,7 +737,7 @@ ngx_int_t -ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl) +ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl, ngx_uint_t check_all) { X509_STORE *store; X509_LOOKUP *lookup; @@ -775,7 +775,8 @@ } X509_STORE_set_flags(store, - X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + X509_V_FLAG_CRL_CHECK | + (check_all ? X509_V_FLAG_CRL_CHECK_ALL : 0)); return NGX_OK; } diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Tue Apr 04 18:01:57 2017 +0300 +++ b/src/event/ngx_event_openssl.h Wed Apr 05 11:25:54 2017 +0100 @@ -151,7 +151,8 @@ ngx_str_t *cert, 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); +ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl, + ngx_uint_t check_all); ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Tue Apr 04 18:01:57 2017 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Wed Apr 05 11:25:54 2017 +0100 @@ -97,6 +97,7 @@ ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; + ngx_flag_t ssl_crl_check_all; ngx_str_t ssl_certificate; ngx_str_t ssl_certificate_key; ngx_array_t *ssl_passwords; @@ -693,6 +694,13 @@ offsetof(ngx_http_proxy_loc_conf_t, ssl_crl), NULL }, + { ngx_string("proxy_ssl_crl_check_all"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, ssl_crl_check_all), + NULL }, + { ngx_string("proxy_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -2884,6 +2892,7 @@ conf->upstream.ssl_server_name = NGX_CONF_UNSET; conf->upstream.ssl_verify = NGX_CONF_UNSET; conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; + conf->ssl_crl_check_all = NGX_CONF_UNSET; conf->ssl_passwords = NGX_CONF_UNSET_PTR; #endif @@ -3219,6 +3228,7 @@ ngx_conf_merge_str_value(conf->ssl_trusted_certificate, prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); + ngx_conf_merge_value(conf->ssl_crl_check_all, prev->ssl_crl_check_all, 1); ngx_conf_merge_str_value(conf->ssl_certificate, prev->ssl_certificate, ""); @@ -4379,7 +4389,7 @@ return NGX_ERROR; } - if (ngx_ssl_crl(cf, plcf->upstream.ssl, &plcf->ssl_crl) != NGX_OK) { + if (ngx_ssl_crl(cf, plcf->upstream.ssl, &plcf->ssl_crl, plcf->ssl_crl_check_all) != NGX_OK) { return NGX_ERROR; } } diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Tue Apr 04 18:01:57 2017 +0300 +++ b/src/http/modules/ngx_http_ssl_module.c Wed Apr 05 11:25:54 2017 +0100 @@ -205,6 +205,13 @@ offsetof(ngx_http_ssl_srv_conf_t, crl), NULL }, + { ngx_string("ssl_crl_check_all"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_ssl_srv_conf_t, crl_check_all), + NULL}, + { ngx_string("ssl_stapling"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -547,6 +554,7 @@ sscf->verify_depth = NGX_CONF_UNSET_UINT; sscf->certificates = NGX_CONF_UNSET_PTR; sscf->certificate_keys = NGX_CONF_UNSET_PTR; + sscf->crl_check_all = NGX_CONF_UNSET; sscf->passwords = NGX_CONF_UNSET_PTR; sscf->builtin_session_cache = NGX_CONF_UNSET; sscf->session_timeout = NGX_CONF_UNSET; @@ -607,6 +615,7 @@ ngx_conf_merge_str_value(conf->trusted_certificate, prev->trusted_certificate, ""); ngx_conf_merge_str_value(conf->crl, prev->crl, ""); + ngx_conf_merge_value(conf->crl_check_all, prev->crl_check_all, 1); ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, NGX_DEFAULT_ECDH_CURVE); @@ -744,7 +753,7 @@ return NGX_CONF_ERROR; } - if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { + if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl, conf->crl_check_all) != NGX_OK) { return NGX_CONF_ERROR; } diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/http/modules/ngx_http_ssl_module.h --- a/src/http/modules/ngx_http_ssl_module.h Tue Apr 04 18:01:57 2017 +0300 +++ b/src/http/modules/ngx_http_ssl_module.h Wed Apr 05 11:25:54 2017 +0100 @@ -40,6 +40,7 @@ ngx_str_t client_certificate; ngx_str_t trusted_certificate; ngx_str_t crl; + ngx_flag_t crl_check_all; ngx_str_t ciphers; diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Tue Apr 04 18:01:57 2017 +0300 +++ b/src/http/modules/ngx_http_uwsgi_module.c Wed Apr 05 11:25:54 2017 +0100 @@ -54,6 +54,7 @@ ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; + ngx_flag_t ssl_crl_check_all; ngx_str_t ssl_certificate; ngx_str_t ssl_certificate_key; ngx_array_t *ssl_passwords; @@ -531,6 +532,13 @@ offsetof(ngx_http_uwsgi_loc_conf_t, ssl_crl), NULL }, + { ngx_string("uwsgi_ssl_crl_check_all"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_crl_check_all), + NULL }, + { ngx_string("uwsgi_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -1767,6 +1775,7 @@ ngx_conf_merge_str_value(conf->ssl_trusted_certificate, prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); + ngx_conf_merge_value(conf->ssl_crl_check_all, prev->ssl_crl_check_all, 1); ngx_conf_merge_str_value(conf->ssl_certificate, prev->ssl_certificate, ""); @@ -2382,7 +2391,7 @@ return NGX_ERROR; } - if (ngx_ssl_crl(cf, uwcf->upstream.ssl, &uwcf->ssl_crl) != NGX_OK) { + if (ngx_ssl_crl(cf, uwcf->upstream.ssl, &uwcf->ssl_crl, uwcf->ssl_crl_check_all) != NGX_OK) { return NGX_ERROR; } } diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c Tue Apr 04 18:01:57 2017 +0300 +++ b/src/mail/ngx_mail_ssl_module.c Wed Apr 05 11:25:54 2017 +0100 @@ -190,6 +190,13 @@ offsetof(ngx_mail_ssl_conf_t, crl), NULL }, + { ngx_string("ssl_crl_check_all"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_ssl_conf_t, crl_check_all), + NULL }, + ngx_null_command }; @@ -255,6 +262,7 @@ scf->prefer_server_ciphers = NGX_CONF_UNSET; scf->verify = NGX_CONF_UNSET_UINT; scf->verify_depth = NGX_CONF_UNSET_UINT; + scf->crl_check_all = NGX_CONF_UNSET; scf->builtin_session_cache = NGX_CONF_UNSET; scf->session_timeout = NGX_CONF_UNSET; scf->session_tickets = NGX_CONF_UNSET; @@ -306,6 +314,7 @@ ngx_conf_merge_str_value(conf->trusted_certificate, prev->trusted_certificate, ""); ngx_conf_merge_str_value(conf->crl, prev->crl, ""); + ngx_conf_merge_value(conf->crl_check_all, prev->crl_check_all, 1); ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); @@ -417,7 +426,7 @@ return NGX_CONF_ERROR; } - if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { + if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl, conf->crl_check_all) != NGX_OK) { return NGX_CONF_ERROR; } } diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/mail/ngx_mail_ssl_module.h --- a/src/mail/ngx_mail_ssl_module.h Tue Apr 04 18:01:57 2017 +0300 +++ b/src/mail/ngx_mail_ssl_module.h Wed Apr 05 11:25:54 2017 +0100 @@ -43,6 +43,7 @@ ngx_str_t client_certificate; ngx_str_t trusted_certificate; ngx_str_t crl; + ngx_flag_t crl_check_all; ngx_str_t ciphers; diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Tue Apr 04 18:01:57 2017 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Wed Apr 05 11:25:54 2017 +0100 @@ -44,6 +44,7 @@ ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; + ngx_flag_t ssl_crl_check_all; ngx_str_t ssl_certificate; ngx_str_t ssl_certificate_key; ngx_array_t *ssl_passwords; @@ -290,6 +291,13 @@ offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl), NULL }, + { ngx_string("proxy_ssl_crl_check_all"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl_check_all), + NULL }, + { ngx_string("proxy_ssl_certificate"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -1928,6 +1936,7 @@ prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); + ngx_conf_merge_value(conf->ssl_crl_check_all, prev->ssl_crl_check_all, 1); ngx_conf_merge_str_value(conf->ssl_certificate, prev->ssl_certificate, ""); @@ -2009,7 +2018,7 @@ return NGX_ERROR; } - if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) { + if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl, pscf->ssl_crl_check_all) != NGX_OK) { return NGX_ERROR; } } diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c Tue Apr 04 18:01:57 2017 +0300 +++ b/src/stream/ngx_stream_ssl_module.c Wed Apr 05 11:25:54 2017 +0100 @@ -186,6 +186,13 @@ offsetof(ngx_stream_ssl_conf_t, crl), NULL }, + { ngx_string("ssl_crl_check_all"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_conf_t, crl_check_all), + NULL }, + ngx_null_command }; @@ -515,6 +522,7 @@ scf->prefer_server_ciphers = NGX_CONF_UNSET; scf->verify = NGX_CONF_UNSET_UINT; scf->verify_depth = NGX_CONF_UNSET_UINT; + scf->crl_check_all = NGX_CONF_UNSET; scf->builtin_session_cache = NGX_CONF_UNSET; scf->session_timeout = NGX_CONF_UNSET; scf->session_tickets = NGX_CONF_UNSET; @@ -561,6 +569,7 @@ ngx_conf_merge_str_value(conf->trusted_certificate, prev->trusted_certificate, ""); ngx_conf_merge_str_value(conf->crl, prev->crl, ""); + ngx_conf_merge_value(conf->crl_check_all, prev->crl_check_all, 1); ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, NGX_DEFAULT_ECDH_CURVE); @@ -635,7 +644,7 @@ return NGX_CONF_ERROR; } - if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { + if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl, conf->crl_check_all) != NGX_OK) { return NGX_CONF_ERROR; } } diff -r 29ba1d6a2da9 -r 00b5a781cee0 src/stream/ngx_stream_ssl_module.h --- a/src/stream/ngx_stream_ssl_module.h Tue Apr 04 18:01:57 2017 +0300 +++ b/src/stream/ngx_stream_ssl_module.h Wed Apr 05 11:25:54 2017 +0100 @@ -38,6 +38,7 @@ ngx_str_t client_certificate; ngx_str_t trusted_certificate; ngx_str_t crl; + ngx_flag_t crl_check_all; ngx_str_t ciphers;
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel