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

Reply via email to