<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"># HG changeset patch<o:p></o:p></p>
<p class="MsoNormal"># User Mandeep Singh Chhabra <mandeep-singh.chhabra@thalesgroup.com><o:p></o:p></p>
<p class="MsoNormal"># Date 1640691269 -19800<o:p></o:p></p>
<p class="MsoNormal"># Tue Dec 28 17:04:29 2021 +0530<o:p></o:p></p>
<p class="MsoNormal"># Node ID 9baaef976ac80f05107b60801ebe6559cdb2cbc6<o:p></o:p></p>
<p class="MsoNormal"># Parent b002ad258f1d70924dc13d8f4bc0cc44362f0d0a<o:p></o:p></p>
<p class="MsoNormal">Add provision to fetch certificate chain from Nginx<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The change adds a new variable ('ssl_client_cert_chain') to the<o:p></o:p></p>
<p class="MsoNormal">existing set of variables. It is being part of the http's SSL<o:p></o:p></p>
<p class="MsoNormal">module. With this, the middleware can fetch the certificate chain<o:p></o:p></p>
<p class="MsoNormal">from Nginx using the variable mentioned. The variable returns<o:p></o:p></p>
<p class="MsoNormal">a verified chain of certificates.<o:p></o:p></p>
<p class="MsoNormal">If the trust anchor is a root certificate (self signed) which has<o:p></o:p></p>
<p class="MsoNormal">issued an intermediate certificate and the client certificate is<o:p></o:p></p>
<p class="MsoNormal">issued by the intermediate certificate. The variable ('ssl_client_cert_chain')<o:p></o:p></p>
<p class="MsoNormal">will return three certificates (rootCert -> intermediateCert -> clientCert)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">diff -r b002ad258f1d -r 9baaef976ac8 src/event/ngx_event_openssl.c<o:p></o:p></p>
<p class="MsoNormal">--- a/src/event/ngx_event_openssl.c Mon Dec 27 19:49:26 2021 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/event/ngx_event_openssl.c Tue Dec 28 17:04:29 2021 +0530<o:p></o:p></p>
<p class="MsoNormal">@@ -5048,6 +5048,99 @@<o:p></o:p></p>
<p class="MsoNormal"> return NGX_ERROR;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">+ngx_int_t<o:p></o:p></p>
<p class="MsoNormal">+ngx_ssl_get_verified_certificate_chain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+ size_t len;<o:p></o:p></p>
<p class="MsoNormal">+ BIO *bio;<o:p></o:p></p>
<p class="MsoNormal">+ X509 *cert;<o:p></o:p></p>
<p class="MsoNormal">+ STACK_OF(X509) *certs;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ s->len = 0;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ bio = BIO_new(BIO_s_mem());<o:p></o:p></p>
<p class="MsoNormal">+ if (bio == NULL) {<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");<o:p></o:p></p>
<p class="MsoNormal">+ return NGX_ERROR;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal">+ certs = SSL_get0_verified_chain(c->ssl->connection);<o:p></o:p></p>
<p class="MsoNormal">+ if (certs == NULL) {<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_get0_verified_chain failed");<o:p></o:p></p>
<p class="MsoNormal">+ goto failed;<o:p></o:p></p>
<p class="MsoNormal">+ } else {<o:p></o:p></p>
<p class="MsoNormal">+ for (int i = 0; i < sk_X509_num(certs); i++) {<o:p></o:p></p>
<p class="MsoNormal">+ cert = sk_X509_value(certs, i);<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal">+ if (PEM_write_bio_X509(bio, cert) == 0) {<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");<o:p></o:p></p>
<p class="MsoNormal">+ goto failed;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ len = BIO_pending(bio);<o:p></o:p></p>
<p class="MsoNormal">+ s->len = len;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ s->data = ngx_pnalloc(pool, len);<o:p></o:p></p>
<p class="MsoNormal">+ if (s->data == NULL) {<o:p></o:p></p>
<p class="MsoNormal">+ goto failed;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ BIO_read(bio, s->data, len);<o:p></o:p></p>
<p class="MsoNormal">+ BIO_free(bio);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ return NGX_OK;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+failed:<o:p></o:p></p>
<p class="MsoNormal">+ BIO_free(bio);<o:p></o:p></p>
<p class="MsoNormal">+ <o:p></o:p></p>
<p class="MsoNormal">+ return NGX_ERROR;<o:p></o:p></p>
<p class="MsoNormal"><span lang="FR">+}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ngx_int_t<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ngx_ssl_get_client_certificate_chain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+{<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ u_char *p;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ size_t len;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ ngx_uint_t i;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ ngx_str_t cert_chain;<o:p></o:p></span></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (ngx_ssl_get_verified_certificate_chain(c, pool, &cert_chain) != NGX_OK) {<o:p></o:p></p>
<p class="MsoNormal">+ return NGX_ERROR;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (cert_chain.len == 0) {<o:p></o:p></p>
<p class="MsoNormal">+ s->len = 0;<o:p></o:p></p>
<p class="MsoNormal">+ return NGX_OK;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ len = cert_chain.len - 1;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ for (i = 0; i < cert_chain.len - 1; i++) {<o:p></o:p></p>
<p class="MsoNormal">+ if (cert_chain.data[i] == LF) {<o:p></o:p></p>
<p class="MsoNormal">+ len++;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ s->len = len;<o:p></o:p></p>
<p class="MsoNormal">+ s->data = ngx_pnalloc(pool, len);<o:p></o:p></p>
<p class="MsoNormal">+ if (s->data == NULL) {<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "ngx_pnalloc failed");<o:p></o:p></p>
<p class="MsoNormal">+ return NGX_ERROR;<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ p = s->data;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ for (i = 0; i < cert_chain.len - 1; i++) {<o:p></o:p></p>
<p class="MsoNormal">+ *p++ = cert_chain.data[i];<o:p></o:p></p>
<p class="MsoNormal">+ if (cert_chain.data[i] == LF) {<o:p></o:p></p>
<p class="MsoNormal">+ *p++ = '\t';<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ return NGX_OK;<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> ngx_int_t<o:p></o:p></p>
<p class="MsoNormal">ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)<o:p></o:p></p>
<p class="MsoNormal">diff -r b002ad258f1d -r 9baaef976ac8 src/event/ngx_event_openssl.h<o:p></o:p></p>
<p class="MsoNormal">--- a/src/event/ngx_event_openssl.h Mon Dec 27 19:49:26 2021 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/event/ngx_event_openssl.h Tue Dec 28 17:04:29 2021 +0530<o:p></o:p></p>
<p class="MsoNormal">@@ -276,6 +276,8 @@<o:p></o:p></p>
<p class="MsoNormal"> ngx_str_t *s);<o:p></o:p></p>
<p class="MsoNormal">ngx_int_t ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool,<o:p></o:p></p>
<p class="MsoNormal"> ngx_str_t *s);<o:p></o:p></p>
<p class="MsoNormal"><span lang="FR">+ngx_int_t ngx_ssl_get_client_certificate_chain(ngx_connection_t *c, ngx_pool_t *pool,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ ngx_str_t *s);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR"> ngx_str_t *s);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,<o:p></o:p></span></p>
<p class="MsoNormal">diff -r b002ad258f1d -r 9baaef976ac8 src/http/modules/ngx_http_ssl_module.c<o:p></o:p></p>
<p class="MsoNormal">--- a/src/http/modules/ngx_http_ssl_module.c Mon Dec 27 19:49:26 2021 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/http/modules/ngx_http_ssl_module.c Tue Dec 28 17:04:29 2021 +0530<o:p></o:p></p>
<p class="MsoNormal">@@ -370,6 +370,10 @@<o:p></o:p></p>
<p class="MsoNormal"> { ngx_string("ssl_client_raw_cert"), NULL, ngx_http_ssl_variable,<o:p></o:p></p>
<p class="MsoNormal"> (uintptr_t) ngx_ssl_get_raw_certificate,<o:p></o:p></p>
<p class="MsoNormal"> <span lang="FR">NGX_HTTP_VAR_CHANGEABLE, 0 },<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ { ngx_string("ssl_client_cert_chain"), NULL, ngx_http_ssl_variable,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="FR">+ (uintptr_t) ngx_ssl_get_client_certificate_chain,<o:p></o:p></span></p>
<p class="MsoNormal">+ NGX_HTTP_VAR_CHANGEABLE, 0 },<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> { ngx_string("ssl_client_escaped_cert"), NULL, ngx_http_ssl_variable,<o:p></o:p></p>
<p class="MsoNormal"> (uintptr_t) ngx_ssl_get_escaped_certificate,<o:p></o:p></p>
</div>
</body>
</html>