From 3d2464ee5a07e4df3573eb4c17d3960ba9c431e2 Mon Sep 17 00:00:00 2001 From: Vadim Zhestikov Date: Tue, 12 May 2026 19:25:12 -0700 Subject: [PATCH] Core: use SSL_get0_peer_certificate() in PP v2 auto-fill. Replace SSL_get_peer_certificate() + X509_free() with the non-refcounting SSL_get0_peer_certificate() in the ssl_cn, ssl_sig_alg and ssl_key_alg cases of ngx_proxy_protocol_v2_auto_ssl_sub(). The returned X509 pointer is borrowed from the SSL object and remains valid as long as the connection is alive. All X509_free() calls on the error and success paths are removed, eliminating the risk of omitting a free on a newly added exit path. SSL_get0_peer_certificate() is available since OpenSSL 1.1.0, which is the minimum version nginx already requires. To squash into: dd8d635cf (Core: add PROXY protocol v2 TLV auto-fill from SSL session.) --- src/core/ngx_proxy_protocol.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/core/ngx_proxy_protocol.c b/src/core/ngx_proxy_protocol.c index b38c7fc27..d8455dea1 100644 --- a/src/core/ngx_proxy_protocol.c +++ b/src/core/ngx_proxy_protocol.c @@ -814,20 +814,18 @@ ngx_proxy_protocol_v2_auto_ssl_sub(ngx_connection_t *c, ngx_uint_t type, return NGX_OK; case NGX_PROXY_PROTOCOL_V2_SUBTYPE_SSL_CN: - cert = SSL_get_peer_certificate(ssl); + cert = SSL_get0_peer_certificate(ssl); if (cert == NULL) { return NGX_DECLINED; } subject = X509_get_subject_name(cert); if (subject == NULL) { - X509_free(cert); return NGX_DECLINED; } idx = X509_NAME_get_index_by_NID(subject, NID_commonName, -1); if (idx < 0) { - X509_free(cert); return NGX_DECLINED; } @@ -836,28 +834,24 @@ ngx_proxy_protocol_v2_auto_ssl_sub(ngx_connection_t *c, ngx_uint_t type, len = ASN1_STRING_length(cn_asn); if (len == 0) { - X509_free(cert); return NGX_DECLINED; } out->data = ngx_pnalloc(c->pool, len); if (out->data == NULL) { - X509_free(cert); return NGX_ERROR; } ngx_memcpy(out->data, ASN1_STRING_get0_data(cn_asn), len); out->len = len; - X509_free(cert); return NGX_OK; case NGX_PROXY_PROTOCOL_V2_SUBTYPE_SSL_SIG_ALG: - cert = SSL_get_peer_certificate(ssl); + cert = SSL_get0_peer_certificate(ssl); if (cert == NULL) { return NGX_DECLINED; } nid = X509_get_signature_nid(cert); - X509_free(cert); s = OBJ_nid2sn(nid); if (s == NULL) { return NGX_DECLINED; @@ -872,17 +866,15 @@ ngx_proxy_protocol_v2_auto_ssl_sub(ngx_connection_t *c, ngx_uint_t type, return NGX_OK; case NGX_PROXY_PROTOCOL_V2_SUBTYPE_SSL_KEY_ALG: - cert = SSL_get_peer_certificate(ssl); + cert = SSL_get0_peer_certificate(ssl); if (cert == NULL) { return NGX_DECLINED; } pkey = X509_get0_pubkey(cert); if (pkey == NULL) { - X509_free(cert); return NGX_DECLINED; } nid = EVP_PKEY_id(pkey); - X509_free(cert); s = OBJ_nid2sn(nid); if (s == NULL) { return NGX_DECLINED;