Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
ab150d7
test: remove flakiness on macOS test
anonrig Feb 9, 2025
0a82d27
test: reduce flakiness on test-net-write-fully-async-buffer
anonrig Feb 9, 2025
d0ee8c0
src: improve error handling in process_wrap
jasnell Feb 11, 2025
41f444f
src: improve error handling in string_bytes/decoder
jasnell Feb 11, 2025
d8e70dc
src: improve node::Dotenv trimming
dario-piotrowicz Feb 11, 2025
9b98ac6
test: update WPT for urlpattern to ef6d83d789
nodejs-github-bot Feb 12, 2025
2990cc8
doc: run license-builder
github-actions[bot] Feb 12, 2025
35f89aa
build: fix GN build of uv
zcbenz Feb 12, 2025
3bc6d62
doc: add `signal` to `filehandle.writeFile()` options
y-hsgw Feb 12, 2025
7e2dac9
src: add self-assigment memcpy checks
wooffie Feb 12, 2025
a6b7bce
doc: move stability index after history section for consistency
aduh95 Feb 12, 2025
a9112df
tools: add support for `import source` syntax in linter
aduh95 Feb 12, 2025
c011271
doc: update cleanup to trust on vuln db automation
RafaelGSS Feb 13, 2025
18ea88b
crypto: cleanup root certificates and skip PEM deserialization
joyeecheung Feb 13, 2025
2ec4ff1
meta: update last name for jkrems
hybrist Feb 13, 2025
dfdaa92
crypto: fix missing OPENSSL_NO_ENGINE guard
codebytere Feb 14, 2025
1efd74b
tools: fix release URL computation in update-root-certs.mjs
joyeecheung Feb 14, 2025
44dd8a5
doc: buffer: fix typo on `Buffer.copyBytesFrom(` `offset` option
tpoisseau Feb 14, 2025
6951133
doc: improve documentation on argument validation
Aditi-1400 Feb 14, 2025
b369ad6
test: remove unnecessary assert requiring from tests
dario-piotrowicz Feb 14, 2025
ccb8c12
test,crypto: make tests work for BoringSSL
codebytere Feb 15, 2025
5af35d1
build: fix GN build failure
zcbenz Feb 15, 2025
50ba04e
doc: recommend writing tests in new files and including comments
joyeecheung Feb 15, 2025
6cdee54
tools: do not run major-release workflow on forks
Trott Feb 15, 2025
a588066
test: add case for unrecognised fields within pjson "exports"
JakobJingleheimer Feb 13, 2025
40f3a51
fs: handle UV_ENOTDIR in `fs.statSync` with `throwIfNoEntry` provided
juanarbol Feb 10, 2025
5b2dfad
doc: add a note about `require('../common')` in testing documentation
Aditi-1400 Feb 15, 2025
b50fc42
crypto: support --use-system-ca on non-Windows and non-macOS
joyeecheung Feb 15, 2025
fa26f83
src: lock the isolate properly in IsolateData destructor
joyeecheung Feb 15, 2025
286bb84
src: fix accessing empty string
zcbenz Feb 16, 2025
c02494f
doc: fix transpiler loader hooks documentation
joyeecheung Feb 16, 2025
a7e5ef9
doc: fix wrong verb form
dario-piotrowicz Feb 16, 2025
9de45cb
doc: `modules.md`: fix `distance` definition
alexweej Feb 16, 2025
f4a82fd
benchmark: add a warmup on bench-openSync
elvessilvavieira Feb 16, 2025
ed5671f
doc: update `module.builtinModules` sentence
dario-piotrowicz Feb 16, 2025
78d4e52
doc: fix wrong articles used to address modules
dario-piotrowicz Feb 17, 2025
4b02fdc
doc: update Xcode version used for arm64 and pkg
targos Feb 17, 2025
5414eb4
src: improve error handling in multiple files
jasnell Feb 8, 2025
90875ba
src: improve error handling in node_blob
jasnell Feb 15, 2025
46df14d
doc: update clang-cl on Windows building guide
joyeecheung Feb 18, 2025
fec2d50
build: add skip_apidoc_files and include QUIC
RafaelGSS Feb 6, 2025
ac35106
sea: suppress builtin warning with disableExperimentalSEAWarning option
koooge Feb 16, 2025
5a74568
doc: disambiguate pseudo-code statement
dario-piotrowicz Feb 18, 2025
cc1cafd
module: allow omitting context in synchronous next hooks
joyeecheung Feb 18, 2025
21d795a
dns: add TLSA record query and parsing
rithvikvibhu May 14, 2024
0de128c
doc: add `module namespace object` links
dario-piotrowicz Feb 16, 2025
b696049
doc: fix link and history of `SourceMap` sections
aduh95 Feb 18, 2025
56f9fe7
src: port `defineLazyProperties` to native code
aduh95 Feb 18, 2025
e3127b8
src: replace NewFromUtf8 with OneByteString where appropriate
jasnell Feb 18, 2025
2929fc6
test_runner: allow special characters in snapshot keys
Ceres6 Feb 19, 2025
b384baa
build: print 'Formatting Markdown...' for long task markdown formatting
1ilsang Feb 19, 2025
e26d484
cli: allow --cpu-prof* in NODE_OPTIONS
Ceres6 Feb 20, 2025
73a8514
tools: consolidate 'introduced_in' check for docs
1ilsang Feb 20, 2025
fdc8aeb
doc: fix 'introduced_in' version in typescript module
1ilsang Feb 20, 2025
7dd326e
src: move instead of copy shared pointer in node_blob
targos Feb 20, 2025
e0a91f6
src: gate all quic behind disabled-by-default compile flag
jasnell Feb 19, 2025
d62299b
meta: add CODEOWNERS for SQLite
cjihrig Feb 20, 2025
90a4de0
src: do not format single string argument for THROW_ERR_*
joyeecheung Feb 18, 2025
ad3c572
module: improve error message from asynchronicity in require(esm)
joyeecheung Feb 17, 2025
8421021
deps: update ada to 3.1.0
nodejs-github-bot Feb 20, 2025
ccf496c
test: improve error output of test-http2-client-promisify-connect-error
aduh95 Feb 21, 2025
c6ddfa5
process: add threadCpuUsage
ShogunPanda Feb 21, 2025
d922153
url: improve urlpattern regexp performance
anonrig Feb 21, 2025
c6d6be2
typings: fix `ImportModuleDynamicallyCallback` return type
legendecas Feb 21, 2025
315244e
test: simplify test-http2-client-promisify-connect-error
lpinca Feb 22, 2025
587112c
doc: remove buffered flag from performance hooks examples
pavel-romanov8 Feb 23, 2025
85ac02f
meta: bump `github/codeql-action` from 3.27.5 to 3.28.8
dependabot[bot] Feb 23, 2025
7f5f02b
meta: bump `actions/stale` from 9.0.0 to 9.1.0
dependabot[bot] Feb 23, 2025
dfd42db
meta: bump `actions/cache` from 4.1.2 to 4.2.0
dependabot[bot] Feb 23, 2025
58d7036
meta: bump `step-security/harden-runner` from 2.10.2 to 2.10.4
dependabot[bot] Feb 23, 2025
0dd0108
meta: bump `codecov/codecov-action` from 5.0.7 to 5.3.1
dependabot[bot] Feb 23, 2025
3d61604
meta: bump `mozilla-actions/sccache-action` from 0.0.6 to 0.0.7
dependabot[bot] Feb 23, 2025
35cdd9b
meta: bump `peter-evans/create-pull-request` from 7.0.5 to 7.0.6
dependabot[bot] Feb 23, 2025
f77069b
meta: bump `actions/setup-python` from 5.3.0 to 5.4.0
dependabot[bot] Feb 23, 2025
d6234b4
inspector: skip promise hook in the inspector async hook
joyeecheung Feb 23, 2025
a025d7b
tools: run Linux tests on GitHub arm64 runners as well
dennisameling Feb 23, 2025
ef314dc
src: fix crash when lazy getter is invoked in a vm context
legendecas Feb 23, 2025
66614cf
doc: fix web.libera.chat link in pull-requests.md
SamB Feb 23, 2025
7c7e9f4
test: make eval snapshot comparison more flexible
codebytere Feb 23, 2025
51dff8b
test: fix test-without-async-context-frame.mjs in debug mode
joyeecheung Feb 15, 2025
116c1fe
test_runner: refactor testPlan counter increse
pmarchini Feb 23, 2025
4413ce7
doc: fix typo in Windows building instructions
timja Feb 24, 2025
e10ef27
inspector: convert event params to protocol without json
legendecas Feb 24, 2025
f35bd86
doc: add additional caveat for fs.watch
mhdawson Feb 24, 2025
1a24417
test: add doAppendAndCancel test
y-hsgw Feb 24, 2025
455bf5a
doc: update options to filehandle.appendFile()
y-hsgw Feb 24, 2025
e08d7d4
lib: fixup incorrect argument order in assertEncoding
jasnell Feb 22, 2025
aa81785
lib: fixup more incorrect ERR_INVALID_ARG_VALUE uses
jasnell Feb 23, 2025
2aceca1
deps: update sqlite to 3.49.1
nodejs-github-bot Feb 25, 2025
8644cf3
deps: update ngtcp2 to 1.11.0
nodejs-github-bot Feb 25, 2025
8076284
deps: update cjs-module-lexer to 2.1.0
nodejs-github-bot Feb 25, 2025
9d2368f
2025-02-26, Version 23.9.0 (Current)
nodejs-github-bot Feb 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
crypto: support --use-system-ca on non-Windows and non-macOS
On other platforms, load from the OpenSSL default certificate
file and diretory.
This is different from --use-openssl-ca in that it caches
the certificates on first load, instead of always reading
from disk every time a new root store is needed.

