New SSL features for Nginx.
Igor Sysoev
is at rambler-co.ru
Wed Jul 22 18:52:33 MSD 2009
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/
-------------- next part --------------
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);
More information about the nginx
mailing list