]> git.kaiwu.me - nginx.git/commitdiff
Merge of r4885: ssl_verify_client optional_no_ca.
authorMaxim Dounin <mdounin@mdounin.ru>
Tue, 13 Nov 2012 10:42:16 +0000 (10:42 +0000)
committerMaxim Dounin <mdounin@mdounin.ru>
Tue, 13 Nov 2012 10:42:16 +0000 (10:42 +0000)
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.

src/event/ngx_event_openssl.h
src/http/modules/ngx_http_ssl_module.c
src/http/ngx_http_request.c

index cd6d88518bf24a0d978097695f459402d088cbae..b8061f0ce4befca96fb56d4d692aa9063d73f0fe 100644 (file)
@@ -120,6 +120,13 @@ ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session);
 #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);
index d759489a614f71e3140933b2270624e60291006d..ea8a0da32a0cedcfcad387a1eaf87d74b721c74c 100644 (file)
@@ -48,6 +48,7 @@ static ngx_conf_enum_t  ngx_http_ssl_verify[] = {
     { ngx_string("off"), 0 },
     { ngx_string("on"), 1 },
     { ngx_string("optional"), 2 },
+    { ngx_string("optional_no_ca"), 3 },
     { ngx_null_string, 0 }
 };
 
@@ -466,7 +467,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
 
     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;
index c104db1c0c6b932391a05428f2b0c9b8c0469512..479b106cfc8d23b867ca8ab12bb5b589827de539 100644 (file)
@@ -1634,7 +1634,9 @@ ngx_http_process_request(ngx_http_request_t *r)
         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));