@@ -1939,20 +1939,30 @@ locked_HMAC_CTX_copy(HMAC_CTX *new_ctx_p, HMACobject *self)
1939
1939
return 0 ;
1940
1940
}
1941
1941
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
+ */
1943
1949
static unsigned int
1944
1950
_hashlib_hmac_digest_size (HMACobject * self )
1945
1951
{
1946
1952
const EVP_MD * md = _hashlib_hmac_get_md (self );
1947
1953
if (md == NULL ) {
1948
- return 0 ;
1954
+ return BAD_DIGEST_SIZE ;
1949
1955
}
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 */
1952
1961
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 ;
1954
1964
}
1955
- return digest_size ;
1965
+ return ( unsigned int ) digest_size ;
1956
1966
}
1957
1967
1958
1968
static int
@@ -2053,24 +2063,38 @@ _hashlib_HMAC_update_impl(HMACobject *self, PyObject *msg)
2053
2063
Py_RETURN_NONE ;
2054
2064
}
2055
2065
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 )
2058
2076
{
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
+ }
2059
2083
HMAC_CTX * temp_ctx = py_openssl_wrapper_HMAC_CTX_new ();
2060
2084
if (temp_ctx == NULL ) {
2061
- return 0 ;
2085
+ return -1 ;
2062
2086
}
2063
2087
if (locked_HMAC_CTX_copy (temp_ctx , self ) < 0 ) {
2064
2088
HMAC_CTX_free (temp_ctx );
2065
- return 0 ;
2089
+ return -1 ;
2066
2090
}
2067
- int r = HMAC_Final (temp_ctx , buf , & len );
2091
+ int r = HMAC_Final (temp_ctx , buf , NULL );
2068
2092
HMAC_CTX_free (temp_ctx );
2069
2093
if (r == 0 ) {
2070
2094
notify_ssl_error_occurred_in (Py_STRINGIFY (HMAC_Final ));
2071
- return 0 ;
2095
+ return -1 ;
2072
2096
}
2073
- return 1 ;
2097
+ return digest_size ;
2074
2098
}
2075
2099
2076
2100
/*[clinic input]
@@ -2082,16 +2106,9 @@ static PyObject *
2082
2106
_hashlib_HMAC_digest_impl (HMACobject * self )
2083
2107
/*[clinic end generated code: output=1b1424355af7a41e input=bff07f74da318fb4]*/
2084
2108
{
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 );
2095
2112
}
2096
2113
2097
2114
/*[clinic input]
@@ -2109,24 +2126,17 @@ static PyObject *
2109
2126
_hashlib_HMAC_hexdigest_impl (HMACobject * self )
2110
2127
/*[clinic end generated code: output=80d825be1eaae6a7 input=5e48db83ab1a4d19]*/
2111
2128
{
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 );
2122
2132
}
2123
2133
2124
2134
static PyObject *
2125
2135
_hashlib_hmac_get_digest_size (PyObject * op , void * Py_UNUSED (closure ))
2126
2136
{
2127
2137
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 );
2130
2140
}
2131
2141
2132
2142
static PyObject *
0 commit comments