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. */
311323static void
312324set_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