From 71b6604e4465b6aac478f04c3608a6be5c6500e6 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 13 Nov 2012 10:42:16 +0000 Subject: [PATCH] Merge of r4885: ssl_verify_client optional_no_ca. 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 | 7 +++++++ src/http/modules/ngx_http_ssl_module.c | 3 ++- src/http/ngx_http_request.c | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index cd6d88518..b8061f0ce 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -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); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index d759489a6..ea8a0da32 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -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; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index c104db1c0..479b106cf 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -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));