@@ -1939,20 +1939,30 @@ locked_HMAC_CTX_copy(HMAC_CTX *new_ctx_p, HMACobject *self)
19391939    return  0 ;
19401940}
19411941
1942- /* returning 0 means that an error occurred and an exception is set */ 
1942+ #define  BAD_DIGEST_SIZE  0
1943+ 
1944+ /* 
1945+  * Return the digest size in bytes. 
1946+  * 
1947+  * On error, set an exception and return BAD_DIGEST_SIZE. 
1948+  */ 
19431949static  unsigned int  
19441950_hashlib_hmac_digest_size (HMACobject  * self )
19451951{
19461952    const  EVP_MD  * md  =  _hashlib_hmac_get_md (self );
19471953    if  (md  ==  NULL ) {
1948-         return  0 ;
1954+         return  BAD_DIGEST_SIZE ;
19491955    }
1950-     unsigned int   digest_size  =  EVP_MD_size (md );
1951-     assert (digest_size  <= EVP_MAX_MD_SIZE );
1956+     int  digest_size  =  EVP_MD_size (md );
1957+     /* digest_size < 0 iff EVP_MD context is NULL (which is impossible here) */ 
1958+     assert (digest_size  >= 0 );
1959+     assert (digest_size  <= (int )EVP_MAX_MD_SIZE );
1960+     /* digest_size == 0 means that the context is not entirely initialized */ 
19521961    if  (digest_size  ==  0 ) {
1953-         notify_ssl_error_occurred ("invalid digest size" );
1962+         raise_ssl_error (PyExc_ValueError , "missing digest size" );
1963+         return  BAD_DIGEST_SIZE ;
19541964    }
1955-     return  digest_size ;
1965+     return  ( unsigned  int ) digest_size ;
19561966}
19571967
19581968static  int 
@@ -2053,24 +2063,38 @@ _hashlib_HMAC_update_impl(HMACobject *self, PyObject *msg)
20532063    Py_RETURN_NONE ;
20542064}
20552065
2056- static  int 
2057- _hmac_digest (HMACobject  * self , unsigned char   * buf , unsigned int   len )
2066+ /* 
2067+  * Extract the MAC value to 'buf' and return the digest size. 
2068+  * 
2069+  * The buffer 'buf' must have at least hashlib_openssl_HMAC_digest_size(self) 
2070+  * bytes. Smaller buffers lead to undefined behaviors. 
2071+  * 
2072+  * On error, set an exception and return -1. 
2073+  */ 
2074+ static  Py_ssize_t 
2075+ _hmac_digest (HMACobject  * self , unsigned char   * buf )
20582076{
2077+     unsigned int   digest_size  =  _hashlib_hmac_digest_size (self );
2078+     assert (digest_size  <= EVP_MAX_MD_SIZE );
2079+     if  (digest_size  ==  BAD_DIGEST_SIZE ) {
2080+         assert (PyErr_Occurred ());
2081+         return  -1 ;
2082+     }
20592083    HMAC_CTX  * temp_ctx  =  py_openssl_wrapper_HMAC_CTX_new ();
20602084    if  (temp_ctx  ==  NULL ) {
2061-         return  0 ;
2085+         return  -1 ;
20622086    }
20632087    if  (locked_HMAC_CTX_copy (temp_ctx , self ) <  0 ) {
20642088        HMAC_CTX_free (temp_ctx );
2065-         return  0 ;
2089+         return  -1 ;
20662090    }
2067-     int  r  =  HMAC_Final (temp_ctx , buf , & len );
2091+     int  r  =  HMAC_Final (temp_ctx , buf , NULL );
20682092    HMAC_CTX_free (temp_ctx );
20692093    if  (r  ==  0 ) {
20702094        notify_ssl_error_occurred_in (Py_STRINGIFY (HMAC_Final ));
2071-         return  0 ;
2095+         return  -1 ;
20722096    }
2073-     return  1 ;
2097+     return  digest_size ;
20742098}
20752099
20762100/*[clinic input] 
@@ -2082,16 +2106,9 @@ static PyObject *
20822106_hashlib_HMAC_digest_impl (HMACobject  * self )
20832107/*[clinic end generated code: output=1b1424355af7a41e input=bff07f74da318fb4]*/ 
20842108{
2085-     unsigned char   digest [EVP_MAX_MD_SIZE ];
2086-     unsigned int   digest_size  =  _hashlib_hmac_digest_size (self );
2087-     if  (digest_size  ==  0 ) {
2088-         return  NULL ;
2089-     }
2090-     int  r  =  _hmac_digest (self , digest , digest_size );
2091-     if  (r  ==  0 ) {
2092-         return  NULL ;
2093-     }
2094-     return  PyBytes_FromStringAndSize ((const  char  * )digest , digest_size );
2109+     unsigned char   buf [EVP_MAX_MD_SIZE ];
2110+     Py_ssize_t  n  =  _hmac_digest (self , buf );
2111+     return  n  <  0  ? NULL  : PyBytes_FromStringAndSize ((const  char  * )buf , n );
20952112}
20962113
20972114/*[clinic input] 
@@ -2109,24 +2126,17 @@ static PyObject *
21092126_hashlib_HMAC_hexdigest_impl (HMACobject  * self )
21102127/*[clinic end generated code: output=80d825be1eaae6a7 input=5e48db83ab1a4d19]*/ 
21112128{
2112-     unsigned char   digest [EVP_MAX_MD_SIZE ];
2113-     unsigned int   digest_size  =  _hashlib_hmac_digest_size (self );
2114-     if  (digest_size  ==  0 ) {
2115-         return  NULL ;
2116-     }
2117-     int  r  =  _hmac_digest (self , digest , digest_size );
2118-     if  (r  ==  0 ) {
2119-         return  NULL ;
2120-     }
2121-     return  _Py_strhex ((const  char  * )digest , digest_size );
2129+     unsigned char   buf [EVP_MAX_MD_SIZE ];
2130+     Py_ssize_t  n  =  _hmac_digest (self , buf );
2131+     return  n  <  0  ? NULL  : _Py_strhex ((const  char  * )buf , n );
21222132}
21232133
21242134static  PyObject  * 
21252135_hashlib_hmac_get_digest_size (PyObject  * op , void  * Py_UNUSED (closure ))
21262136{
21272137    HMACobject  * self  =  HMACobject_CAST (op );
2128-     unsigned int   digest_size  =  _hashlib_hmac_digest_size (self );
2129-     return  digest_size  ==  0  ? NULL  : PyLong_FromLong (digest_size );
2138+     unsigned int   size  =  _hashlib_hmac_digest_size (self );
2139+     return  size  ==  BAD_DIGEST_SIZE  ? NULL  : PyLong_FromLong (size );
21302140}
21312141
21322142static  PyObject  * 
0 commit comments