[PATCH 4 of 6] SSL: add ngx_ssl_verify_client()
Piotr Sikora
piotrsikora at google.com
Thu Aug 18 00:29:25 UTC 2016
# HG changeset patch
# User Piotr Sikora <piotrsikora at google.com>
# Date 1471428990 25200
# Wed Aug 17 03:16:30 2016 -0700
# Node ID a9f36e1dd744130aa2ba080ae2a63f07986c8e83
# Parent 99c2f52beae28567bf2f8501d1a182cd20004c71
SSL: add ngx_ssl_verify_client().
No functional changes.
Signed-off-by: Piotr Sikora <piotrsikora at google.com>
diff -r 99c2f52beae2 -r a9f36e1dd744 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -3075,6 +3075,39 @@ ngx_ssl_cleanup_ctx(void *data)
ngx_int_t
+ngx_ssl_verify_client(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_uint_t verify)
+{
+ long rc;
+ X509 *cert;
+
+ rc = SSL_get_verify_result(c->ssl->connection);
+
+ if (rc != X509_V_OK
+ && (verify != NGX_SSL_VERIFY_OPTIONAL_NO_CA
+ || !ngx_ssl_verify_error_optional(rc)))
+ {
+ ngx_ssl_remove_cached_session(ssl->ctx,
+ SSL_get0_session(c->ssl->connection));
+ return (ngx_int_t) rc;
+ }
+
+ if (verify == NGX_SSL_VERIFY_REQUIRED) {
+ cert = SSL_get_peer_certificate(c->ssl->connection);
+
+ if (cert == NULL) {
+ ngx_ssl_remove_cached_session(ssl->ctx,
+ SSL_get0_session(c->ssl->connection));
+ return NGX_DECLINED;
+ }
+
+ X509_free(cert);
+ }
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name)
{
X509 *cert;
diff -r 99c2f52beae2 -r a9f36e1dd744 src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -188,12 +188,15 @@ ngx_int_t ngx_ssl_set_session(ngx_connec
#define ngx_ssl_get_server_conf(ssl_ctx) \
SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_server_conf_index)
+ngx_int_t ngx_ssl_verify_client(ngx_connection_t *c, ngx_ssl_t *ssl,
+ ngx_uint_t verify);
#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)
+#define ngx_ssl_verify_error_string(n) X509_verify_cert_error_string((long) n)
ngx_int_t ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name);
diff -r 99c2f52beae2 -r a9f36e1dd744 src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1845,8 +1845,7 @@ ngx_http_process_request(ngx_http_reques
#if (NGX_HTTP_SSL)
if (r->http_connection->ssl) {
- long rc;
- X509 *cert;
+ ngx_int_t rc;
ngx_http_ssl_srv_conf_t *sscf;
if (c->ssl == NULL) {
@@ -1859,39 +1858,23 @@ ngx_http_process_request(ngx_http_reques
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
if (sscf->verify) {
- rc = SSL_get_verify_result(c->ssl->connection);
-
- if (rc != X509_V_OK
- && (sscf->verify != NGX_SSL_VERIFY_OPTIONAL_NO_CA
- || !ngx_ssl_verify_error_optional(rc)))
- {
+ rc = ngx_ssl_verify_client(c, &sscf->ssl, sscf->verify);
+
+ if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client SSL certificate verify error: (%l:%s)",
- rc, X509_verify_cert_error_string(rc));
-
- ngx_ssl_remove_cached_session(sscf->ssl.ctx,
- (SSL_get0_session(c->ssl->connection)));
+ "client sent no required SSL certificate");
+
+ ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
+ return;
+
+ } else if (rc != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client SSL certificate verify error: (%i:%s)",
+ rc, ngx_ssl_verify_error_string(rc));
ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
return;
}
-
- if (sscf->verify == NGX_SSL_VERIFY_REQUIRED) {
- 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");
-
- ngx_ssl_remove_cached_session(sscf->ssl.ctx,
- (SSL_get0_session(c->ssl->connection)));
-
- ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
- return;
- }
-
- X509_free(cert);
- }
}
}
diff -r 99c2f52beae2 -r a9f36e1dd744 src/mail/ngx_mail_handler.c
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -16,8 +16,6 @@ static void ngx_mail_init_session(ngx_co
#if (NGX_MAIL_SSL)
static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c);
-static ngx_int_t ngx_mail_verify_cert(ngx_mail_session_t *s,
- ngx_connection_t *c);
#endif
@@ -247,15 +245,44 @@ ngx_mail_ssl_init_connection(ngx_ssl_t *
static void
ngx_mail_ssl_handshake_handler(ngx_connection_t *c)
{
+ ngx_int_t rc;
ngx_mail_session_t *s;
+ ngx_mail_ssl_conf_t *sslcf;
ngx_mail_core_srv_conf_t *cscf;
if (c->ssl->handshaked) {
s = c->data;
- if (ngx_mail_verify_cert(s, c) != NGX_OK) {
- return;
+ sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
+
+ if (sslcf->verify) {
+ rc = ngx_ssl_verify_client(c, &sslcf->ssl, sslcf->verify);
+
+ if (rc != NGX_OK) {
+ cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
+
+ if (rc == NGX_DECLINED) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent no required SSL certificate");
+
+ s->out = cscf->protocol->no_cert;
+
+ } else {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client SSL certificate verify error: (%i:%s)",
+ rc, ngx_ssl_verify_error_string(rc));
+
+ s->out = cscf->protocol->cert_error;
+ }
+
+ s->quit = 1;
+
+ c->write->handler = ngx_mail_send;
+
+ ngx_mail_send(s->connection->write);
+ return;
+ }
}
if (s->starttls) {
@@ -278,72 +305,6 @@ ngx_mail_ssl_handshake_handler(ngx_conne
ngx_mail_close_connection(c);
}
-
-static ngx_int_t
-ngx_mail_verify_cert(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- long rc;
- X509 *cert;
- ngx_mail_ssl_conf_t *sslcf;
- ngx_mail_core_srv_conf_t *cscf;
-
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (!sslcf->verify) {
- return NGX_OK;
- }
-
- rc = SSL_get_verify_result(c->ssl->connection);
-
- if (rc != X509_V_OK
- && (sslcf->verify != NGX_SSL_VERIFY_OPTIONAL_NO_CA
- || !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));
-
- ngx_ssl_remove_cached_session(sslcf->ssl.ctx,
- (SSL_get0_session(c->ssl->connection)));
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- s->out = cscf->protocol->cert_error;
- s->quit = 1;
-
- c->write->handler = ngx_mail_send;
-
- ngx_mail_send(s->connection->write);
- return NGX_ERROR;
- }
-
- if (sslcf->verify == NGX_SSL_VERIFY_REQUIRED) {
- 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");
-
- ngx_ssl_remove_cached_session(sslcf->ssl.ctx,
- (SSL_get0_session(c->ssl->connection)));
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- s->out = cscf->protocol->no_cert;
- s->quit = 1;
-
- c->write->handler = ngx_mail_send;
-
- ngx_mail_send(s->connection->write);
- return NGX_ERROR;
- }
-
- X509_free(cert);
- }
-
- return NGX_OK;
-}
-
#endif
More information about the nginx-devel
mailing list