@@ -304,30 +304,17 @@ class _hashlib.HMAC "HMACobject *" "((_hashlibstate *)PyModule_GetState(module))
304304
305305
306306/* LCOV_EXCL_START */
307- static PyObject *
308- _setException (PyObject * exc , const char * altmsg , ...)
309- {
310- unsigned long errcode = ERR_peek_last_error ();
311- const char * lib , * func , * reason ;
312- va_list vargs ;
313307
314- va_start (vargs , altmsg );
315- if (!errcode ) {
316- if (altmsg == NULL ) {
317- PyErr_SetString (exc , "no reason supplied" );
318- } else {
319- PyErr_FormatV (exc , altmsg , vargs );
320- }
321- va_end (vargs );
322- return NULL ;
323- }
324- va_end (vargs );
325- ERR_clear_error ();
308+ /* Set an exception of given type using the given OpenSSL error code. */
309+ static void
310+ set_ssl_exception_from_errcode (PyObject * exc , unsigned long errcode )
311+ {
312+ assert (errcode != 0 );
326313
327314 /* ERR_ERROR_STRING(3) ensures that the messages below are ASCII */
328- lib = ERR_lib_error_string (errcode );
329- func = ERR_func_error_string (errcode );
330- reason = ERR_reason_error_string (errcode );
315+ const char * lib = ERR_lib_error_string (errcode );
316+ const char * func = ERR_func_error_string (errcode );
317+ const char * reason = ERR_reason_error_string (errcode );
331318
332319 if (lib && func ) {
333320 PyErr_Format (exc , "[%s: %s] %s" , lib , func , reason );
@@ -338,7 +325,42 @@ _setException(PyObject *exc, const char* altmsg, ...)
338325 else {
339326 PyErr_SetString (exc , reason );
340327 }
341- return NULL ;
328+ }
329+
330+ /*
331+ * Set an exception of given type.
332+ *
333+ * By default, the exception's message is constructed by using the last SSL
334+ * error that occurred. If no error occurred, the 'fallback_format' is used
335+ * to create a C-style formatted fallback message.
336+ */
337+ static void
338+ raise_ssl_error (PyObject * exc , const char * fallback_format , ...)
339+ {
340+ assert (fallback_format != NULL );
341+ unsigned long errcode = ERR_peek_last_error ();
342+ if (errcode ) {
343+ ERR_clear_error ();
344+ set_ssl_exception_from_errcode (exc , errcode );
345+ }
346+ else {
347+ va_list vargs ;
348+ va_start (vargs , fallback_format );
349+ PyErr_FormatV (exc , fallback_format , vargs );
350+ va_end (vargs );
351+ }
352+ }
353+
354+ /*
355+ * Set an exception with a generic default message after an error occurred.
356+ *
357+ * It can also be used without previous calls to SSL built-in functions,
358+ * in which case a generic error message is provided.
359+ */
360+ static inline void
361+ notify_ssl_error_occurred (void )
362+ {
363+ raise_ssl_error (PyExc_ValueError , "no reason supplied" );
342364}
343365/* LCOV_EXCL_STOP */
344366
@@ -430,8 +452,8 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht)
430452 }
431453 }
432454 if (digest == NULL ) {
433- ( void ) _setException (state -> unsupported_digestmod_error ,
434- "unsupported hash type %s" , name );
455+ raise_ssl_error (state -> unsupported_digestmod_error ,
456+ "unsupported hash type %s" , name );
435457 return NULL ;
436458 }
437459 return digest ;
@@ -504,7 +526,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
504526 else
505527 process = Py_SAFE_DOWNCAST (len , Py_ssize_t , unsigned int );
506528 if (!EVP_DigestUpdate (self -> ctx , (const void * )cp , process )) {
507- ( void ) _setException ( PyExc_ValueError , NULL );
529+ notify_ssl_error_occurred ( );
508530 return -1 ;
509531 }
510532 len -= process ;
@@ -554,7 +576,8 @@ EVP_copy_impl(EVPobject *self)
554576
555577 if (!locked_EVP_MD_CTX_copy (newobj -> ctx , self )) {
556578 Py_DECREF (newobj );
557- return _setException (PyExc_ValueError , NULL );
579+ notify_ssl_error_occurred ();
580+ return NULL ;
558581 }
559582 return (PyObject * )newobj ;
560583}
@@ -594,7 +617,8 @@ EVP_digest_impl(EVPobject *self)
594617
595618error :
596619 EVP_MD_CTX_free (temp_ctx );
597- return _setException (PyExc_ValueError , NULL );
620+ notify_ssl_error_occurred ();
621+ return NULL ;
598622}
599623
600624/*[clinic input]
@@ -632,7 +656,8 @@ EVP_hexdigest_impl(EVPobject *self)
632656
633657error :
634658 EVP_MD_CTX_free (temp_ctx );
635- return _setException (PyExc_ValueError , NULL );
659+ notify_ssl_error_occurred ();
660+ return NULL ;
636661}
637662
638663/*[clinic input]
@@ -703,7 +728,8 @@ EVP_get_name(PyObject *op, void *Py_UNUSED(closure))
703728 EVPobject * self = EVPobject_CAST (op );
704729 const EVP_MD * md = EVP_MD_CTX_md (self -> ctx );
705730 if (md == NULL ) {
706- return _setException (PyExc_ValueError , NULL );
731+ notify_ssl_error_occurred ();
732+ return NULL ;
707733 }
708734 return py_digest_name (md );
709735}
@@ -808,7 +834,8 @@ EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length)
808834error :
809835 Py_DECREF (retval );
810836 EVP_MD_CTX_free (temp_ctx );
811- return _setException (PyExc_ValueError , NULL );
837+ notify_ssl_error_occurred ();
838+ return NULL ;
812839}
813840
814841/*[clinic input]
@@ -857,7 +884,8 @@ EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length)
857884error :
858885 PyMem_Free (digest );
859886 EVP_MD_CTX_free (temp_ctx );
860- return _setException (PyExc_ValueError , NULL );
887+ notify_ssl_error_occurred ();
888+ return NULL ;
861889}
862890
863891static PyMethodDef EVPXOF_methods [] = {
@@ -955,7 +983,7 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj,
955983
956984 int result = EVP_DigestInit_ex (self -> ctx , digest , NULL );
957985 if (!result ) {
958- ( void ) _setException ( PyExc_ValueError , NULL );
986+ notify_ssl_error_occurred ( );
959987 Py_CLEAR (self );
960988 goto exit ;
961989 }
@@ -971,6 +999,7 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj,
971999 result = EVP_hash (self , view .buf , view .len );
9721000 }
9731001 if (result == -1 ) {
1002+ assert (PyErr_Occurred ());
9741003 Py_CLEAR (self );
9751004 goto exit ;
9761005 }
@@ -1345,7 +1374,7 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name,
13451374
13461375 if (!retval ) {
13471376 Py_CLEAR (key_obj );
1348- _setException ( PyExc_ValueError , NULL );
1377+ notify_ssl_error_occurred ( );
13491378 goto end ;
13501379 }
13511380
@@ -1451,8 +1480,9 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
14511480 /* let OpenSSL validate the rest */
14521481 retval = EVP_PBE_scrypt (NULL , 0 , NULL , 0 , n , r , p , maxmem , NULL , 0 );
14531482 if (!retval ) {
1454- return _setException (PyExc_ValueError ,
1455- "Invalid parameter combination for n, r, p, maxmem." );
1483+ raise_ssl_error (PyExc_ValueError ,
1484+ "Invalid parameter combination for n, r, p, maxmem." );
1485+ return NULL ;
14561486 }
14571487
14581488 key_obj = PyBytes_FromStringAndSize (NULL , dklen );
@@ -1472,7 +1502,8 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
14721502
14731503 if (!retval ) {
14741504 Py_CLEAR (key_obj );
1475- return _setException (PyExc_ValueError , NULL );
1505+ notify_ssl_error_occurred ();
1506+ return NULL ;
14761507 }
14771508 return key_obj ;
14781509}
@@ -1528,7 +1559,8 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
15281559 PY_EVP_MD_free (evp );
15291560
15301561 if (result == NULL ) {
1531- return _setException (PyExc_ValueError , NULL );
1562+ notify_ssl_error_occurred ();
1563+ return NULL ;
15321564 }
15331565 return PyBytes_FromStringAndSize ((const char * )md , md_len );
15341566}
@@ -1585,7 +1617,7 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
15851617 r = HMAC_Init_ex (ctx , key -> buf , (int )key -> len , digest , NULL /* impl */ );
15861618 PY_EVP_MD_free (digest );
15871619 if (r == 0 ) {
1588- ( void ) _setException ( PyExc_ValueError , NULL );
1620+ notify_ssl_error_occurred ( );
15891621 goto error ;
15901622 }
15911623
@@ -1629,13 +1661,13 @@ _hmac_digest_size(HMACobject *self)
16291661{
16301662 const EVP_MD * md = HMAC_CTX_get_md (self -> ctx );
16311663 if (md == NULL ) {
1632- ( void ) _setException ( PyExc_ValueError , NULL );
1664+ notify_ssl_error_occurred ( );
16331665 return 0 ;
16341666 }
16351667 unsigned int digest_size = EVP_MD_size (md );
16361668 assert (digest_size <= EVP_MAX_MD_SIZE );
16371669 if (digest_size == 0 ) {
1638- ( void ) _setException ( PyExc_ValueError , NULL );
1670+ notify_ssl_error_occurred ( );
16391671 }
16401672 return digest_size ;
16411673}
@@ -1664,7 +1696,7 @@ _hmac_update(HMACobject *self, PyObject *obj)
16641696 PyBuffer_Release (& view );
16651697
16661698 if (r == 0 ) {
1667- ( void ) _setException ( PyExc_ValueError , NULL );
1699+ notify_ssl_error_occurred ( );
16681700 return 0 ;
16691701 }
16701702 return 1 ;
@@ -1688,7 +1720,8 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
16881720 }
16891721 if (!locked_HMAC_CTX_copy (ctx , self )) {
16901722 HMAC_CTX_free (ctx );
1691- return _setException (PyExc_ValueError , NULL );
1723+ notify_ssl_error_occurred ();
1724+ return NULL ;
16921725 }
16931726
16941727 retval = PyObject_New (HMACobject , Py_TYPE (self ));
@@ -1721,7 +1754,8 @@ _hmac_repr(PyObject *op)
17211754 HMACobject * self = HMACobject_CAST (op );
17221755 const EVP_MD * md = HMAC_CTX_get_md (self -> ctx );
17231756 if (md == NULL ) {
1724- return _setException (PyExc_ValueError , NULL );
1757+ notify_ssl_error_occurred ();
1758+ return NULL ;
17251759 }
17261760 PyObject * digest_name = py_digest_name (md );
17271761 if (digest_name == NULL ) {
@@ -1761,13 +1795,13 @@ _hmac_digest(HMACobject *self, unsigned char *buf, unsigned int len)
17611795 }
17621796 if (!locked_HMAC_CTX_copy (temp_ctx , self )) {
17631797 HMAC_CTX_free (temp_ctx );
1764- ( void ) _setException ( PyExc_ValueError , NULL );
1798+ notify_ssl_error_occurred ( );
17651799 return 0 ;
17661800 }
17671801 int r = HMAC_Final (temp_ctx , buf , & len );
17681802 HMAC_CTX_free (temp_ctx );
17691803 if (r == 0 ) {
1770- ( void ) _setException ( PyExc_ValueError , NULL );
1804+ notify_ssl_error_occurred ( );
17711805 return 0 ;
17721806 }
17731807 return 1 ;
@@ -1836,7 +1870,8 @@ _hashlib_hmac_get_block_size(PyObject *op, void *Py_UNUSED(closure))
18361870 HMACobject * self = HMACobject_CAST (op );
18371871 const EVP_MD * md = HMAC_CTX_get_md (self -> ctx );
18381872 if (md == NULL ) {
1839- return _setException (PyExc_ValueError , NULL );
1873+ notify_ssl_error_occurred ();
1874+ return NULL ;
18401875 }
18411876 return PyLong_FromLong (EVP_MD_block_size (md ));
18421877}
@@ -1847,7 +1882,8 @@ _hashlib_hmac_get_name(PyObject *op, void *Py_UNUSED(closure))
18471882 HMACobject * self = HMACobject_CAST (op );
18481883 const EVP_MD * md = HMAC_CTX_get_md (self -> ctx );
18491884 if (md == NULL ) {
1850- return _setException (PyExc_ValueError , NULL );
1885+ notify_ssl_error_occurred ();
1886+ return NULL ;
18511887 }
18521888 PyObject * digest_name = py_digest_name (md );
18531889 if (digest_name == NULL ) {
@@ -2000,7 +2036,7 @@ _hashlib_get_fips_mode_impl(PyObject *module)
20002036 // But 0 is also a valid result value.
20012037 unsigned long errcode = ERR_peek_last_error ();
20022038 if (errcode ) {
2003- ( void ) _setException ( PyExc_ValueError , NULL );
2039+ notify_ssl_error_occurred ( );
20042040 return -1 ;
20052041 }
20062042 }
0 commit comments