Skip to content

Commit d74799d

Browse files
joyeecheungrichardlau
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 18ceefb commit d74799d

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
@@ -812,6 +812,23 @@ static std::vector<X509*>& GetSystemStoreCACertificates() {
812812
return system_store_certs;
813813
}
814814

815+
static void LoadSystemCACertificates(void* data) {
816+
GetSystemStoreCACertificates();
817+
}
818+
819+
static uv_thread_t system_ca_thread;
820+
static bool system_ca_thread_started = false;
821+
int LoadSystemCACertificatesOffThread() {
822+
// This is only run once during the initialization of the process, so
823+
// it is safe to use a static thread here.
824+
int r =
825+
uv_thread_create(&system_ca_thread, LoadSystemCACertificates, nullptr);
826+
if (r == 0) {
827+
system_ca_thread_started = true;
828+
}
829+
return r;
830+
}
831+
815832
static std::vector<X509*> InitializeExtraCACertificates() {
816833
std::vector<X509*> extra_certs;
817834
unsigned long err = LoadCertsFromFile( // NOLINT(runtime/int)
@@ -923,6 +940,10 @@ void CleanupCachedRootCertificates() {
923940
X509_free(cert);
924941
}
925942
}
943+
if (system_ca_thread_started) {
944+
uv_thread_join(&system_ca_thread);
945+
system_ca_thread_started = false;
946+
}
926947
}
927948

928949
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
@@ -62,6 +62,7 @@ void InitCryptoOnce();
6262
void InitCrypto(v8::Local<v8::Object> target);
6363

6464
extern void UseExtraCaCerts(const std::string& file);
65+
extern int LoadSystemCACertificatesOffThread();
6566
void CleanupCachedRootCertificates();
6667

6768
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
@@ -1245,6 +1245,20 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
12451245
return result;
12461246
}
12471247

1248+
if (per_process::cli_options->use_system_ca) {
1249+
// Load the system CA certificates eagerly off the main thread to avoid
1250+
// blocking the main thread when the first TLS connection is made. We
1251+
// don't need to wait for the thread to finish with code here, as
1252+
// GetSystemStoreCACertificates() has a function-local static and any
1253+
// actual user of it will wait for that to complete initialization.
1254+
int r = crypto::LoadSystemCACertificatesOffThread();
1255+
if (r != 0) {
1256+
FPrintF(
1257+
stderr,
1258+
"Warning: Failed to load system CA certificates off thread: %s\n",
1259+
uv_strerror(r));
1260+
}
1261+
}
12481262
// Ensure CSPRNG is properly seeded.
12491263
CHECK(ncrypto::CSPRNG(nullptr, 0));
12501264

0 commit comments

Comments
 (0)