From 3da748b73d42e3c854bae71a3ba8c027519c59b8 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 13 Jul 2026 16:54:28 +0200 Subject: [PATCH] win32: Add bindings to query the Windows certificate store --- core/sys/windows/crypt32.odin | 12 +++++ core/sys/windows/types.odin | 86 +++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 core/sys/windows/crypt32.odin diff --git a/core/sys/windows/crypt32.odin b/core/sys/windows/crypt32.odin new file mode 100644 index 000000000..93161ce59 --- /dev/null +++ b/core/sys/windows/crypt32.odin @@ -0,0 +1,12 @@ +#+build windows +package sys_windows + +foreign import crypt32 "system:crypt32.lib" + +@(default_calling_convention="system") +foreign crypt32 { + CertOpenSystemStoreW :: proc(hProv: HCRYPTPROV_LEGACY, szSubsystemProtocol: LPCWSTR) -> HCERTSTORE --- + CertCloseStore :: proc(hCertStore: HCERTSTORE, dwFlags: DWORD) -> BOOL --- + CertEnumCertificatesInStore :: proc(hCertStore: HCERTSTORE, pPrevCertContext: ^CERT_CONTEXT) -> ^CERT_CONTEXT --- + CertFreeCertificateContext :: proc(pCertContext: ^CERT_CONTEXT) -> BOOL --- +} \ No newline at end of file diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 8d2e4bf53..89a94b1da 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -5425,3 +5425,89 @@ ASSOCIATIONELEMENT :: struct { hkClass: HKEY, pszClass: PCWSTR, } + + + +HCERTSTORE :: distinct rawptr + +// This type is used where the HCRYPTPROV parameter is no longer used. +// The caller should always pass in `nil`. +HCRYPTPROV_LEGACY :: rawptr + +CERT_CLOSE_STORE_FORCE_FLAG :: 0x00000001 +CERT_CLOSE_STORE_CHECK_FLAG :: 0x00000002 + +CERT_CONTEXT :: struct { + dwCertEncodingType: DWORD, + pbCertEncoded: [^]byte, + cbCertEncoded: DWORD, + pCertInfo: ^CERT_INFO, + hCertStore: HCERTSTORE, +} + +CERT_INFO :: struct { + dwVersion: DWORD, + SerialNumber: CRYPT_INTEGER_BLOB, + SignatureAlgorithm: CRYPT_ALGORITHM_IDENTIFIER, + Issuer: CERT_NAME_BLOB, + NotBefore: FILETIME, + NotAfter: FILETIME, + Subject: CERT_NAME_BLOB, + SubjectPublicKeyInfo: CERT_PUBLIC_KEY_INFO, + IssuerUniqueId: CRYPT_BIT_BLOB, + SubjectUniqueId: CRYPT_BIT_BLOB, + cExtension: DWORD, + rgExtension: ^CERT_EXTENSION, +} + +CRYPTOAPI_BLOB :: struct { + cbData: DWORD, + pbData: [^]byte `fmt:s,cbData`, +} + +CRYPT_INTEGER_BLOB :: distinct CRYPTOAPI_BLOB +CRYPT_UINT_BLOB :: distinct CRYPTOAPI_BLOB +CRYPT_OBJID_BLOB :: distinct CRYPTOAPI_BLOB +CERT_NAME_BLOB :: distinct CRYPTOAPI_BLOB +CERT_RDN_VALUE_BLOB :: distinct CRYPTOAPI_BLOB +CERT_BLOB :: distinct CRYPTOAPI_BLOB +CRL_BLOB :: distinct CRYPTOAPI_BLOB +DATA_BLOB :: distinct CRYPTOAPI_BLOB +CRYPT_DATA_BLOB :: distinct CRYPTOAPI_BLOB +CRYPT_HASH_BLOB :: distinct CRYPTOAPI_BLOB +CRYPT_DIGEST_BLOB :: distinct CRYPTOAPI_BLOB +CRYPT_DER_BLOB :: distinct CRYPTOAPI_BLOB +CRYPT_ATTR_BLOB :: distinct CRYPTOAPI_BLOB + +//+------------------------------------------------------------------------- +// In a CRYPT_BIT_BLOB the last byte may contain 0-7 unused bits. Therefore, the +// overall bit length is cbData * 8 - cUnusedBits. +//-------------------------------------------------------------------------- +// certenrolls_begin -- CERT_CONTEXT +CRYPT_BIT_BLOB :: struct { + cbData: DWORD, + pbData: [^]byte, + cUnusedBits: DWORD, +} + +//+------------------------------------------------------------------------- +// Type used for any algorithm +// +// Where the Parameters CRYPT_OBJID_BLOB is in its encoded representation. For most +// algorithm types, the Parameters CRYPT_OBJID_BLOB is NULL (Parameters.cbData = 0). +//-------------------------------------------------------------------------- +CRYPT_ALGORITHM_IDENTIFIER :: struct { + pszObjId: LPSTR, + Parameters: CRYPT_OBJID_BLOB, +} + +CERT_PUBLIC_KEY_INFO :: struct { + Algorithm: CRYPT_ALGORITHM_IDENTIFIER, + PublicKey: CRYPT_BIT_BLOB, +} + +CERT_EXTENSION :: struct { + pszObjId: LPSTR, + fCritical: BOOL, + Value: CRYPT_OBJID_BLOB, +} \ No newline at end of file