From 2a571cb4da145a596047fe572b42486038101625 Mon Sep 17 00:00:00 2001 From: nr Date: Tue, 19 Feb 2019 00:12:01 +0700 Subject: [PATCH 1/4] Fix ssl certificate enumeration for windows This commit adds a function that collects certificates from several certificate stores into one certificate collection store that is enumerated. --- Modules/_ssl.c | 108 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 20 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 0e720e268d937a..518cc7ad54abf4 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5400,6 +5400,66 @@ parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags) return retval; } +/* + This function collects the system certificate stores listed in + system_stores into a collection certificate store for being + enumerated. The store must be readable to be added to the + store collection. +*/ +static HCERTSTORE +ssl_collect_certificates(const char *store_name) +{ + HCERTSTORE hCollectionStore = NULL; + HCERTSTORE hSystemStore = NULL; + DWORD system_stores[] = {CERT_SYSTEM_STORE_LOCAL_MACHINE, + CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, + CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, + CERT_SYSTEM_STORE_CURRENT_USER, + CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, + CERT_SYSTEM_STORE_SERVICES, + CERT_SYSTEM_STORE_USERS}; + unsigned int i; + + if (!(hCollectionStore = CertOpenStore( + CERT_STORE_PROV_COLLECTION, + 0, + (HCRYPTPROV)NULL, + 0, + NULL))) + { + return NULL; + } + + for (i=0;ipbCertEncoded, pCertCtx->cbCertEncoded); if (!cert) { @@ -5464,9 +5523,11 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) enc = NULL; PyTuple_SET_ITEM(tup, 2, keyusage); keyusage = NULL; - if (PyList_Append(result, tup) < 0) { - Py_CLEAR(result); - break; + if (!list_contains((PyListObject*)result, tup)) { + if (PyList_Append(result, tup) < 0) { + Py_CLEAR(result); + break; + } } Py_CLEAR(tup); } @@ -5481,11 +5542,15 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) Py_XDECREF(keyusage); Py_XDECREF(tup); - if (!CertCloseStore(hStore, 0)) { + /* CERT_CLOSE_STORE_FORCE_FLAG forces freeing of memory for all contexts + associated with the store, in this case our collection store and the + associated system stores. */ + if (!CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG)) { /* This error case might shadow another exception.*/ Py_XDECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); } + return result; } @@ -5505,7 +5570,7 @@ static PyObject * _ssl_enum_crls_impl(PyObject *module, const char *store_name) /*[clinic end generated code: output=bce467f60ccd03b6 input=a1f1d7629f1c5d3d]*/ { - HCERTSTORE hStore = NULL; + HCERTSTORE hCollectionStore = NULL; PCCRL_CONTEXT pCrlCtx = NULL; PyObject *crl = NULL, *enc = NULL, *tup = NULL; PyObject *result = NULL; @@ -5514,15 +5579,13 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) if (result == NULL) { return NULL; } - hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, (HCRYPTPROV)NULL, - CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, - store_name); - if (hStore == NULL) { + hCollectionStore = ssl_collect_certificates(store_name); + if (hCollectionStore == NULL) { Py_DECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); } - while (pCrlCtx = CertEnumCRLsInStore(hStore, pCrlCtx)) { + while (pCrlCtx = CertEnumCRLsInStore(hCollectionStore, pCrlCtx)) { crl = PyBytes_FromStringAndSize((const char*)pCrlCtx->pbCrlEncoded, pCrlCtx->cbCrlEncoded); if (!crl) { @@ -5542,9 +5605,11 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) PyTuple_SET_ITEM(tup, 1, enc); enc = NULL; - if (PyList_Append(result, tup) < 0) { - Py_CLEAR(result); - break; + if (!list_contains((PyListObject*)result, tup)) { + if (PyList_Append(result, tup) < 0) { + Py_CLEAR(result); + break; + } } Py_CLEAR(tup); } @@ -5558,7 +5623,10 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) Py_XDECREF(enc); Py_XDECREF(tup); - if (!CertCloseStore(hStore, 0)) { + /* CERT_CLOSE_STORE_FORCE_FLAG forces freeing of memory for all contexts + associated with the store, in this case our collection store and the + associated system stores. */ + if (!CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG)) { /* This error case might shadow another exception.*/ Py_XDECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); From 7557dca387484573578205d4f963a4a388a69db3 Mon Sep 17 00:00:00 2001 From: nr Date: Tue, 19 Feb 2019 00:50:28 +0700 Subject: [PATCH 2/4] Fix ssl certificate enumeration for windows This commit adds a function that collects certificates from several certificate stores into one certificate collection store that is enumerated. --- Modules/_ssl.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 518cc7ad54abf4..91da2f9d38a292 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5419,6 +5419,7 @@ ssl_collect_certificates(const char *store_name) CERT_SYSTEM_STORE_SERVICES, CERT_SYSTEM_STORE_USERS}; unsigned int i; + unsigned int storesAdded; if (!(hCollectionStore = CertOpenStore( CERT_STORE_PROV_COLLECTION, @@ -5430,6 +5431,7 @@ ssl_collect_certificates(const char *store_name) return NULL; } + storesAdded = 0; for (i=0;i Date: Wed, 20 Feb 2019 02:27:54 +0700 Subject: [PATCH 3/4] adjust code to PEP 7 --- Modules/_ssl.c | 60 ++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 91da2f9d38a292..66e22695f3b878 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5400,54 +5400,46 @@ parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags) return retval; } -/* - This function collects the system certificate stores listed in - system_stores into a collection certificate store for being - enumerated. The store must be readable to be added to the - store collection. -*/ static HCERTSTORE ssl_collect_certificates(const char *store_name) { - HCERTSTORE hCollectionStore = NULL; - HCERTSTORE hSystemStore = NULL; - DWORD system_stores[] = {CERT_SYSTEM_STORE_LOCAL_MACHINE, +/* this function collects the system certificate stores listed in + * system_stores into a collection certificate store for being + * enumerated. The store must be readable to be added to the + * store collection. + */ + + HCERTSTORE hCollectionStore = NULL, hSystemStore = NULL; + static DWORD system_stores[] = { + CERT_SYSTEM_STORE_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, CERT_SYSTEM_STORE_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, CERT_SYSTEM_STORE_SERVICES, CERT_SYSTEM_STORE_USERS}; - unsigned int i; - unsigned int storesAdded; - - if (!(hCollectionStore = CertOpenStore( - CERT_STORE_PROV_COLLECTION, - 0, - (HCRYPTPROV)NULL, - 0, - NULL))) - { + size_t i, storesAdded; + BOOL result; + + hCollectionStore = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, + (HCRYPTPROV)NULL, 0, NULL); + if (!hCollectionStore) { return NULL; } - storesAdded = 0; - for (i=0;i Date: Thu, 28 Mar 2019 03:51:17 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Windows/2019-03-28-03-51-16.bpo-35941.UnlAEE.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Windows/2019-03-28-03-51-16.bpo-35941.UnlAEE.rst diff --git a/Misc/NEWS.d/next/Windows/2019-03-28-03-51-16.bpo-35941.UnlAEE.rst b/Misc/NEWS.d/next/Windows/2019-03-28-03-51-16.bpo-35941.UnlAEE.rst new file mode 100644 index 00000000000000..cda654bfa5b9aa --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-03-28-03-51-16.bpo-35941.UnlAEE.rst @@ -0,0 +1,3 @@ +enum_certificates function of the ssl module now returns certificates from all available certificate stores inside windows in a query instead of returning only certificates from the system wide certificate store. +This includes certificates from these certificate stores: local machine, local machine enterprise, local machine group policy, current user, current user group policy, services, users. +ssl.enum_crls() function is changed in the same way to return all certificate revocation lists inside the windows certificate revocation list stores. \ No newline at end of file