changeset 4884:e406c997470a

SSL: the "ssl_verify_client" directive parameter "optional_no_ca". This parameter allows to don't require certificate to be signed by a trusted CA, e.g. if CA certificate isn't known in advance, like in WebID protocol. Note that it doesn't add any security unless the certificate is actually checked to be trusted by some external means (e.g. by a backend). Patch by Mike Kazantsev, Eric O'Connor.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 03 Oct 2012 15:24:08 +0000
parents f7443eeb3536
children 8f1ad536caf1
files src/event/ngx_event_openssl.h src/http/modules/ngx_http_ssl_module.c src/http/ngx_http_request.c
diffstat 3 files changed, 12 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.h	Wed Oct 03 15:22:18 2012 +0000
+++ b/src/event/ngx_event_openssl.h	Wed Oct 03 15:24:08 2012 +0000
@@ -127,6 +127,13 @@
 #define ngx_ssl_get_server_conf(ssl_ctx)                                      \
     SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_server_conf_index)
 
+#define ngx_ssl_verify_error_optional(n)                                      \
+    (n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT                              \
+     || n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN                             \
+     || n == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY                     \
+     || n == X509_V_ERR_CERT_UNTRUSTED                                        \
+     || n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)
+
 
 ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
--- a/src/http/modules/ngx_http_ssl_module.c	Wed Oct 03 15:22:18 2012 +0000
+++ b/src/http/modules/ngx_http_ssl_module.c	Wed Oct 03 15:24:08 2012 +0000
@@ -50,6 +50,7 @@
     { ngx_string("off"), 0 },
     { ngx_string("on"), 1 },
     { ngx_string("optional"), 2 },
+    { ngx_string("optional_no_ca"), 3 },
     { ngx_null_string, 0 }
 };
 
@@ -515,7 +516,7 @@
 
     if (conf->verify) {
 
-        if (conf->client_certificate.len == 0) {
+        if (conf->client_certificate.len == 0 && conf->verify != 3) {
             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                           "no ssl_client_certificate for ssl_client_verify");
             return NGX_CONF_ERROR;
--- a/src/http/ngx_http_request.c	Wed Oct 03 15:22:18 2012 +0000
+++ b/src/http/ngx_http_request.c	Wed Oct 03 15:24:08 2012 +0000
@@ -1642,7 +1642,9 @@
         if (sscf->verify) {
             rc = SSL_get_verify_result(c->ssl->connection);
 
-            if (rc != X509_V_OK) {
+            if (rc != X509_V_OK
+                && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
+            {
                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
                               "client SSL certificate verify error: (%l:%s)",
                               rc, X509_verify_cert_error_string(rc));