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.)
This commit is contained in:
Vadim Zhestikov 2026-05-12 19:25:12 -07:00
parent e1e6ed3616
commit 3d2464ee5a

View file

@ -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;