Hi, I've been bitten by issue 857: https://trac.nginx.org/nginx/ticket/857
I terminate TLS in nginx, but I need access to the full client certificate in the backend, so to that end I've been using $ssl_client_cert, but now I've upgraded the application to a version that is RFC 7230 compliant and that means blowing up when multi-line headers are seen. As there's no reason to have newlines in a PEM file, my fix for #857 is to remove all the newlines, as my PEM parser in the application already ignores all newlines this works perfectly for me. I think simply removing the newlines is a much better solution than url encoding the newlines as less code (in my case none at all) is needed to deal with no newlines than urldecoding. -- Flemming Frandsen - YAPH - http://osaa.dk - http://dren.dk/
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 5c7734d..5510dce 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -3434,6 +3434,42 @@ ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) return NGX_OK; } +ngx_int_t +ngx_ssl_get_bare_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + size_t len; + ngx_uint_t i; + ngx_str_t cert; + + if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) { + return NGX_ERROR; + } + + if (cert.len == 0) { + s->len = 0; + return NGX_OK; + } + + // The stripped certificate is never going to be bigger than the input. + // so we'll just allocate the same number of bytes for it. + s->data = ngx_pnalloc(pool, cert.len); + if (s->data == NULL) { + return NGX_ERROR; + } + + len = 0; + for (i = 0; i < cert.len - 1; i++) { + u_char ch = cert.data[i]; + if (ch != LF) { + s->data[len++] = ch; + } + } + + s->len = len; + + return NGX_OK; +} + ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index d233c02..62cc6e8 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -201,6 +201,8 @@ ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_bare_certificate(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index e75f5d8..889fd18 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -288,6 +288,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = { { ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_bare_cert"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_bare_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_raw_cert"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_raw_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel