diff --git a/misc/windows/min-wincrypt.h b/misc/windows/min-wincrypt.h index 07aed556f..6c0f30026 100644 --- a/misc/windows/min-wincrypt.h +++ b/misc/windows/min-wincrypt.h @@ -4,7 +4,6 @@ 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" @@ -37,6 +36,25 @@ typedef struct _CERT_CHAIN_PARA { CERT_USAGE_MATCH RequestedUsage; } CERT_CHAIN_PARA; +typedef struct _CERT_TRUST_STATUS { + DWORD dwErrorStatus; + DWORD dwInfoStatus; +} CERT_TRUST_STATUS, *PCERT_TRUST_STATUS; + +typedef struct _CERT_CHAIN_CONTEXT { + DWORD cbSize; + CERT_TRUST_STATUS TrustStatus; + DWORD cChain; + void* rgpChain; + DWORD cLowerQualityChainContext; + void* rgpLowerQualityChainContext; + BOOL fHasRevocationFreshnessTime; + DWORD dwRevocationFreshnessTime; + DWORD dwCreateFlags; + GUID ChainId; +} CERT_CHAIN_CONTEXT, *PCERT_CHAIN_CONTEXT; +typedef const CERT_CHAIN_CONTEXT* PCCERT_CHAIN_CONTEXT; + 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); diff --git a/readme.md b/readme.md index 9bbc24b7a..a12917b7b 100644 --- a/readme.md +++ b/readme.md @@ -139,7 +139,7 @@ Setting up TCC: Compiling with TCC: 1. Navigate to the directory with ClassiCube's source code 2. In `ExtMath.c`, change `fabsf` to `fabs` and `sqrtf` to `sqrt` -3. Run `tcc.exe -o ClassiCube.exe *.c -lwinmm -lgdi32 -luser32 -lcomdlg32 -lshell32`
+3. Run `tcc.exe -o ClassiCube.exe src/*.c third_party/bearssl/*.c -lwinmm -lgdi32 -luser32 -lcomdlg32 -lshell32`
(Note: You may need to specify the full path to `tcc.exe` instead of just `tcc.exe`) ## Compiling - Linux diff --git a/src/Certs.c b/src/Certs.c index 4bebe6336..c96bef581 100644 --- a/src/Certs.c +++ b/src/Certs.c @@ -315,30 +315,21 @@ static const LPCSTR const usage[] = { szOID_SGC_NETSCAPE }; -int Certs_VerifyChain(struct X509CertContext* x509) { - struct X509Cert* cert = &x509->certs[0]; +static BOOL BuildChain(struct X509CertContext* x509, HCERTSTORE store, PCCERT_CONTEXT* end_cert, PCCERT_CHAIN_CONTEXT* chain) { + struct X509Cert* cert; CERT_CHAIN_PARA para = { 0 }; - PCCERT_CHAIN_CONTEXT chain; - PCCERT_CONTEXT end_cert; - HCERTSTORE store; - BOOL ok; int i; - if (!_CertOpenStore) return ERR_NOT_SUPPORTED; - store = _CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); - if (!store) return ERR_NOT_SUPPORTED; - - 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; + BOOL ok = _CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, cert->data, cert->offset, + CERT_STORE_ADD_ALWAYS, end_cert); + if (!ok || !(*end_cert)) return FALSE; 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); + } para.cbSize = sizeof(para); @@ -346,13 +337,30 @@ int Certs_VerifyChain(struct X509CertContext* x509) { para.RequestedUsage.Usage.cUsageIdentifier = Array_Elems(usage); para.RequestedUsage.Usage.rgpszUsageIdentifier = (LPSTR*)usage; - chain = NULL; - ok = _CertGetCertificateChain(NULL, end_cert, NULL, NULL, ¶, 0, NULL, &chain); - // TODO look at dwErrorStatus + return _CertGetCertificateChain(NULL, *end_cert, NULL, NULL, ¶, 0, NULL, chain); +} + +int Certs_VerifyChain(struct X509CertContext* x509) { + struct X509Cert* cert = &x509->certs[0]; + PCCERT_CHAIN_CONTEXT chain = NULL; + PCCERT_CONTEXT end_cert = NULL; + HCERTSTORE store; + DWORD res = 200; + BOOL ok; + + if (!_CertOpenStore) return ERR_NOT_SUPPORTED; + store = _CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); + if (!store) return ERR_NOT_SUPPORTED; + + ok = BuildChain(x509, store, &end_cert, &chain); + if (ok) { + res = chain->TrustStatus.dwErrorStatus; + if (res) Platform_Log1("Cert validation failed: %h", &res); + } _CertFreeCertificateChain(chain); ok = _CertFreeCertificateContext(end_cert); - ok = _CertCloseStore(store, 0); // TODO check memory all released + ok = _CertCloseStore(store, 0); return ERR_NOT_SUPPORTED; } #endif