Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: use system CAs instead of bundled ones #8334

Closed
wants to merge 3 commits into from

Conversation

AdamMajer
Copy link
Contributor

@AdamMajer AdamMajer commented Aug 30, 2016

Checklist
  • make -j4 test (UNIX), or vcbuild test nosign (Windows) passes
  • commit message follows commit guidelines
Affected core subsystem(s)

crypto

Description of change

Use system supplied CAs instead of using Node's bundled version.
This is a compile time option with default reverting back to
using bundled certificates.

Also simplify cert_store lifetime by using reference count instead
of pulling it from under the SSL_CTX right before deletion.
(merged)

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. build Issues and PRs related to build files or the CI. labels Aug 30, 2016
@addaleax addaleax added the openssl Issues and PRs related to the OpenSSL dependency. label Aug 30, 2016
@addaleax
Copy link
Member

/cc @nodejs/crypto

@addaleax
Copy link
Member

@AdamMajer Here typically Fixes: and full URIs are used when referencing issues to be closed :)

Here’s a CI run: https://ci.nodejs.org/job/node-test-commit/4835/

@AdamMajer
Copy link
Contributor Author

@addaleax ah ,yes of couse. I'm completely new to NodeJS code review, but it seems that all commit messages have PR-URL: and Reviewed-By:. so is it correct to assume that once pull requests are reviewed, I amend the commit message with these extra headers (And fix my Fixes: header :)) ?

@addaleax
Copy link
Member

@AdamMajer Usually, the person who lands the PR adds these review headers (the ones you named), but it’s not like there’s anything stopping you from adding PR-URL: https://github.com/nodejs/node/pull/8334 yourself. :)

@jasnell
Copy link
Member

jasnell commented Aug 30, 2016

I know that @rvagg had suggested that this is best done as a configure option but I can definitely see value in this as a runtime command-line flag also -- even if left undocumented for the time being.

@jasnell jasnell changed the title Distro crypto crypto: use system CAs instead of bundled ones Aug 30, 2016
@AdamMajer
Copy link
Contributor Author

Having it as runtime option is OK in rare situation, maybe if you need to specify multiple stores? But then can't that be done already with the environmental variables SSL_CERT_DIR and SSL_CERT_FILE? Enable this at compile time, then select various stores with environmental variables overriding OpenSSL defaults. That's how I understand it from quick grep through OpenSSL.

An alternative would be to have compile time option "no-bundled-ca-certs" with runtime override option (no-)use-bundled-ca-certs (or something like that),

  1. look for system CAs as primary (including the environmental variables)
  2. fall back bundled CAs unless runtime/compiletime flag set to not use them.

The idea behind compile time selection is to make like easier for Linux distributions (and their users) where bundled CAs are very bad idea. On Linux we definitely would not want to fallback to bundled CAs. But there are quite a per different permutations on how this can be done.

@dougwilson
Copy link
Member

Would this make it possible to use the Windows system cert store?

@Fishrock123
Copy link
Contributor

Fixes #3159.

Being able to specify a path to root CAs at may also be useful. I think that would be more suited as a runtime flag?

@@ -905,6 +910,8 @@ def configure_openssl(o):
o['variables']['node_use_openssl'] = b(not options.without_ssl)
o['variables']['node_shared_openssl'] = b(options.shared_openssl)
o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0
if options.use_system_ca_store:
o['defines'] += ['USE_SYSTEM_CERTIFICATE_STORE']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's prefix it NODE_, may be something like NODE_SYSTEM_CERT_STORE?

@AdamMajer
Copy link
Contributor Author

On 08/30/2016 05:15 PM, Douglas Wilson wrote:

Would this make it possible to use the Windows system cert store?

For this better question would be, does OpenSSL support using Windows
cert store? I have no idea.

@indutny
Copy link
Member

indutny commented Aug 30, 2016

LGTM with a define naming nit, unless @bnoordhuis has some comments.

@jasnell
Copy link
Member

jasnell commented Aug 30, 2016

Having it as runtime option is OK in rare situation, maybe if you need to specify multiple stores?

