Search code examples
pythonwindowswinapicertificatepywin32

Access windows local machine store with Python win32crypt


I'm trying to access a certificate, that's stored in windows local machine store. This can't be done with wincertstore, as it uses CertOpenSystemStoreA function (see remarks: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopensystemstorea)

However CertOpenStore from pywin32 has access, I just don't know how to pass the right parameters. Here's my code:

import win32crypt

# store provider
CERT_STORE_PROV_SYSTEM = 13
#dwFlags
CERT_SYSTEM_STORE_CURRENT_SERVICE = 0x0100
CERT_SYSTEM_STORE_CURRENT_USER = 0x0200
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY = 0x0400
CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x0800
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE = 0x1000
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY = 0x2000
CERT_SYSTEM_STORE_SERVICES = 0x4000
CERT_SYSTEM_STORE_USERS = 0x8000

store = win32crypt.CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, None, CERT_SYSTEM_STORE_LOCAL_MACHINE, "MY")
for cert in store.CertEnumCertificatesInStore():
    print("1 Cert: " + str(cert))
    print("2 CertEnumCertificateContextProperties: " + str(cert.CertEnumCertificateContextProperties()))
    print("3 cert.Subject: " + str(win32crypt.CertNameToStr(cert.Subject)))

When running, I get an exception: (-2147024809, 'CertOpenStore', 'Wrong Parameter.')

Documentation of CertOpenStore in pywin32: http://timgolden.me.uk/pywin32-docs/win32crypt__CertOpenStore_meth.html Documentaion of CertOpenStore in Windows Dev Center: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopenstore


Solution

  • You messed up the constants. I don't know where you got them from, but the values (at least both that you used) are wrong, so I deleted them all (didn't look at the others). They (or most of them) are preprocessor macros, defined in [MS.Learn]: wincrypt.h header (part of Windows SDK - unfortunately I didn't find an official location on the web where it could be downloaded from - I have it on my laptop, as it was automatically installed by Visual Studio).

    code00.py:

    #!/usr/bin/env python
    
    import sys
    import win32crypt as wcrypt
    
    
    # lpszStoreProvider
    CERT_STORE_PROV_SYSTEM = 0x0000000A
    
    # dwFlags
    CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000
    
    
    def main(*argv):
        store = wcrypt.CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, None, CERT_SYSTEM_STORE_LOCAL_MACHINE, "My")
    
        for cert in store.CertEnumCertificatesInStore():
            print("1 Cert: {0:}".format(cert))
            print("2 CertEnumCertificateContextProperties returned: {0:}".format(cert.CertEnumCertificateContextProperties()))
            print("3 cert.Subject: {0:}".format(wcrypt.CertNameToStr(cert.Subject)))
    
    
    if __name__ == "__main__":
        print(
            "Python {:s} {:03d}bit on {:s}\n".format(
                " ".join(elem.strip() for elem in sys.version.split("\n")),
                64 if sys.maxsize > 0x100000000 else 32,
                sys.platform,
            )
        )
        rc = main(*sys.argv[1:])
        print("\nDone.\n")
        sys.exit(rc)
    

    Output:

    [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q061118677]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" ./code00.py
    Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 064bit on win32
    
    1 Cert: <PyCERT_CONTEXT object at 0x0000021CDE3BD740>
    2 CertEnumCertificateContextProperties returned: [92, 15, 20, 11, 2, 3, 4, 25, 89]
    3 cert.Subject: localhost
    
    Done.