Howdy,

I am trying to import a PFX/P12 certificate to the local machine certificate 
store and there’s no errors, but it also doesn’t seem to work either.

I’ve left a bit of debugging code in the script to show all the things I’ve 
tried, but again there’s no errors, and it generates the PyStore object like 
the docs say it will and I enumerate the certificates in the store with a for 
loop, BUT it doesn’t seem to add the PFX to the store (or at least I can’t see 
it in the Certificates MMC app for the local machine).

I can manually import the PFX by using the CryptoAPI  “Install PFX” option from 
the windows explorer shell just fine, but the win32crypt.PFXImportCertStore() 
call doesn’t error, but it also enumerates the machine store certs without the 
“newly added” PFX.

# this is output from the script in the for loop at the bottom from the 
attached python script – these 2 certificates existed prior to the PFX trying 
to get imported
1 Cert: <PyCERT_CONTEXT object at 0x000001D0103736B0>
2 CertEnumCertificateContextProperties returned: []
3 cert.Subject: w22test001.manross.net
4 cert Serial Number: redacted
5 Issuer: redacted
6 NotBefore: redacted
7 NotAfter: redacted

1 Cert: <PyCERT_CONTEXT object at 0x000001D010373920>
2 CertEnumCertificateContextProperties returned: [2, 11]
3 cert.Subject: w22test001.manross.net
4 cert Serial Number: redacted
5 Issuer: redacted
6 NotBefore: redacted
7 NotAfter: redacted

Please and thank you,
Steven
# ran on Windows Server 2022, and Windows Server 2016 (can test Windows Server 
2019 if needed)
# Python 3.11.9 (tags/v3.11.9:de54cf5, Apr  2 2024, 10:12:12) [MSC v.1938 64 
bit (AMD64)]
# pywin32==306

import win32crypt
import getpass
import datetime

CERT_STORE_PROV_SYSTEM = 0x0000000A
CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000
CERT_STORE_MAXIMUM_ALLOWED_FLAG = 0x00001000
X509_ASN_ENCODING= 0x00000001
PKCS_7_ASN_ENCODING= 0x00010000
PKCS_7_OR_X509_ASN_ENCODING= PKCS_7_ASN_ENCODING | X509_ASN_ENCODING
CERT_STORE_ADD_NEW = 1
CRYPT_STRING_BASE64HEADER = 0x00000000
CERT_STORE_ADD_REPLACE_EXISTING = 3

CRYPT_EXPORTABLE = 0x00000001
CRYPT_MACHINE_KEYSET = 0x00000020

def 
import_certificate_to_the_windows_certificate_store_for_local_machine(cert_file_name,
 password):
    # open and read the cert
    cert_file = open(cert_file_name, "rb")
    p12_data = cert_file.read() # this is a P12/PFX file that is secured by a 
password
    
    # crypt the cert to the expected type 
    #     Don't need this for PFXs (I think) because its already bytes (from 
the loaded p12_data -- opened from file)
    # cert_byte = win32crypt.CryptStringToBinary(p12_data, 0x00000000)[0]

    # # Add the certificate to the store (wrong kind of import for this -- just 
a certificate without the P12/PFX encoding/encryption/password)
    # store.CertAddEncodedCertificateToStore(
    #     X509_ASN_ENCODING,
    #     p12_data,
    #     CERT_STORE_ADD_REPLACE_EXISTING
    # )

    # 
https://timgolden.me.uk/pywin32-docs/win32crypt__PFXImportCertStore_meth.html
    # constants: 
https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-pfximportcertstore
    # imports to the store because of CRYPT_MACHINE_KEYSET
    store = win32crypt.PFXImportCertStore(p12_data, password, CRYPT_EXPORTABLE 
| CRYPT_MACHINE_KEYSET | PKCS12_INCLUDE_EXTENDED_PROPERTIES)

    # the previous call creates a store object so this isn’t needed - open 
the LOCAL_LACHINE "Personal" certificates store
    # store = win32crypt.CertOpenStore(
    #     CERT_STORE_PROV_SYSTEM,
    #     0,
    #     None,
    #     CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
    #     "My"
    # )

    # however, even though the store enumerates, it doesn’t show the PFX that 
was just imported
    for mscert in store.CertEnumCertificatesInStore():
        print( "1 Cert: {0:}".format(mscert))
        print( "2 CertEnumCertificateContextProperties returned: 
{0:}".format(mscert.CertEnumCertificateContextProperties()))
        print( "3 cert.Subject: 
{0:}".format(win32crypt.CertNameToStr(mscert.Subject)))
        print(f"4 cert Serial Number: {mscert.SerialNumber.hex()}")
        print(f"5 Issuer: {win32crypt.CertNameToStr(mscert.Issuer)}")
        print(f"6 NotBefore: 
{datetime.datetime.fromtimestamp(mscert.NotBefore.timestamp()).astimezone(mscert.NotBefore.tzinfo)}")
        print(f"7 NotAfter: 
{datetime.datetime.fromtimestamp(mscert.NotAfter.timestamp()).astimezone(mscert.NotAfter.tzinfo)}")
        print()

if __name__ == "__main__":
    cert_file_name = f"c:\\scripts\\certs\\w22test001.manross.net-winrm.pfx"
    password = getpass.getpass(prompt="PFX Password:", stream=None)
    
import_certificate_to_the_windows_certificate_store_for_local_machine(cert_file_name,
 password)


_______________________________________________
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32

Reply via email to