For one, it would make it easier/possible to test this in CI :-)

@dougwilson
Copy link
Member

For this better question would be, does OpenSSL support using Windows cert store? I have no idea.

Yea, I have no idea, that's why I was asking :) Your config parameter along with it's description would suggest it does, and that it is not restricted to whatever OpenSSL happens to do. Some Googling suggests that no, OpenSSL cannot use the Windows cert store (but I have no idea how to verify those claims), which seems to make the configure switch misleading(?)

@AdamMajer
Copy link
Contributor Author

Updated to use suggested define name. Minor change to comment, but otherwise same patch.

The runtime option can be done later. The compile time option still needs to be there for 2 reasons,

  1. to not change current default behavior . maybe in node 7 we can delegate root certs to OS only as it should be possible on windows too, see http://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store but I'm not sure whether this belongs in Node or OpenSSL.
  2. all Linux distros would prefer to manage CAs in one place. Here they need to change current default behavior.

One step at a time .

@jasnell
Copy link
Member

jasnell commented Aug 31, 2016

LGTM. It's a shame that we don't have a direct way of testing this in CI since we can't set compile time flags for CI. I would say that this should likely be considered to be unsupported/experimental until it's gone through at least one release and we can see if any issues come up on it.

@@ -751,6 +751,23 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
CHECK_EQ(sc->ca_store_, nullptr);

