diff --git a/misc/windows/min-wincrypt.h b/misc/windows/min-wincrypt.h index b2ebe1fb7..07aed556f 100644 --- a/misc/windows/min-wincrypt.h +++ b/misc/windows/min-wincrypt.h @@ -2,6 +2,18 @@ #define CC_CRYPT32_FUNC #endif +typedef void* HCERTSTORE; +typedef void* PCCERT_CONTEXT; +typedef void* PCCERT_CHAIN_CONTEXT; + +#define szOID_PKIX_KP_SERVER_AUTH "1.3.6.1.5.5.7.3.1" +#define szOID_SERVER_GATED_CRYPTO "1.3.6.1.4.1.311.10.3.3" +#define szOID_SGC_NETSCAPE "2.16.840.1.113730.4.1" + +#define CERT_STORE_PROV_MEMORY ((LPCSTR)2) +#define CERT_STORE_ADD_ALWAYS 4 +#define X509_ASN_ENCODING 0x1 + typedef struct _CRYPTOAPI_BLOB { DWORD cbData; BYTE* pbData; @@ -29,14 +41,22 @@ typedef struct _CERT_CHAIN_PARA { CC_CRYPT32_FUNC BOOL (WINAPI *_CryptProtectData )(DATA_BLOB* dataIn, PCWSTR dataDescr, PVOID entropy, PVOID reserved, PVOID promptStruct, DWORD flags, DATA_BLOB* dataOut); CC_CRYPT32_FUNC BOOL (WINAPI *_CryptUnprotectData)(DATA_BLOB* dataIn, PWSTR* dataDescr, PVOID entropy, PVOID reserved, PVOID promptStruct, DWORD flags, DATA_BLOB* dataOut); -/*CC_CRYPT32_FUNC BOOL (WINAPI *_CertGetCertificateChain)(PVOID chainEngine, PCCERT_CONTEXT certContext, LPFILETIME time, HCERTSTORE additionalStore, CERT_CHAIN_PARA* chainPara, DWORD flags, PVOID reserved, PCCERT_CHAIN_CONTEXT* chainContext); +CC_CRYPT32_FUNC HCERTSTORE (WINAPI *_CertOpenStore)(LPCSTR storeProvider, DWORD encodingType, void* cryptProv, DWORD flags, const void* para); +CC_CRYPT32_FUNC BOOL (WINAPI *_CertCloseStore)(HCERTSTORE certStore, DWORD flags); +CC_CRYPT32_FUNC BOOL (WINAPI *_CertAddEncodedCertificateToStore)(HCERTSTORE certStore, DWORD certEncodingType, const BYTE* certEncoded, DWORD lenEncoded, DWORD addDisposition, PCCERT_CONTEXT* certContext); -CC_CRYPT32_FUNC void (WINAPI *_CertFreeCertificateChain)(PCCERT_CHAIN_CONTEXT chainContext);*/ +CC_CRYPT32_FUNC BOOL (WINAPI *_CertGetCertificateChain)(PVOID chainEngine, PCCERT_CONTEXT certContext, LPFILETIME time, HCERTSTORE additionalStore, CERT_CHAIN_PARA* chainPara, DWORD flags, PVOID reserved, PCCERT_CHAIN_CONTEXT* chainContext); +CC_CRYPT32_FUNC void (WINAPI *_CertFreeCertificateChain)(PCCERT_CHAIN_CONTEXT chainContext); + +CC_CRYPT32_FUNC BOOL (WINAPI *_CertFreeCertificateContext)(PCCERT_CONTEXT certContext); static void Crypt32_LoadDynamicFuncs(void) { static const struct DynamicLibSym funcs[] = { - DynamicLib_OptSym(CryptProtectData), DynamicLib_OptSym(CryptUnprotectData), - //DynamicLib_OptSym(CertGetCertificateChain), DynamicLib_OptSym(CertFreeCertificateChain), + DynamicLib_OptSym(CryptProtectData), DynamicLib_OptSym(CryptUnprotectData), + DynamicLib_ReqSym(CertGetCertificateChain), DynamicLib_ReqSym(CertFreeCertificateChain), + DynamicLib_ReqSym(CertOpenStore), DynamicLib_ReqSym(CertCloseStore), + DynamicLib_ReqSym(CertAddEncodedCertificateToStore), + DynamicLib_ReqSym(CertFreeCertificateContext), }; static const cc_string crypt32 = String_FromConst("CRYPT32.DLL"); diff --git a/src/Certs.c b/src/Certs.c index 564e6ba0e..4bebe6336 100644 --- a/src/Certs.c +++ b/src/Certs.c @@ -300,64 +300,61 @@ int Certs_VerifyChain(struct X509CertContext* x509) { #define UNICODE #define _UNICODE #endif -#include -/* -#include -*/ -/* Compatibility versions so compiling works on older Windows SDKs */ -//#include "../misc/windows/min-wincrypt.h" -#include +#include +/* Compatibility versions so compiling works on older Windows SDKs */ +#include "../misc/windows/min-wincrypt.h" /* #include */ void CertsBackend_Init(void) { - //Crypt32_LoadDynamicFuncs(); + Crypt32_LoadDynamicFuncs(); } +static const LPCSTR const usage[] = { + szOID_PKIX_KP_SERVER_AUTH, + szOID_SERVER_GATED_CRYPTO, + szOID_SGC_NETSCAPE +}; + int Certs_VerifyChain(struct X509CertContext* x509) { struct X509Cert* cert = &x509->certs[0]; + CERT_CHAIN_PARA para = { 0 }; + PCCERT_CHAIN_CONTEXT chain; + PCCERT_CONTEXT end_cert; + HCERTSTORE store; + BOOL ok; int i; - HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, - CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL); + if (!_CertOpenStore) return ERR_NOT_SUPPORTED; + store = _CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); if (!store) return ERR_NOT_SUPPORTED; - PCCERT_CONTEXT primary_cert = NULL; - BOOL ok = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, cert->data, cert->offset, - CERT_STORE_ADD_ALWAYS, &primary_cert); - if (!ok || !primary_cert) + end_cert = NULL; + ok = _CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, cert->data, cert->offset, + CERT_STORE_ADD_ALWAYS, &end_cert); + if (!ok || !end_cert) return -1; for (i = 1; i < x509->numCerts; i++) { cert = &x509->certs[i]; - ok = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, cert->data, cert->offset, + ok = _CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, cert->data, cert->offset, CERT_STORE_ADD_ALWAYS, NULL); } - //if (!_CertGetCertificateChain) return ERR_NOT_SUPPORTED; - static const LPCSTR usage[] = { - szOID_PKIX_KP_SERVER_AUTH, - szOID_SERVER_GATED_CRYPTO, - szOID_SGC_NETSCAPE - }; - - CERT_CHAIN_PARA para = { 0 }; para.cbSize = sizeof(para); - para.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; para.RequestedUsage.Usage.cUsageIdentifier = Array_Elems(usage); - para.RequestedUsage.Usage.rgpszUsageIdentifier = usage; + para.RequestedUsage.Usage.rgpszUsageIdentifier = (LPSTR*)usage; - PCCERT_CHAIN_CONTEXT chain = NULL; - ok = CertGetCertificateChain(NULL, primary_cert, NULL, NULL, ¶, 0, NULL, &chain); - //_CertGetCertificateChain(NULL, PCCERT_CONTEXT certContext, NULL, HCERTSTORE additionalStore, PCERT_CHAIN_PARA chainPara, DWORD flags, PVOID reserved, PCCERT_CHAIN_CONTEXT* chainContext); + chain = NULL; + ok = _CertGetCertificateChain(NULL, end_cert, NULL, NULL, ¶, 0, NULL, &chain); + // TODO look at dwErrorStatus - CertFreeCertificateChain(chain); - ok = CertFreeCertificateContext(primary_cert); - ok = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG); + _CertFreeCertificateChain(chain); + ok = _CertFreeCertificateContext(end_cert); + ok = _CertCloseStore(store, 0); // TODO check memory all released return ERR_NOT_SUPPORTED; } - #endif #endif