6464#define PY_EVP_MD_fetch (algorithm , properties ) EVP_MD_fetch(NULL, algorithm, properties)
6565#define PY_EVP_MD_up_ref (md ) EVP_MD_up_ref(md)
6666#define PY_EVP_MD_free (md ) EVP_MD_free(md)
67+
68+ #define PY_EVP_MD_CTX_md (CTX ) EVP_MD_CTX_get0_md(CTX)
6769#else
6870#define PY_EVP_MD const EVP_MD
6971#define PY_EVP_MD_fetch (algorithm , properties ) EVP_get_digestbyname(algorithm)
7072#define PY_EVP_MD_up_ref (md ) do {} while(0)
7173#define PY_EVP_MD_free (md ) do {} while(0)
74+
75+ #define PY_EVP_MD_CTX_md (CTX ) EVP_MD_CTX_md(CTX)
7276#endif
7377
7478/* hash alias map and fast lookup
@@ -308,6 +312,14 @@ class _hashlib.HMAC "HMACobject *" "&PyType_Type"
308312
309313/* LCOV_EXCL_START */
310314
315+ /* Thin wrapper around ERR_reason_error_string() returning non-NULL text. */
316+ static const char *
317+ py_wrapper_ERR_reason_error_string (unsigned long errcode )
318+ {
319+ const char * reason = ERR_reason_error_string (errcode );
320+ return reason ? reason : "no reason" ;
321+ }
322+
311323/* Set an exception of given type using the given OpenSSL error code. */
312324static void
313325set_ssl_exception_from_errcode (PyObject * exc_type , unsigned long errcode )
@@ -317,8 +329,13 @@ set_ssl_exception_from_errcode(PyObject *exc_type, unsigned long errcode)
317329
318330 /* ERR_ERROR_STRING(3) ensures that the messages below are ASCII */
319331 const char * lib = ERR_lib_error_string (errcode );
332+ #ifdef Py_HAS_OPENSSL3_SUPPORT
333+ // Since OpenSSL 3.0, ERR_func_error_string() always returns NULL.
334+ const char * func = NULL ;
335+ #else
320336 const char * func = ERR_func_error_string (errcode );
321- const char * reason = ERR_reason_error_string (errcode );
337+ #endif
338+ const char * reason = py_wrapper_ERR_reason_error_string (errcode );
322339
323340 if (lib && func ) {
324341 PyErr_Format (exc_type , "[%s: %s] %s" , lib , func , reason );
@@ -838,7 +855,7 @@ static PyObject *
838855_hashlib_HASH_get_name (PyObject * op , void * Py_UNUSED (closure ))
839856{
840857 HASHobject * self = HASHobject_CAST (op );
841- const EVP_MD * md = EVP_MD_CTX_md (self -> ctx );
858+ const EVP_MD * md = PY_EVP_MD_CTX_md (self -> ctx );
842859 if (md == NULL ) {
843860 notify_ssl_error_occurred ("missing EVP_MD for HASH context" );
844861 return NULL ;
0 commit comments