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