atom feed20 messages in ru.sysoev.nginxRe: New SSL features for Nginx.
FromSent OnAttachments
Brice FigureauJul 21, 2009 11:01 am 
Igor SysoevJul 22, 2009 1:43 am 
Brice FigureauJul 22, 2009 3:21 am 
Brice FigureauJul 22, 2009 4:39 am 
Igor SysoevJul 22, 2009 5:15 am 
Igor SysoevJul 22, 2009 7:52 am.optional
Brice FigureauJul 22, 2009 10:15 am 
Brice FigureauJul 22, 2009 10:20 am 
Igor SysoevJul 22, 2009 11:38 am 
Igor SysoevJul 22, 2009 11:42 am 
Brice FigureauJul 22, 2009 12:13 pm 
Igor SysoevJul 22, 2009 12:23 pm 
Brice FigureauJul 22, 2009 2:17 pm 
Tom KeyserJul 22, 2009 5:50 pm 
Glen LumanauJul 22, 2009 5:59 pm 
Edward MiddletonJul 22, 2009 7:26 pm 
Cliff WellsJul 22, 2009 8:22 pm 
Igor SysoevJul 23, 2009 12:08 am 
Igor SysoevJul 23, 2009 12:56 am.crl
Brice FigureauJul 23, 2009 4:32 am 
Subject:Re: New SSL features for Nginx.
From:Igor Sysoev (is@rambler-co.ru)
Date:Jul 22, 2009 7:52:10 am
List:ru.sysoev.nginx
Attachments:
patch.ssl.optional - 4k

On Wed, Jul 22, 2009 at 12:21:23PM +0200, Brice Figureau wrote:

Hi Igor,

On Wed, 2009-07-22 at 12:44 +0400, Igor Sysoev wrote:

On Tue, Jul 21, 2009 at 08:02:05PM +0200, Brice Figureau wrote:

Hi,

For Puppet[1] Nginx deployement (that is using Nginx as a front-end load-balancers to puppetmasters[2]), I had to create the following two patches, to match Apache behaviour:

* The first patch allows: + a new variant of ssl_client_verify: optional. In this mode, if the client sends a certificate it is verified, but if the client doesn't send a certificate, the connection is authorized too.

+ a new variable: $ssl_client_verify which contains, either NONE, SUCCESS or FAILURE depending on the verification status. It can be used to send information to the upstream about the client verification.

* The second patch adds CRL support to the client certificate verification:

ssl_crl /path/to/crl.pem;

Nginx then verifies the client certificate hasn't been revoked in the given CRL before allowing the connection to proceed.

For access to the patches, please see my last blog article: http://www.masterzen.fr/2009/07/21/new-ssl-features-for-nginx/

It would be great if those patches could be merged in the official Nginx source tree.

Thanks for reviewing the patch (at least the first one could be merged, isn't it?).

Could you test the attached slightly changed first patch ?

-- Igor Sysoev http://sysoev.ru/en/

Index: src/http/ngx_http_request.c =================================================================== --- src/http/ngx_http_request.c (revision 2313) +++ src/http/ngx_http_request.c (working copy) @@ -1524,7 +1524,7 @@

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 @@ 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); } }

Index: src/http/modules/ngx_http_ssl_module.c =================================================================== --- src/http/modules/ngx_http_ssl_module.c (revision 2313) +++ src/http/modules/ngx_http_ssl_module.c (working copy) @@ -52,7 +52,7 @@ 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 @@ { 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 } };

Index: src/event/ngx_event_openssl.c =================================================================== --- src/event/ngx_event_openssl.c (revision 2313) +++ src/event/ngx_event_openssl.c (working copy) @@ -2108,6 +2108,35 @@ }

+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) { Index: src/event/ngx_event_openssl.h =================================================================== --- src/event/ngx_event_openssl.h (revision 2313) +++ src/event/ngx_event_openssl.h (working copy) @@ -131,6 +131,8 @@ 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);