Skip to content

Commit 9b0b3c1

Browse files
committed
pythongh-136591: avoid using deprecated features for OpenSSL 3.0+ (python#136592)
Since OpenSSL 3.0, `ERR_func_error_string()` always returns NULL and `EVP_MD_CTX_get0_md()` should be preferred over `EVP_MD_CTX_md()`.
1 parent 5fc0a6d commit 9b0b3c1

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:mod:`!_hashlib`: avoid using deprecated functions
2+
:manpage:`ERR_func_error_string` and :manpage:`EVP_MD_CTX_md` when using
3+
OpenSSL 3.0 and later. Patch by Bénédikt Tran.

Modules/_hashopenssl.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,15 @@
6363
#define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties)
6464
#define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md)
6565
#define PY_EVP_MD_free(md) EVP_MD_free(md)
66+
67+
#define PY_EVP_MD_CTX_md(CTX) EVP_MD_CTX_get0_md(CTX)
6668
#else
6769
#define PY_EVP_MD const EVP_MD
6870
#define PY_EVP_MD_fetch(algorithm, properties) EVP_get_digestbyname(algorithm)
6971
#define PY_EVP_MD_up_ref(md) do {} while(0)
7072
#define PY_EVP_MD_free(md) do {} while(0)
73+
74+
#define PY_EVP_MD_CTX_md(CTX) EVP_MD_CTX_md(CTX)
7175
#endif
7276

7377
/* hash alias map and fast lookup
@@ -307,6 +311,14 @@ class _hashlib.HMAC "HMACobject *" "&PyType_Type"
307311

308312
/* LCOV_EXCL_START */
309313

314+
/* Thin wrapper around ERR_reason_error_string() returning non-NULL text. */
315+
static const char *
316+
py_wrapper_ERR_reason_error_string(unsigned long errcode)
317+
{
318+
const char *reason = ERR_reason_error_string(errcode);
319+
return reason ? reason : "no reason";
320+
}
321+
310322
/* Set an exception of given type using the given OpenSSL error code. */
311323
static void
312324
set_ssl_exception_from_errcode(PyObject *exc_type, unsigned long errcode)
@@ -316,8 +328,13 @@ set_ssl_exception_from_errcode(PyObject *exc_type, unsigned long errcode)
316328

317329
/* ERR_ERROR_STRING(3) ensures that the messages below are ASCII */
318330
const char *lib = ERR_lib_error_string(errcode);
331+
#ifdef Py_HAS_OPENSSL3_SUPPORT
332+
// Since OpenSSL 3.0, ERR_func_error_string() always returns NULL.
333+
const char *func = NULL;
334+
#else
319335
const char *func = ERR_func_error_string(errcode);
320-
const char *reason = ERR_reason_error_string(errcode);
336+
#endif
337+
const char *reason = py_wrapper_ERR_reason_error_string(errcode);
321338

322339
if (lib && func) {
323340
PyErr_Format(exc_type, "[%s: %s] %s", lib, func, reason);
@@ -837,7 +854,7 @@ static PyObject *
837854
_hashlib_HASH_get_name(PyObject *op, void *Py_UNUSED(closure))
838855
{
839856
HASHobject *self = HASHobject_CAST(op);
840-
const EVP_MD *md = EVP_MD_CTX_md(self->ctx);
857+
const EVP_MD *md = PY_EVP_MD_CTX_md(self->ctx);
841858
if (md == NULL) {
842859
notify_ssl_error_occurred("missing EVP_MD for HASH context");
843860
return NULL;

0 commit comments

Comments
 (0)