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

Reply via email to