From 5cd1c6cbf714ba356ddec3821e24e09aaa813d16 Mon Sep 17 00:00:00 2001 From: Tobiasz Laskowski Date: Sat, 7 Dec 2024 16:36:01 +0000 Subject: [PATCH] [ssl] Fix ssl cert verification failure on windows On clean windows environments, certificate verification would fail incorrectly in some cases. This uses a callback to run windows api functions to reverify whenever verification fails. --- src/hx/libs/ssl/SSL.cpp | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/hx/libs/ssl/SSL.cpp b/src/hx/libs/ssl/SSL.cpp index 1f5afe121..2c4904a82 100644 --- a/src/hx/libs/ssl/SSL.cpp +++ b/src/hx/libs/ssl/SSL.cpp @@ -397,6 +397,50 @@ Array _hx_ssl_read( Dynamic hssl ) { return result; } +#ifdef NEKO_WINDOWS +static int verify_callback(void* param, mbedtls_x509_crt *crt, int depth, uint32_t *flags) { + if (*flags == 0 || *flags & MBEDTLS_X509_BADCERT_CN_MISMATCH) { + return 0; + } + + HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL); + if(store == NULL) { + return MBEDTLS_ERR_X509_FATAL_ERROR; + } + PCCERT_CONTEXT primary_context = {0}; + if(!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, crt->raw.p, crt->raw.len, CERT_STORE_ADD_REPLACE_EXISTING, &primary_context)) { + CertCloseStore(store, 0); + return MBEDTLS_ERR_X509_FATAL_ERROR; + } + PCCERT_CHAIN_CONTEXT chain_context = {0}; + CERT_CHAIN_PARA parameters = {0}; + if(!CertGetCertificateChain(NULL, primary_context, NULL, store, ¶meters, 0, NULL, &chain_context)) { + CertFreeCertificateContext(primary_context); + CertCloseStore(store, 0); + return MBEDTLS_ERR_X509_FATAL_ERROR; + } + CERT_CHAIN_POLICY_PARA policy_parameters = {0}; + CERT_CHAIN_POLICY_STATUS policy_status = {0}; + if(!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chain_context, &policy_parameters, &policy_status)) { + CertFreeCertificateChain(chain_context); + CertFreeCertificateContext(primary_context); + CertCloseStore(store, 0); + return MBEDTLS_ERR_X509_FATAL_ERROR; + } + if(policy_status.dwError == 0) { + *flags = 0; + } else { + // if we ever want to read the verification result, + // we need to properly map dwError to flags + *flags |= MBEDTLS_X509_BADCERT_OTHER; + } + CertFreeCertificateChain(chain_context); + CertFreeCertificateContext(primary_context); + CertCloseStore(store, 0); + return 0; +} +#endif + Dynamic _hx_ssl_conf_new( bool server ) { int ret; sslconf *conf = new sslconf(); @@ -407,6 +451,9 @@ Dynamic _hx_ssl_conf_new( bool server ) { conf->destroy(); ssl_error( ret ); } +#ifdef NEKO_WINDOWS + mbedtls_ssl_conf_verify(conf->c, verify_callback, NULL); +#endif mbedtls_ssl_conf_rng( conf->c, mbedtls_ctr_drbg_random, &ctr_drbg ); return conf; }