if (!root_cert_store) {
#if defined(NODE_SYSTEM_CERT_STORE)
// *Assume* OpenSSL is setup correctly, which is the case
// for distribution supplied versions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's only going to be the case when node is linked against the distro openssl. It defaults to /usr/local/ssl with the bundled copy and that's unlikely to be the right path.

Aside: s/setup/set up/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this does not appear to be the case. Look in openssl.gypi. I've tested this with OpenSUSE Leap 42.1 which needs bundled OpenSSL and it certainly uses the /etc/ssl path as defined in the openssl.gypi file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnoordhuis I agree with @AdamMajer here, node's copy of OpenSSL uses a cert path in /etc, not /usr/local

MylesBorins pushed a commit that referenced this pull request May 16, 2017
The pointer to std::vector is unnecessary, so replace it with standard
instance. Also, make the for() loop more readable by using actual type
instead of inferred - there is no readability benefit here from
obfuscating the type.

PR-URL: #8334
Backport-PR-URL: #11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 16, 2017
NodeJS can already use an external, shared OpenSSL library. This
library knows where to look for OS managed certificates. Allow
a compile-time option to use this CA store by default instead of
using bundled certificates.

In case when using bundled OpenSSL, the paths are also valid for
majority of Linux systems without additional intervention. If
this is not set, we can use SSL_CERT_DIR to point it to correct
location.

Fixes: #3159
PR-URL: #8334
Backport-PR-URL: #11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 16, 2017
PR-URL: #8334
Backport-PR-URL: #11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 18, 2017
The pointer to std::vector is unnecessary, so replace it with standard
instance. Also, make the for() loop more readable by using actual type
instead of inferred - there is no readability benefit here from
obfuscating the type.

PR-URL: #8334
Backport-PR-URL: #11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 18, 2017
NodeJS can already use an external, shared OpenSSL library. This
library knows where to look for OS managed certificates. Allow
a compile-time option to use this CA store by default instead of
using bundled certificates.

In case when using bundled OpenSSL, the paths are also valid for
majority of Linux systems without additional intervention. If
this is not set, we can use SSL_CERT_DIR to point it to correct
location.

Fixes: #3159
PR-URL: #8334
Backport-PR-URL: #11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 18, 2017
PR-URL: #8334
Backport-PR-URL: #11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
@MylesBorins MylesBorins mentioned this pull request May 23, 2017
MylesBorins added a commit that referenced this pull request Jun 6, 2017
This LTS release comes with 126 commits. This includes 40 which
are test related, 32 which are doc related, 12 which are
build / tool related and 4 commits which are updates to
dependencies.

Notable Changes:

* build:
  - support for building mips64el (nanxiongchao)
    #10991
* cluster:
  - disconnect() now returns a reference to the disconnected
    worker. (Sean Villars)
    #10019
* crypto:
  - ability to select cert store at runtime (Adam Majer)
    #8334
  - Use system CAs instead of using bundled ones (Adam Majer)
    #8334
  - The `Decipher` methods `setAuthTag()` and `setAAD` now return
    `this`. (Kirill Fomichev)
    #9398
  - adding support for OPENSSL_CONF again (Sam Roberts)
    #11006
  - make LazyTransform compabile with Streams1 (Matteo Collina)
    #12380
* deps:
  - upgrade libuv to 1.11.0 (cjihrig)
    #11094
  - upgrade libuv to 1.10.2 (cjihrig)
    #10717
  - upgrade libuv to 1.10.1 (cjihrig)
    #9647
  - upgrade libuv to 1.10.0 (cjihrig)
    #9267
* dns:
  - Implemented `{ttl: true}` for `resolve4()` and `resolve6()`
    (Ben Noordhuis)
    #9296
* process:
  - add NODE_NO_WARNINGS environment variable (cjihrig)
    #10842
* readline:
  - add option to stop duplicates in history (Danny Nemer)
    #2982
* src:
  - support "--" after "-e" as end-of-options (John Barboza)
    #10651
* tls:
  - new tls.TLSSocket() supports sec ctx options (Sam Roberts)
    #11005
  - Allow obvious key/passphrase combinations. (Sam Roberts)
    #10294

PR-URL: #13059
MylesBorins added a commit that referenced this pull request Jun 6, 2017
This LTS release comes with 126 commits. This includes 40 which
are test related, 32 which are doc related, 12 which are
build / tool related and 4 commits which are updates to
dependencies.

Notable Changes:

* build:
  - support for building mips64el (nanxiongchao)
    #10991
* cluster:
  - disconnect() now returns a reference to the disconnected
    worker. (Sean Villars)
    #10019
* crypto:
  - ability to select cert store at runtime (Adam Majer)
    #8334
  - Use system CAs instead of using bundled ones (Adam Majer)
    #8334
  - The `Decipher` methods `setAuthTag()` and `setAAD` now return
    `this`. (Kirill Fomichev)
    #9398
  - adding support for OPENSSL_CONF again (Sam Roberts)
    #11006
  - make LazyTransform compabile with Streams1 (Matteo Collina)
    #12380
* deps:
  - upgrade libuv to 1.11.0 (cjihrig)
    #11094
  - upgrade libuv to 1.10.2 (cjihrig)
    #10717
  - upgrade libuv to 1.10.1 (cjihrig)
    #9647
  - upgrade libuv to 1.10.0 (cjihrig)
    #9267
* dns:
  - Implemented `{ttl: true}` for `resolve4()` and `resolve6()`
    (Ben Noordhuis)
    #9296
* process:
  - add NODE_NO_WARNINGS environment variable (cjihrig)
    #10842
* readline:
  - add option to stop duplicates in history (Danny Nemer)
    #2982
* src:
  - support "--" after "-e" as end-of-options (John Barboza)
    #10651
* tls:
  - new tls.TLSSocket() supports sec ctx options (Sam Roberts)
    #11005
  - Allow obvious key/passphrase combinations. (Sam Roberts)
    #10294

PR-URL: #13059
andrew749 pushed a commit to michielbaird/node that referenced this pull request Jul 19, 2017
The pointer to std::vector is unnecessary, so replace it with standard
instance. Also, make the for() loop more readable by using actual type
instead of inferred - there is no readability benefit here from
obfuscating the type.

PR-URL: nodejs/node#8334
Backport-PR-URL: nodejs/node#11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
andrew749 pushed a commit to michielbaird/node that referenced this pull request Jul 19, 2017
NodeJS can already use an external, shared OpenSSL library. This
library knows where to look for OS managed certificates. Allow
a compile-time option to use this CA store by default instead of
using bundled certificates.

In case when using bundled OpenSSL, the paths are also valid for
majority of Linux systems without additional intervention. If
this is not set, we can use SSL_CERT_DIR to point it to correct
location.

Fixes: nodejs/node#3159
PR-URL: nodejs/node#8334
Backport-PR-URL: nodejs/node#11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
andrew749 pushed a commit to michielbaird/node that referenced this pull request Jul 19, 2017
PR-URL: nodejs/node#8334
Backport-PR-URL: nodejs/node#11794
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
andrew749 pushed a commit to michielbaird/node that referenced this pull request Jul 19, 2017
This LTS release comes with 126 commits. This includes 40 which
are test related, 32 which are doc related, 12 which are
build / tool related and 4 commits which are updates to
dependencies.

Notable Changes:

* build:
  - support for building mips64el (nanxiongchao)
    nodejs/node#10991
* cluster:
  - disconnect() now returns a reference to the disconnected
    worker. (Sean Villars)
    nodejs/node#10019
* crypto:
  - ability to select cert store at runtime (Adam Majer)
    nodejs/node#8334
  - Use system CAs instead of using bundled ones (Adam Majer)
    nodejs/node#8334
  - The `Decipher` methods `setAuthTag()` and `setAAD` now return
    `this`. (Kirill Fomichev)
    nodejs/node#9398
  - adding support for OPENSSL_CONF again (Sam Roberts)
    nodejs/node#11006
  - make LazyTransform compabile with Streams1 (Matteo Collina)
    nodejs/node#12380
* deps:
  - upgrade libuv to 1.11.0 (cjihrig)
    nodejs/node#11094
  - upgrade libuv to 1.10.2 (cjihrig)
    nodejs/node#10717
  - upgrade libuv to 1.10.1 (cjihrig)
    nodejs/node#9647
  - upgrade libuv to 1.10.0 (cjihrig)
    nodejs/node#9267
* dns:
  - Implemented `{ttl: true}` for `resolve4()` and `resolve6()`
    (Ben Noordhuis)
    nodejs/node#9296
* process:
  - add NODE_NO_WARNINGS environment variable (cjihrig)
    nodejs/node#10842
* readline:
  - add option to stop duplicates in history (Danny Nemer)
    nodejs/node#2982
* src:
  - support "--" after "-e" as end-of-options (John Barboza)
    nodejs/node#10651
* tls:
  - new tls.TLSSocket() supports sec ctx options (Sam Roberts)
    nodejs/node#11005
  - Allow obvious key/passphrase combinations. (Sam Roberts)
    nodejs/node#10294

PR-URL: nodejs/node#13059
@JPvRiel JPvRiel mentioned this pull request May 22, 2018
@aguynamedben
Copy link

This was a while ago, but I'm curious if the runtime option ever got worked on? I have customers who install my app and I'd like for my app to use system-installed CAs on macOS. I think I'd have to build Node native module to access the certificates in Keychain Access, though, similar to how node-keytar does.

Any tips for telling Node to use system certs on macOS at runtime?

@sam-github
Copy link
Contributor

No work was done on Node.js side. You might want to ask on the openssl-users mailing list if OpenSSL has a mechanism for doing this.

@FranklinYu
Copy link

FranklinYu commented Mar 27, 2019

@sam-github Isn’t node --use-openssl-ca the “runtime option”? Did I miss anything?

Sorry didn’t saw that @aguynamedben was asking for macOS and Keychain.

abhishekumar-tyagi pushed a commit to abhishekumar-tyagi/node that referenced this pull request May 5, 2024
NodeJS can already use an external, shared OpenSSL library. This
library knows where to look for OS managed certificates. Allow
a compile-time option to use this CA store by default instead of
using bundled certificates.

In case when using bundled OpenSSL, the paths are also valid for
majority of Linux systems without additional intervention. If
this is not set, we can use SSL_CERT_DIR to point it to correct
location.

Fixes: nodejs/node#3159
PR-URL: nodejs/node#8334
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Issues and PRs related to build files or the CI. c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. openssl Issues and PRs related to the OpenSSL dependency. security Issues and PRs related to security. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.