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
[email protected]
https://mail.python.org/mailman/listinfo/python-win32