When used together with the statically-linked OpenSSL, the
default configuration usually leads to this behavior:

- If SSL_CERT_FILE is used, load from SSL_CERT_FILE. Otherwise
  load from /etc/ssl/cert.pem
- If SSL_CERT_DIR is used, load from all the files under
  SSL_CERT_DIR. Otherwise, load from all the files under
  /etc/ssl/certs

PR-URL: #57009
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
joyeecheung authored and targos committed Feb 17, 2025
commit b50fc42a992ee8ab3371fa37ca2d36a7f1c7b127
36 changes: 26 additions & 10 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -2838,12 +2838,15 @@ The following values are valid for `mode`:
### `--use-system-ca`

Node.js uses the trusted CA certificates present in the system store along with
the `--use-bundled-ca`, `--use-openssl-ca` options.
the `--use-bundled-ca` option and the `NODE_EXTRA_CA_CERTS` environment variable.
On platforms other than Windows and macOS, this loads certificates from the directory
and file trusted by OpenSSL, similar to `--use-openssl-ca`, with the difference being
that it caches the certificates after first load.

This option is only supported on Windows and macOS, and the certificate trust policy
is planned to follow [Chromium's policy for locally trusted certificates][]:
On Windows and macOS, the certificate trust policy is planned to follow
[Chromium's policy for locally trusted certificates][]:

On macOS, the following certifcates are trusted:
On macOS, the following settings are respected:

* Default and System Keychains
* Trust:
Expand All @@ -2853,8 +2856,8 @@ On macOS, the following certifcates are trusted:
* Any certificate where the “When using this certificate” flag is set to “Never Trust” or
* Any certificate where the “Secure Sockets Layer (SSL)” flag is set to “Never Trust.”

On Windows, the following certificates are currently trusted (unlike
Chromium's policy, distrust is not currently supported):
On Windows, the following settings are respected (unlike Chromium's policy, distrust
and intermediate CA are not currently supported):

* Local Machine (accessed via `certlm.msc`)
* Trust:
Expand All @@ -2869,8 +2872,19 @@ Chromium's policy, distrust is not currently supported):
* Trusted Root Certification Authorities
* Enterprise Trust -> Group Policy -> Trusted Root Certification Authorities

On any supported system, Node.js would check that the certificate's key usage and extended key
usage are consistent with TLS use cases before using it for server authentication.
On Windows and macOS, Node.js would check that the user settings for the certificates
do not forbid them for TLS server authentication before using them.

On other systems, Node.js loads certificates from the default certificate file
(typically `/etc/ssl/cert.pem`) and default certificate directory (typically
`/etc/ssl/certs`) that the version of OpenSSL that Node.js links to respects.
This typically works with the convention on major Linux distributions and other
Unix-like systems. If the overriding OpenSSL environment variables
(typically `SSL_CERT_FILE` and `SSL_CERT_DIR`, depending on the configuration
of the OpenSSL that Node.js links to) are set, the specified paths will be used to load
certificates instead. These environment variables can be used as workarounds
if the conventional paths used by the version of OpenSSL Node.js links to are
not consistent with the system configuration that the users have for some reason.

### `--v8-options`

Expand Down Expand Up @@ -3512,7 +3526,8 @@ variable is ignored.
added: v7.7.0
-->

If `--use-openssl-ca` is enabled, this overrides and sets OpenSSL's directory
If `--use-openssl-ca` is enabled, or if `--use-system-ca` is enabled on
platforms other than macOS and Windows, this overrides and sets OpenSSL's directory
containing trusted certificates.

Be aware that unless the child environment is explicitly set, this environment
Expand All @@ -3525,7 +3540,8 @@ may cause them to trust the same CAs as node.
added: v7.7.0
-->

If `--use-openssl-ca` is enabled, this overrides and sets OpenSSL's file
If `--use-openssl-ca` is enabled, or if `--use-system-ca` is enabled on
platforms other than macOS and Windows, this overrides and sets OpenSSL's file
containing trusted certificates.

Be aware that unless the child environment is explicitly set, this environment
Expand Down
73 changes: 72 additions & 1 deletion src/crypto/crypto_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
issuer);
}

unsigned long LoadCertsFromFile( // NOLINT(runtime/int)
static unsigned long LoadCertsFromFile( // NOLINT(runtime/int)
std::vector<X509*>* certs,
const char* file) {
MarkPopErrorOnReturn mark_pop_error_on_return;
Expand Down Expand Up @@ -645,6 +645,74 @@ void ReadWindowsCertificates(
}
#endif

static void LoadCertsFromDir(std::vector<X509*>* certs,
std::string_view cert_dir) {
uv_fs_t dir_req;
auto cleanup = OnScopeLeave([&dir_req]() { uv_fs_req_cleanup(&dir_req); });
int err = uv_fs_scandir(nullptr, &dir_req, cert_dir.data(), 0, nullptr);
if (err < 0) {
fprintf(stderr,
"Cannot open directory %s to load OpenSSL certificates.\n",
cert_dir.data());
return;
}

uv_fs_t stats_req;
auto cleanup_stats =
OnScopeLeave([&stats_req]() { uv_fs_req_cleanup(&stats_req); });
for (;;) {
uv_dirent_t ent;

int r = uv_fs_scandir_next(&dir_req, &ent);
if (r == UV_EOF) {
break;
}
if (r < 0) {
char message[64];
uv_strerror_r(r, message, sizeof(message));
fprintf(stderr,
"Cannot scan directory %s to load OpenSSL certificates.\n",
cert_dir.data());
return;
}

std::string file_path = std::string(cert_dir) + "/" + ent.name;
int stats_r = uv_fs_stat(nullptr, &stats_req, file_path.c_str(), nullptr);
if (stats_r == 0 &&
(static_cast<uv_stat_t*>(stats_req.ptr)->st_mode & S_IFREG)) {
LoadCertsFromFile(certs, file_path.c_str());
}
}
}

// Loads CA certificates from the default certificate paths respected by
// OpenSSL.
void GetOpenSSLSystemCertificates(std::vector<X509*>* system_store_certs) {
std::string cert_file;
// While configurable when OpenSSL is built, this is usually SSL_CERT_FILE.
if (!credentials::SafeGetenv(X509_get_default_cert_file_env(), &cert_file)) {
// This is usually /etc/ssl/cert.pem if we are using the OpenSSL statically
// linked and built with default configurations.
cert_file = X509_get_default_cert_file();
}

std::string cert_dir;
// While configurable when OpenSSL is built, this is usually SSL_CERT_DIR.
if (!credentials::SafeGetenv(X509_get_default_cert_dir_env(), &cert_dir)) {
// This is usually /etc/ssl/certs if we are using the OpenSSL statically
// linked and built with default configurations.
cert_dir = X509_get_default_cert_dir();
}

if (!cert_file.empty()) {
LoadCertsFromFile(system_store_certs, cert_file.c_str());
}

if (!cert_dir.empty()) {
LoadCertsFromDir(system_store_certs, cert_dir.c_str());
}
}

static std::vector<X509*> InitializeBundledRootCertificates() {
// Read the bundled certificates in node_root_certs.h into
// bundled_root_certs_vector.
Expand Down Expand Up @@ -685,6 +753,9 @@ static std::vector<X509*> InitializeSystemStoreCertificates() {
#endif
#ifdef _WIN32
ReadWindowsCertificates(&system_store_certs);
#endif
#if !defined(__APPLE__) && !defined(_WIN32)
GetOpenSSLSystemCertificates(&system_store_certs);
#endif
return system_store_certs;
}
Expand Down
17 changes: 13 additions & 4 deletions test/parallel/test-native-certs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ import fixtures from '../common/fixtures.js';
import { it, beforeEach, afterEach, describe } from 'node:test';
import { once } from 'events';

if (!common.isMacOS && !common.isWindows) {
common.skip('--use-system-ca is only supported on macOS and Windows');
}

if (!common.hasCrypto) {
common.skip('requires crypto');
}
Expand All @@ -34,6 +30,19 @@ if (!common.hasCrypto) {
// $ $thumbprint = (Get-ChildItem -Path Cert:\CurrentUser\Root | \
// Where-Object { $_.Subject -match "StartCom Certification Authority" }).Thumbprint
// $ Remove-Item -Path "Cert:\CurrentUser\Root\$thumbprint"
//
// On Debian/Ubuntu:
// 1. To add the certificate:
// $ sudo cp test/fixtures/keys/fake-startcom-root-cert.pem \
// /usr/local/share/ca-certificates/fake-startcom-root-cert.crt
// $ sudo update-ca-certificates
// 2. To remove the certificate
// $ sudo rm /usr/local/share/ca-certificates/fake-startcom-root-cert.crt
// $ sudo update-ca-certificates --fresh
//
// For other Unix-like systems, consult their manuals, there are usually
// file-based processes similar to the Debian/Ubuntu one but with different
// file locations and update commands.
const handleRequest = (req, res) => {
const path = req.url;
switch (path) {
Expand Down