[Python-checkins] bpo-40671: Prepare _hashlib for PEP 489 (GH-20180)

Christian Heimes webhook-mailer at python.org
Mon May 25 04:44:56 EDT 2020


https://github.com/python/cpython/commit/20c22db602bf2a51f5231433b9054290f8069b90
commit: 20c22db602bf2a51f5231433b9054290f8069b90
branch: master
author: Christian Heimes <christian at python.org>
committer: GitHub <noreply at github.com>
date: 2020-05-25T10:44:51+02:00
summary:

bpo-40671: Prepare _hashlib for PEP 489 (GH-20180)

files:
A Misc/NEWS.d/next/Library/2020-05-18-15-26-31.bpo-40671.NeZ9Cy.rst
M Modules/_hashopenssl.c

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 0000000000000..d38b88dbf356d
--- /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 674bddc090a6f..0b2ef95a6f126 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;
 }



More information about the Python-checkins mailing list