Skip to content

Commit 89fe635

Browse files
joyeecheungtargos
authored andcommitted
crypto: load system CA certificates off thread
When --use-system-ca is enabled, load the system CA certificates eagerly off the main thread to avoid blocking the main thread when the first TLS connection is made. PR-URL: #59550 Refs: #58990 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 40b217a commit 89fe635

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

src/crypto/crypto_context.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,23 @@ static std::vector<X509*>& GetSystemStoreCACertificates() {
814814
return system_store_certs;
815815
}
816816

817+
static void LoadSystemCACertificates(void* data) {
818+
GetSystemStoreCACertificates();
819+
}
820+
821+
static uv_thread_t system_ca_thread;
822+
static bool system_ca_thread_started = false;
823+
int LoadSystemCACertificatesOffThread() {
824+
// This is only run once during the initialization of the process, so
825+
// it is safe to use a static thread here.
826+
int r =
827+
uv_thread_create(&system_ca_thread, LoadSystemCACertificates, nullptr);
828+
if (r == 0) {
829+
system_ca_thread_started = true;
830+
}
831+
return r;
832+
}
833+
817834
static std::vector<X509*> InitializeExtraCACertificates() {
818835
std::vector<X509*> extra_certs;
819836
unsigned long err = LoadCertsFromFile( // NOLINT(runtime/int)
@@ -925,6 +942,10 @@ void CleanupCachedRootCertificates() {
925942
X509_free(cert);
926943
}
927944
}
945+
if (system_ca_thread_started) {
946+
uv_thread_join(&system_ca_thread);
947+
system_ca_thread_started = false;
948+
}
928949
}
929950

930951
void GetBundledRootCertificates(const FunctionCallbackInfo<Value>& args) {

src/crypto/crypto_util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ void InitCryptoOnce();
4545
void InitCrypto(v8::Local<v8::Object> target);
4646

4747
extern void UseExtraCaCerts(std::string_view file);
48+
extern int LoadSystemCACertificatesOffThread();
4849
void CleanupCachedRootCertificates();
4950

5051
int PasswordCallback(char* buf, int size, int rwflag, void* u);

src/node.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,20 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
12081208
return result;
12091209
}
12101210

1211+
if (per_process::cli_options->use_system_ca) {
1212+
// Load the system CA certificates eagerly off the main thread to avoid
1213+
// blocking the main thread when the first TLS connection is made. We
1214+
// don't need to wait for the thread to finish with code here, as
1215+
// GetSystemStoreCACertificates() has a function-local static and any
1216+
// actual user of it will wait for that to complete initialization.
1217+
int r = crypto::LoadSystemCACertificatesOffThread();
1218+
if (r != 0) {
1219+
FPrintF(
1220+
stderr,
1221+
"Warning: Failed to load system CA certificates off thread: %s\n",
1222+
uv_strerror(r));
1223+
}
1224+
}
12111225
// Ensure CSPRNG is properly seeded.
12121226
CHECK(ncrypto::CSPRNG(nullptr, 0));
12131227

0 commit comments

Comments
 (0)