From fc4d62ff9fc3c669abd4020ada01092e4cd24573 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 10 Feb 2025 19:59:57 +0100 Subject: [PATCH 1/3] tls: implement tls.getCACertificates() To accompany --use-system-ca, this adds a new API that allows querying various kinds of CA certificates. - If the first argument `type` is `"default"` or undefined, it returns the CA certificates that will be used by Node.js TLS clients by default, which includes the Mozilla CA if --use-bundled-ca is enabled or --use-openssl-ca is not enabled, and the system certificates if --use-system-ca is enabled, and the extra certificates if NODE_EXTRA_CA_CERTS is used. - If `type` is `"system"` this returns the system certificates, regardless of whether --use-system-ca is enabeld or not. - If `type` is `"bundled"` this is the same as `tls.rootCertificates` and returns the Mozilla CA certificates. - If `type` is `"extra"` this returns the certificates parsed from the path specified by NODE_EXTRA_CA_CERTS. Drive-by: remove the inaccurate description in `tls.rootCertificates` about including system certificates, since it in fact does not include them, and also it is contradicting the previous description about `tls.rootCertificates` always returning the Mozilla CA store and staying the same across platforms. --- doc/api/tls.md | 55 ++++++++++-- lib/tls.js | 88 +++++++++++++++++-- src/crypto/crypto_context.cc | 76 ++++++++++++++-- test/common/tls.js | 13 +++ .../tls-check-extra-ca-certificates.js | 17 ++++ test/fixtures/tls-get-ca-certificates.js | 11 +++ ...-tls-get-ca-certificates-bundled-subset.js | 17 ++++ .../test-tls-get-ca-certificates-bundled.js | 20 +++++ .../test-tls-get-ca-certificates-default.js | 20 +++++ .../test-tls-get-ca-certificates-error.js | 20 +++++ ...est-tls-get-ca-certificates-extra-empty.js | 29 ++++++ ...st-tls-get-ca-certificates-extra-subset.js | 16 ++++ .../test-tls-get-ca-certificates-extra.js | 29 ++++++ ...get-ca-certificates-system-without-flag.js | 36 ++++++++ .../test-tls-get-ca-certificates-system.js | 32 +++++++ test/testpy/__init__.py | 7 +- 16 files changed, 463 insertions(+), 23 deletions(-) create mode 100644 test/fixtures/tls-check-extra-ca-certificates.js create mode 100644 test/fixtures/tls-get-ca-certificates.js create mode 100644 test/parallel/test-tls-get-ca-certificates-bundled-subset.js create mode 100644 test/parallel/test-tls-get-ca-certificates-bundled.js create mode 100644 test/parallel/test-tls-get-ca-certificates-default.js create mode 100644 test/parallel/test-tls-get-ca-certificates-error.js create mode 100644 test/parallel/test-tls-get-ca-certificates-extra-empty.js create mode 100644 test/parallel/test-tls-get-ca-certificates-extra-subset.js create mode 100644 test/parallel/test-tls-get-ca-certificates-extra.js create mode 100644 test/parallel/test-tls-get-ca-certificates-system-without-flag.js create mode 100644 test/parallel/test-tls-get-ca-certificates-system.js diff --git a/doc/api/tls.md b/doc/api/tls.md index 8da9d66c350030..86644cea76b6a3 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1985,9 +1985,13 @@ changes: * `allowPartialTrustChain` {boolean} Treat intermediate (non-self-signed) certificates in the trust CA certificate list as trusted. * `ca` {string|string\[]|Buffer|Buffer\[]} Optionally override the trusted CA - certificates. Default is to trust the well-known CAs curated by Mozilla. - Mozilla's CAs are completely replaced when CAs are explicitly specified - using this option. The value can be a string or `Buffer`, or an `Array` of + certificates. If not specified, the CA certificates trusted by default are + the same as the ones returned by [`tls.getCACertificates()`][] using the + `default` type. If specified, the default list would be completely replaced + (instead of being concatenated) by the certificates in the `ca` option. + Users need to concatenate manually if they wish to add additional certificates + instead of completely overriding the default. + The value can be a string or `Buffer`, or an `Array` of strings and/or `Buffer`s. Any string or `Buffer` can contain multiple PEM CAs concatenated together. The peer's certificate must be chainable to a CA trusted by the server for the connection to be authenticated. When using @@ -2001,7 +2005,6 @@ changes: provided. For PEM encoded certificates, supported types are "TRUSTED CERTIFICATE", "X509 CERTIFICATE", and "CERTIFICATE". - See also [`tls.rootCertificates`][]. * `cert` {string|string\[]|Buffer|Buffer\[]} Cert chains in PEM format. One cert chain should be provided per private key. Each cert chain should consist of the PEM formatted certificate for a provided private `key`, @@ -2364,6 +2367,39 @@ openssl pkcs12 -certpbe AES-256-CBC -export -out client-cert.pem \ The server can be tested by connecting to it using the example client from [`tls.connect()`][]. +## `tls.getCACertificates([type])` + + + +* `type` {string|undefined} The type of CA certificates that will be returned. Valid values + are `"default"`, `"system"`, `"bundled"` and `"extra"`. + **Default:** `"default"`. +* Returns: {string\[]} An array of PEM-encoded certificates. The array may contain duplicates + if the same certificate is repeatedly stored in multiple sources. + +Returns an array containing the CA certificates from various sources, depending on `type`: + +* `"default"`: return the CA certificates that will be used by the Node.js TLS clients by default. + * When [`--use-bundled-ca`][] is enabled (default), or [`--use-openssl-ca`][] is not enabled, + this would include CA certificates from the bundled Mozilla CA store. + * When [`--use-system-ca`][] is enabled, this would also include certificates from the system's + trusted store. + * When [`NODE_EXTRA_CA_CERTS`][] is used, this would also include certificates loaded from the specified + file. +* `"system"`: return the CA certificates that are loaded from the system's trusted store, according + to rules set by [`--use-system-ca`][]. This can be used to get the certificates from the system + when [`--use-system-ca`][] is not enabled. +* `"bundled"`: return the CA certificates from the bundled Mozilla CA store. This would be the same + as [`tls.rootCertificates`][]. +* `"extra"`: return the CA certificates loaded from [`NODE_EXTRA_CA_CERTS`][]. It's an empty array if + [`NODE_EXTRA_CA_CERTS`][] is not set. + + + ## `tls.getCiphers()`