summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2020-05-25 12:18:49 (GMT)
committerGitHub <noreply@github.com>2020-05-25 12:18:49 (GMT)
commit1fe1a14703001ec8076412ca28a3fbdf1f5c0735 (patch)
treed049c54ad70a4fbc7052e70ba602e5fc380c051e
parent7015823971e7c0cf41cd7d9d9991ed0abdc2f1f4 (diff)
downloadcpython-1fe1a14703001ec8076412ca28a3fbdf1f5c0735.zip
cpython-1fe1a14703001ec8076412ca28a3fbdf1f5c0735.tar.gz
cpython-1fe1a14703001ec8076412ca28a3fbdf1f5c0735.tar.bz2
bpo-40671: Prepare _hashlib for PEP 489 (GH-20180)
(cherry picked from commit 20c22db602bf2a51f5231433b9054290f8069b90) Co-authored-by: Christian Heimes <christian@python.org>
-rw-r--r--Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst1
-rw-r--r--Modules/_hashopenssl.c181
2 files changed, 115 insertions, 67 deletions
diff --git a/Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst b/Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst
new file mode 100644
index 0000000..d38b88d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst
@@ -0,0 +1 @@
+Prepare ``_hashlib`` for :pep:`489` and use :c:func:`PyModule_AddType`.
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index 674bddc..0b2ef95 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -95,9 +95,6 @@ get_hashlib_state(PyObject *module)
return (_hashlibstate *)state;
}
-#define _hashlibstate_global ((_hashlibstate *)PyModule_GetState(PyState_FindModule(&_hashlibmodule)))
-
-
typedef struct {
PyObject_HEAD
EVP_MD_CTX *ctx; /* OpenSSL message digest context */
@@ -1763,22 +1760,30 @@ _openssl_hash_name_mapper(const EVP_MD *md, const char *from,
/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */
-static PyObject*
-generate_hash_name_list(void)
+static int
+hashlib_md_meth_names(PyObject *module)
{
- _InternalNameMapperState state;
- state.set = PyFrozenSet_New(NULL);
- if (state.set == NULL)
- return NULL;
- state.error = 0;
+ _InternalNameMapperState state = {
+ .set = PyFrozenSet_New(NULL),
+ .error = 0
+ };
+ if (state.set == NULL) {
+ return -1;
+ }
EVP_MD_do_all(&_openssl_hash_name_mapper, &state);
if (state.error) {
Py_DECREF(state.set);
- return NULL;
+ return -1;
}
- return state.set;
+
+ if (PyModule_AddObject(module, "openssl_md_meth_names", state.set) < 0) {
+ Py_DECREF(state.set);
+ return -1;
+ }
+
+ return 0;
}
/* LibreSSL doesn't support FIPS:
@@ -1885,94 +1890,136 @@ hashlib_free(void *m)
hashlib_clear((PyObject *)m);
}
+/* Py_mod_exec functions */
+static int
+hashlib_openssl_legacy_init(PyObject *module)
+{
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
+ /* Load all digest algorithms and initialize cpuid */
+ OPENSSL_add_all_algorithms_noconf();
+ ERR_load_crypto_strings();
+#endif
+ return 0;
+}
-static struct PyModuleDef _hashlibmodule = {
- PyModuleDef_HEAD_INIT,
- "_hashlib",
- NULL,
- sizeof(_hashlibstate),
- EVP_functions,
- NULL,
- hashlib_traverse,
- hashlib_clear,
- hashlib_free
-};
+static int
+hashlib_init_evptype(PyObject *module)
+{
+ _hashlibstate *state = get_hashlib_state(module);
-PyMODINIT_FUNC
-PyInit__hashlib(void)
+ state->EVPtype = (PyTypeObject *)PyType_FromSpec(&EVPtype_spec);
+ if (state->EVPtype == NULL) {
+ return -1;
+ }
+ if (PyModule_AddType(module, state->EVPtype) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+hashlib_init_evpxoftype(PyObject *module)
{
- PyObject *m, *openssl_md_meth_names;
- _hashlibstate *state = NULL;
#ifdef PY_OPENSSL_HAS_SHAKE
+ _hashlibstate *state = get_hashlib_state(module);
PyObject *bases;
+
+ if (state->EVPtype == NULL) {
+ return -1;
+ }
+
+ bases = PyTuple_Pack(1, state->EVPtype);
+ if (bases == NULL) {
+ return -1;
+ }
+
+ state->EVPXOFtype = (PyTypeObject *)PyType_FromSpecWithBases(
+ &EVPXOFtype_spec, bases
+ );
+ Py_DECREF(bases);
+ if (state->EVPXOFtype == NULL) {
+ return -1;
+ }
+ if (PyModule_AddType(module, state->EVPXOFtype) < 0) {
+ return -1;
+ }
#endif
+ return 0;
+}
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
- /* Load all digest algorithms and initialize cpuid */
- OPENSSL_add_all_algorithms_noconf();
- ERR_load_crypto_strings();
+static int
+hashlib_init_hmactype(PyObject *module)
+{
+ _hashlibstate *state = get_hashlib_state(module);
+
+ state->HMACtype = (PyTypeObject *)PyType_FromSpec(&HMACtype_spec);
+ if (state->HMACtype == NULL) {
+ return -1;
+ }
+ if (PyModule_AddType(module, state->HMACtype) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+#if 0
+static PyModuleDef_Slot hashlib_slots[] = {
+ /* OpenSSL 1.0.2 and LibreSSL */
+ {Py_mod_exec, hashlib_openssl_legacy_init},
+ {Py_mod_exec, hashlib_init_evptype},
+ {Py_mod_exec, hashlib_init_evpxoftype},
+ {Py_mod_exec, hashlib_init_hmactype},
+ {Py_mod_exec, hashlib_md_meth_names},
+ {0, NULL}
+};
#endif
- m = PyState_FindModule(&_hashlibmodule);
+static struct PyModuleDef _hashlibmodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_hashlib",
+ .m_doc = "OpenSSL interface for hashlib module",
+ .m_size = sizeof(_hashlibstate),
+ .m_methods = EVP_functions,
+ .m_slots = NULL,
+ .m_traverse = hashlib_traverse,
+ .m_clear = hashlib_clear,
+ .m_free = hashlib_free
+};
+
+PyMODINIT_FUNC
+PyInit__hashlib(void)
+{
+ PyObject *m = PyState_FindModule(&_hashlibmodule);
if (m != NULL) {
Py_INCREF(m);
return m;
}
m = PyModule_Create(&_hashlibmodule);
- if (m == NULL)
- return NULL;
-
- state = get_hashlib_state(m);
-
- PyTypeObject *EVPtype = (PyTypeObject *)PyType_FromSpec(&EVPtype_spec);
- if (EVPtype == NULL) {
- Py_DECREF(m);
+ if (m == NULL) {
return NULL;
}
- state->EVPtype = EVPtype;
- Py_INCREF((PyObject *)state->EVPtype);
- PyModule_AddObject(m, "HASH", (PyObject *)state->EVPtype);
- PyTypeObject *HMACtype = (PyTypeObject *)PyType_FromSpec(&HMACtype_spec);
- if (HMACtype == NULL) {
+ if (hashlib_openssl_legacy_init(m) < 0) {
Py_DECREF(m);
return NULL;
}
- state->HMACtype = HMACtype;
- Py_INCREF((PyObject *)state->HMACtype);
- PyModule_AddObject(m, "HMAC", (PyObject *)state->HMACtype);
-
-#ifdef PY_OPENSSL_HAS_SHAKE
- bases = PyTuple_Pack(1, (PyObject *)EVPtype);
- if (bases == NULL) {
+ if (hashlib_init_evptype(m) < 0) {
Py_DECREF(m);
return NULL;
}
- PyTypeObject *EVPXOFtype = (PyTypeObject *)PyType_FromSpecWithBases(
- &EVPXOFtype_spec, bases
- );
- Py_DECREF(bases);
- if (EVPXOFtype == NULL) {
+ if (hashlib_init_evpxoftype(m) < 0) {
Py_DECREF(m);
return NULL;
}
- state->EVPXOFtype = EVPXOFtype;
-
- Py_INCREF((PyObject *)state->EVPXOFtype);
- PyModule_AddObject(m, "HASHXOF", (PyObject *)state->EVPXOFtype);
-#endif
-
- openssl_md_meth_names = generate_hash_name_list();
- if (openssl_md_meth_names == NULL) {
+ if (hashlib_init_hmactype(m) < 0) {
Py_DECREF(m);
return NULL;
}
- if (PyModule_AddObject(m, "openssl_md_meth_names", openssl_md_meth_names)) {
+ if (hashlib_md_meth_names(m) == -1) {
Py_DECREF(m);
return NULL;
}
- PyState_AddModule(m, &_hashlibmodule);
return m;
}