diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 1607814ce..a2f6a25c5 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2108,6 +2108,35 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) } +ngx_int_t +ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + X509 *cert; + + if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) { + s->len = sizeof("FAILED") - 1; + s->data = (u_char *) "FAILED"; + + return NGX_OK; + } + + cert = SSL_get_peer_certificate(c->ssl->connection); + + if (cert) { + s->len = sizeof("SUCCESS") - 1; + s->data = (u_char *) "SUCCESS"; + + } else { + s->len = sizeof("NONE") - 1; + s->data = (u_char *) "NONE"; + } + + X509_free(cert); + + return NGX_OK; +} + + static void * ngx_openssl_create_conf(ngx_cycle_t *cycle) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 1e83606fd..3e496ee42 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -131,6 +131,8 @@ ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index c0fd6fdda..51f5465c7 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -52,7 +52,7 @@ static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = { static ngx_conf_enum_t ngx_http_ssl_verify[] = { { ngx_string("off"), 0 }, { ngx_string("on"), 1 }, - { ngx_string("ask"), 2 }, + { ngx_string("optional"), 2 }, { ngx_null_string, 0 } }; @@ -206,6 +206,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = { { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index f07472b33..a1e02acaf 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1524,7 +1524,7 @@ ngx_http_process_request(ngx_http_request_t *r) sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); - if (sscf->verify == 1) { + if (sscf->verify) { rc = SSL_get_verify_result(c->ssl->connection); if (rc != X509_V_OK) { @@ -1539,20 +1539,22 @@ ngx_http_process_request(ngx_http_request_t *r) return; } - cert = SSL_get_peer_certificate(c->ssl->connection); + if (sscf->verify == 1) { + cert = SSL_get_peer_certificate(c->ssl->connection); - if (cert == NULL) { - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent no required SSL certificate"); + if (cert == NULL) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent no required SSL certificate"); - ngx_ssl_remove_cached_session(sscf->ssl.ctx, + ngx_ssl_remove_cached_session(sscf->ssl.ctx, (SSL_get0_session(c->ssl->connection))); - ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT); - return; - } + ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT); + return; + } - X509_free(cert); + X509_free(cert); + } } }