Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 31b8efe

Browse filesBrowse files
authored
[3.6] bpo-9146: Raise a ValueError if OpenSSL fails to init a hash func (#3274)
* [3.6] bpo-9146: Raise a ValueError if OpenSSL fails to init a hash func. (GH-1777) This helps people in weird FIPS mode environments where common things like MD5 are not available in the binary as a matter of policy. (cherry picked from commit 07244a8) * Include a NEWS entry.
1 parent d409735 commit 31b8efe
Copy full SHA for 31b8efe

File tree

Expand file treeCollapse file tree

2 files changed

+39
-9
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+39
-9
lines changed
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a segmentation fault in _hashopenssl when standard hash functions
2+
such as md5 are not available in the linked OpenSSL library. As in
3+
some special FIPS-140 build environments.

‎Modules/_hashopenssl.c

Copy file name to clipboardExpand all lines: Modules/_hashopenssl.c
+36-9Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,10 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
139139
process = MUNCH_SIZE;
140140
else
141141
process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
142-
EVP_DigestUpdate(self->ctx, (const void*)cp, process);
142+
if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) {
143+
_setException(PyExc_ValueError);
144+
break;
145+
}
143146
len -= process;
144147
cp += process;
145148
}
@@ -209,7 +212,10 @@ EVP_digest(EVPobject *self, PyObject *unused)
209212
return _setException(PyExc_ValueError);
210213
}
211214
digest_size = EVP_MD_CTX_size(temp_ctx);
212-
EVP_DigestFinal(temp_ctx, digest, NULL);
215+
if (!EVP_DigestFinal(temp_ctx, digest, NULL)) {
216+
_setException(PyExc_ValueError);
217+
return NULL;
218+
}
213219

214220
retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
215221
EVP_MD_CTX_free(temp_ctx);
@@ -237,7 +243,10 @@ EVP_hexdigest(EVPobject *self, PyObject *unused)
237243
return _setException(PyExc_ValueError);
238244
}
239245
digest_size = EVP_MD_CTX_size(temp_ctx);
240-
EVP_DigestFinal(temp_ctx, digest, NULL);
246+
if (!EVP_DigestFinal(temp_ctx, digest, NULL)) {
247+
_setException(PyExc_ValueError);
248+
return NULL;
249+
}
241250

242251
EVP_MD_CTX_free(temp_ctx);
243252

@@ -362,7 +371,12 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
362371
PyBuffer_Release(&view);
363372
return -1;
364373
}
365-
EVP_DigestInit(self->ctx, digest);
374+
if (!EVP_DigestInit(self->ctx, digest)) {
375+
_setException(PyExc_ValueError);
376+
if (data_obj)
377+
PyBuffer_Release(&view);
378+
return -1;
379+
}
366380

367381
self->name = name_obj;
368382
Py_INCREF(self->name);
@@ -461,7 +475,11 @@ EVPnew(PyObject *name_obj,
461475
if (initial_ctx) {
462476
EVP_MD_CTX_copy(self->ctx, initial_ctx);
463477
} else {
464-
EVP_DigestInit(self->ctx, digest);
478+
if (!EVP_DigestInit(self->ctx, digest)) {
479+
_setException(PyExc_ValueError);
480+
Py_DECREF(self);
481+
return NULL;
482+
}
465483
}
466484

467485
if (cp && len) {
@@ -902,6 +920,8 @@ generate_hash_name_list(void)
902920
* the generic one passing it a python string and are noticeably
903921
* faster than calling a python new() wrapper. Thats important for
904922
* code that wants to make hashes of a bunch of small strings.
923+
* The first call will lazy-initialize, which reports an exception
924+
* if initialization fails.
905925
*/
906926
#define GEN_CONSTRUCTOR(NAME) \
907927
static PyObject * \
@@ -914,6 +934,17 @@ generate_hash_name_list(void)
914934
if (!PyArg_ParseTuple(args, "|O:" #NAME , &data_obj)) { \
915935
return NULL; \
916936
} \
937+
\
938+
if (CONST_new_ ## NAME ## _ctx_p == NULL) { \
939+
EVP_MD_CTX *ctx_p = EVP_MD_CTX_new(); \
940+
if (!EVP_get_digestbyname(#NAME) || \
941+
!EVP_DigestInit(ctx_p, EVP_get_digestbyname(#NAME))) { \
942+
_setException(PyExc_ValueError); \
943+
EVP_MD_CTX_free(ctx_p); \
944+
return NULL; \
945+
} \
946+
CONST_new_ ## NAME ## _ctx_p = ctx_p; \
947+
} \
917948
\
918949
if (data_obj) \
919950
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); \
@@ -942,10 +973,6 @@ generate_hash_name_list(void)
942973
#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \
943974
if (CONST_ ## NAME ## _name_obj == NULL) { \
944975
CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
945-
if (EVP_get_digestbyname(#NAME)) { \
946-
CONST_new_ ## NAME ## _ctx_p = EVP_MD_CTX_new(); \
947-
EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
948-
} \
949976
} \
950977
} while (0);
951978

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.