Skip to content

Commit 22da087

Browse files
authored
[ssl] Fix cert verification failure on windows (#293)
This uses an mbedtls callback to call some windows api functions if verification fails, which avoids certain failures in clean windows environments.
1 parent 68ab7dd commit 22da087

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

libs/ssl/ssl.c

+47
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,50 @@ static value ssl_read( value ssl ) {
288288
return buffer_to_string(b);
289289
}
290290

291+
#ifdef _WIN32
292+
static int verify_callback(void* param, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
293+
if (*flags == 0 || *flags & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
294+
return 0;
295+
}
296+
297+
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL);
298+
if(store == NULL) {
299+
return MBEDTLS_ERR_X509_FATAL_ERROR;
300+
}
301+
PCCERT_CONTEXT primary_context = {0};
302+
if(!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, crt->raw.p, crt->raw.len, CERT_STORE_ADD_REPLACE_EXISTING, &primary_context)) {
303+
CertCloseStore(store, 0);
304+
return MBEDTLS_ERR_X509_FATAL_ERROR;
305+
}
306+
PCCERT_CHAIN_CONTEXT chain_context = {0};
307+
CERT_CHAIN_PARA parameters = {0};
308+
if(!CertGetCertificateChain(NULL, primary_context, NULL, store, &parameters, 0, NULL, &chain_context)) {
309+
CertFreeCertificateContext(primary_context);
310+
CertCloseStore(store, 0);
311+
return MBEDTLS_ERR_X509_FATAL_ERROR;
312+
}
313+
CERT_CHAIN_POLICY_PARA policy_parameters = {0};
314+
CERT_CHAIN_POLICY_STATUS policy_status = {0};
315+
if(!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chain_context, &policy_parameters, &policy_status)) {
316+
CertFreeCertificateChain(chain_context);
317+
CertFreeCertificateContext(primary_context);
318+
CertCloseStore(store, 0);
319+
return MBEDTLS_ERR_X509_FATAL_ERROR;
320+
}
321+
if(policy_status.dwError == 0) {
322+
*flags = 0;
323+
} else {
324+
// if we ever want to read the verification result,
325+
// we need to properly map dwError to flags
326+
*flags |= MBEDTLS_X509_BADCERT_OTHER;
327+
}
328+
CertFreeCertificateChain(chain_context);
329+
CertFreeCertificateContext(primary_context);
330+
CertCloseStore(store, 0);
331+
return 0;
332+
}
333+
#endif
334+
291335
static value conf_new( value server ) {
292336
int ret;
293337
mbedtls_ssl_config *conf;
@@ -299,6 +343,9 @@ static value conf_new( value server ) {
299343
mbedtls_ssl_config_free(conf);
300344
return ssl_error( ret );
301345
}
346+
#ifdef NEKO_WINDOWS
347+
mbedtls_ssl_conf_verify( conf, verify_callback, NULL );
348+
#endif
302349
mbedtls_ssl_conf_rng( conf, mbedtls_ctr_drbg_random, &ctr_drbg );
303350
return alloc_abstract( k_ssl_conf, conf );
304351
}

0 commit comments

Comments
 (0)