Skip to content

Commit a1e75f9

Browse files
authored
[ssl] Fix ssl cert verification failure on windows (#1164)
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.
1 parent 3acb855 commit a1e75f9

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

src/hx/libs/ssl/SSL.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,50 @@ Array<unsigned char> _hx_ssl_read( Dynamic hssl ) {
397397
return result;
398398
}
399399

400+
#ifdef NEKO_WINDOWS
401+
static int verify_callback(void* param, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
402+
if (*flags == 0 || *flags & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
403+
return 0;
404+
}
405+
406+
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL);
407+
if(store == NULL) {
408+
return MBEDTLS_ERR_X509_FATAL_ERROR;
409+
}
410+
PCCERT_CONTEXT primary_context = {0};
411+
if(!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, crt->raw.p, crt->raw.len, CERT_STORE_ADD_REPLACE_EXISTING, &primary_context)) {
412+
CertCloseStore(store, 0);
413+
return MBEDTLS_ERR_X509_FATAL_ERROR;
414+
}
415+
PCCERT_CHAIN_CONTEXT chain_context = {0};
416+
CERT_CHAIN_PARA parameters = {0};
417+
if(!CertGetCertificateChain(NULL, primary_context, NULL, store, &parameters, 0, NULL, &chain_context)) {
418+
CertFreeCertificateContext(primary_context);
419+
CertCloseStore(store, 0);
420+
return MBEDTLS_ERR_X509_FATAL_ERROR;
421+
}
422+
CERT_CHAIN_POLICY_PARA policy_parameters = {0};
423+
CERT_CHAIN_POLICY_STATUS policy_status = {0};
424+
if(!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chain_context, &policy_parameters, &policy_status)) {
425+
CertFreeCertificateChain(chain_context);
426+
CertFreeCertificateContext(primary_context);
427+
CertCloseStore(store, 0);
428+
return MBEDTLS_ERR_X509_FATAL_ERROR;
429+
}
430+
if(policy_status.dwError == 0) {
431+
*flags = 0;
432+
} else {
433+
// if we ever want to read the verification result,
434+
// we need to properly map dwError to flags
435+
*flags |= MBEDTLS_X509_BADCERT_OTHER;
436+
}
437+
CertFreeCertificateChain(chain_context);
438+
CertFreeCertificateContext(primary_context);
439+
CertCloseStore(store, 0);
440+
return 0;
441+
}
442+
#endif
443+
400444
Dynamic _hx_ssl_conf_new( bool server ) {
401445
int ret;
402446
sslconf *conf = new sslconf();
@@ -407,6 +451,9 @@ Dynamic _hx_ssl_conf_new( bool server ) {
407451
conf->destroy();
408452
ssl_error( ret );
409453
}
454+
#ifdef NEKO_WINDOWS
455+
mbedtls_ssl_conf_verify(conf->c, verify_callback, NULL);
456+
#endif
410457
mbedtls_ssl_conf_rng( conf->c, mbedtls_ctr_drbg_random, &ctr_drbg );
411458
return conf;
412459
}

0 commit comments

Comments
 (0)