@ -5400,6 +5400,68 @@ parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags)
return retval ;
}
static HCERTSTORE
ssl_collect_certificates ( const char * store_name )
{
/* 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 } ;
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 < sizeof ( system_stores ) / sizeof ( DWORD ) ; i + + ) {
hSystemStore = CertOpenStore ( CERT_STORE_PROV_SYSTEM_A , 0 ,
( HCRYPTPROV ) NULL ,
CERT_STORE_READONLY_FLAG |
system_stores [ i ] , store_name ) ;
if ( hSystemStore ) {
result = CertAddStoreToCollection ( hCollectionStore , hSystemStore ,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , 0 ) ;
if ( result ) {
+ + storesAdded ;
}
}
}
if ( storesAdded = = 0 ) {
CertCloseStore ( hCollectionStore , CERT_CLOSE_STORE_FORCE_FLAG ) ;
return NULL ;
}
return hCollectionStore ;
}
/* code from Objects/listobject.c */
static int
list_contains ( PyListObject * a , PyObject * el )
{
Py_ssize_t i ;
int cmp ;
for ( i = 0 , cmp = 0 ; cmp = = 0 & & i < Py_SIZE ( a ) ; + + i )
cmp = PyObject_RichCompareBool ( el , PyList_GET_ITEM ( a , i ) ,
Py_EQ ) ;
return cmp ;
}
/*[clinic input]
_ssl . enum_certificates
store_name : str
@ -5417,7 +5479,7 @@ static PyObject *
_ssl_enum_certificates_impl ( PyObject * module , const char * store_name )
/*[clinic end generated code: output=5134dc8bb3a3c893 input=915f60d70461ea4e]*/
{
HCERTSTORE hStore = NULL ;
HCERTSTORE hCollection Store = NULL ;
PCCERT_CONTEXT pCertCtx = NULL ;
PyObject * keyusage = NULL , * cert = NULL , * enc = NULL , * tup = NULL ;
PyObject * result = NULL ;
@ -5426,15 +5488,13 @@ _ssl_enum_certificates_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 ( pCertCtx = CertEnumCertificatesInStore ( hStore , pCertCtx ) ) {
while ( pCertCtx = CertEnumCertificatesInStore ( hCollection Store , pCertCtx ) ) {
cert = PyBytes_FromStringAndSize ( ( const char * ) pCertCtx - > pbCertEncoded ,
pCertCtx - > cbCertEncoded ) ;
if ( ! cert ) {
@ -5464,9 +5524,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 +5543,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 +5571,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 hCollection Store = NULL ;
PCCRL_CONTEXT pCrlCtx = NULL ;
PyObject * crl = NULL , * enc = NULL , * tup = NULL ;
PyObject * result = NULL ;
@ -5514,15 +5580,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 ( hCollection Store , pCrlCtx ) ) {
crl = PyBytes_FromStringAndSize ( ( const char * ) pCrlCtx - > pbCrlEncoded ,
pCrlCtx - > cbCrlEncoded ) ;
if ( ! crl ) {
@ -5542,9 +5606,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 +5624,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 ( ) ) ;