openssl: fix peer certificate leak in channel binding

Reported-by: Stanislav Fort
Bug: https://hackerone.com/reports/3373640
Closes #18917
This commit is contained in:
Daniel Stenberg 2025-10-07 07:49:00 +02:00
parent f609b57389
commit 1ce6dff01a
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View file

@ -5628,6 +5628,7 @@ static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex,
struct connectdata *conn = data->conn;
struct Curl_cfilter *cf = conn->cfilter[sockindex];
struct ossl_ctx *octx = NULL;
CURLcode result = CURLE_OK;
do {
const struct Curl_cftype *cft = cf->cft;
@ -5649,15 +5650,15 @@ static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex,
}
cert = SSL_get1_peer_certificate(octx->ssl);
if(!cert) {
if(!cert)
/* No server certificate, don't do channel binding */
return CURLE_OK;
}
if(!OBJ_find_sigid_algs(X509_get_signature_nid(cert), &algo_nid, NULL)) {
failf(data,
"Unable to find digest NID for certificate signature algorithm");
return CURLE_SSL_INVALIDCERTSTATUS;
result = CURLE_SSL_INVALIDCERTSTATUS;
goto error;
}
/* https://datatracker.ietf.org/doc/html/rfc5929#section-4.1 */
@ -5670,23 +5671,28 @@ static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex,
algo_name = OBJ_nid2sn(algo_nid);
failf(data, "Could not find digest algorithm %s (NID %d)",
algo_name ? algo_name : "(null)", algo_nid);
return CURLE_SSL_INVALIDCERTSTATUS;
result = CURLE_SSL_INVALIDCERTSTATUS;
goto error;
}
}
if(!X509_digest(cert, algo_type, buf, &length)) {
failf(data, "X509_digest() failed");
return CURLE_SSL_INVALIDCERTSTATUS;
result = CURLE_SSL_INVALIDCERTSTATUS;
goto error;
}
/* Append "tls-server-end-point:" */
if(curlx_dyn_addn(binding, prefix, sizeof(prefix) - 1) != CURLE_OK)
return CURLE_OUT_OF_MEMORY;
/* Append digest */
if(curlx_dyn_addn(binding, buf, length))
return CURLE_OUT_OF_MEMORY;
result = curlx_dyn_addn(binding, prefix, sizeof(prefix) - 1);
if(result)
goto error;
return CURLE_OK;
/* Append digest */
result = curlx_dyn_addn(binding, buf, length);
error:
X509_free(cert);
return result;
#else
/* No X509_get_signature_nid support */
(void)data;