# HG changeset patch # User Maxim Dounin # Date 1725053442 -10800 # Node ID 03cdd806c0f2a05de843a9968c4bf153a5a9e285 # Parent 8ebb4e488aa489c6746b75ede9a5b1631ca949a4 SSL: added SHA-256 fingerprints. In http and stream modules, the $ssl_client_fingerprint_sha256 variable now provides client certificate SHA-256 fingerprint, in addition to the $ssl_client_fingerprint variable with SHA-1 fingerprint. In mail proxy, the "Auth-SSL-Fingerprint-SHA256" header was added. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -5749,6 +5749,42 @@ ngx_ssl_get_fingerprint(ngx_connection_t ngx_int_t +ngx_ssl_get_fingerprint_sha256(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s) +{ + X509 *cert; + unsigned int len; + u_char buf[EVP_MAX_MD_SIZE]; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + + if (!X509_digest(cert, EVP_sha256(), buf, &len)) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_digest() failed"); + X509_free(cert); + return NGX_ERROR; + } + + s->len = 2 * len; + s->data = ngx_pnalloc(pool, 2 * len); + if (s->data == NULL) { + X509_free(cert); + return NGX_ERROR; + } + + ngx_hex_dump(s->data, buf, len); + + X509_free(cert); + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { X509 *cert; diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -299,6 +299,8 @@ ngx_int_t ngx_ssl_get_serial_number(ngx_ ngx_str_t *s); ngx_int_t ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_fingerprint_sha256(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_get_client_v_start(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 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -387,6 +387,9 @@ static ngx_http_variable_t ngx_http_ssl { ngx_string("ssl_client_fingerprint"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_fingerprint, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_fingerprint_sha256"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_fingerprint_sha256, 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 }, diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -1213,7 +1213,8 @@ ngx_mail_auth_http_create_request(ngx_ma ngx_connection_t *c; #if (NGX_MAIL_SSL) ngx_str_t protocol, cipher, verify, subject, issuer, - serial, fingerprint, raw_cert, cert; + serial, fingerprint, fingerprint2, raw_cert, + cert; ngx_mail_ssl_conf_t *sslcf; #endif ngx_mail_core_srv_conf_t *cscf; @@ -1275,6 +1276,10 @@ ngx_mail_auth_http_create_request(ngx_ma return NULL; } + if (ngx_ssl_get_fingerprint_sha256(c, pool, &fingerprint2) != NGX_OK) { + return NULL; + } + if (ahcf->pass_client_cert) { /* certificate itself, if configured */ @@ -1297,6 +1302,7 @@ ngx_mail_auth_http_create_request(ngx_ma ngx_str_null(&issuer); ngx_str_null(&serial); ngx_str_null(&fingerprint); + ngx_str_null(&fingerprint2); ngx_str_null(&cert); } @@ -1360,6 +1366,8 @@ ngx_mail_auth_http_create_request(ngx_ma + sizeof(CRLF) - 1 + sizeof("Auth-SSL-Fingerprint: ") - 1 + fingerprint.len + sizeof(CRLF) - 1 + + sizeof("Auth-SSL-Fingerprint-SHA256: ") - 1 + fingerprint2.len + + sizeof(CRLF) - 1 + sizeof("Auth-SSL-Cert: ") - 1 + cert.len + sizeof(CRLF) - 1; } @@ -1520,6 +1528,13 @@ ngx_mail_auth_http_create_request(ngx_ma *b->last++ = CR; *b->last++ = LF; } + if (fingerprint2.len) { + b->last = ngx_cpymem(b->last, "Auth-SSL-Fingerprint-SHA256: ", + sizeof("Auth-SSL-Fingerprint-SHA256: ") - 1); + b->last = ngx_copy(b->last, fingerprint2.data, fingerprint2.len); + *b->last++ = CR; *b->last++ = LF; + } + if (cert.len) { b->last = ngx_cpymem(b->last, "Auth-SSL-Cert: ", sizeof("Auth-SSL-Cert: ") - 1); diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -310,6 +310,10 @@ static ngx_stream_variable_t ngx_stream { ngx_string("ssl_client_fingerprint"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_fingerprint, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_fingerprint_sha256"), NULL, + ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_fingerprint_sha256, + NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_verify"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_client_verify, NGX_STREAM_VAR_CHANGEABLE, 0 },