fix: exception when reading system certificates via nodejs (#49028)

This commit is contained in:
Robo
2025-11-22 00:35:05 +09:00
committed by GitHub
parent 2200a70e8d
commit 79e17ce4be
2 changed files with 75 additions and 0 deletions

View File

@@ -42,3 +42,4 @@ api_promote_deprecation_of_v8_context_and_v8_object_api_methods.patch
src_use_cp_utf8_for_wide_file_names_on_win32.patch
fix_ensure_traverseparent_bails_on_resource_path_exit.patch
reland_temporal_unflag_temporal.patch
src_handle_der_decoding_errors_from_system_certificates.patch

View File

@@ -0,0 +1,74 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joyee Cheung <joyeec9h3@gmail.com>
Date: Thu, 20 Nov 2025 13:50:28 +0900
Subject: src: handle DER decoding errors from system certificates
When decoding certificates from the system store, it's not actually
guaranteed to succeed. In case the system returns a certificate
that cannot be decoded (might be related to SSL implementation issues),
skip them.
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index 96f6ea29525bc2c60297e7be5bc1d0b74cd568e1..9b83f8d6b2c7639044e739a7f055e457882370a2 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -507,7 +507,11 @@ void ReadMacOSKeychainCertificates(
CFRelease(search);
if (ortn) {
- fprintf(stderr, "ERROR: SecItemCopyMatching failed %d\n", ortn);
+ per_process::Debug(DebugCategory::CRYPTO,
+ "Cannot read certificates from system because "
+ "SecItemCopyMatching failed %d\n",
+ ortn);
+ return;
}
CFIndex count = CFArrayGetCount(curr_anchors);
@@ -518,7 +522,9 @@ void ReadMacOSKeychainCertificates(
CFDataRef der_data = SecCertificateCopyData(cert_ref);
if (!der_data) {
- fprintf(stderr, "ERROR: SecCertificateCopyData failed\n");
+ per_process::Debug(DebugCategory::CRYPTO,
+ "Skipping read of a system certificate "
+ "because SecCertificateCopyData failed\n");
continue;
}
auto data_buffer_pointer = CFDataGetBytePtr(der_data);
@@ -526,9 +532,19 @@ void ReadMacOSKeychainCertificates(
X509* cert =
d2i_X509(nullptr, &data_buffer_pointer, CFDataGetLength(der_data));
CFRelease(der_data);
+
+ if (cert == nullptr) {
+ per_process::Debug(DebugCategory::CRYPTO,
+ "Skipping read of a system certificate "
+ "because decoding failed\n");
+ continue;
+ }
+
bool is_valid = IsCertificateTrustedForPolicy(cert, cert_ref);
if (is_valid) {
system_root_certificates_X509->emplace_back(cert);
+ } else {
+ X509_free(cert);
}
}
CFRelease(curr_anchors);
@@ -638,7 +654,14 @@ void GatherCertsForLocation(std::vector<X509*>* vector,
reinterpret_cast<const unsigned char*>(cert_from_store->pbCertEncoded);
const size_t cert_size = cert_from_store->cbCertEncoded;
- vector->emplace_back(d2i_X509(nullptr, &cert_data, cert_size));
+ X509* x509 = d2i_X509(nullptr, &cert_data, cert_size);
+ if (x509 == nullptr) {
+ per_process::Debug(DebugCategory::CRYPTO,
+ "Skipping read of a system certificate "
+ "because decoding failed\n");
+ } else {
+ vector->emplace_back(x509);
+ }
}
}