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: add extra CA certs to all secure contexts #44529

Closed

Conversation

ebickle
Copy link
Contributor

@ebickle ebickle commented Sep 6, 2022

Fixes the NODE_EXTRA_CA_CERTS root certificates being missing in a SecureContext when the crl or pfx options are specified in a call to tls.createSecureContext(). This was done by loading the NODE_EXTRA_CA_CERTS into root_certs_vector, allowing them to be added to secure contexts when NewRootCertStore() is called.

As part of this change, specifying NODE_EXTRA_CA_CERTS no longer causes the bundled CA store to be immediately loaded at startup. This improves Node.js startup time and makes the behavior of NODE_EXTRA_CA_CERTS consistent with the default behavior when NODE_EXTRA_CA_CERTS is omitted. Although this change effectively reverts #20434, it does not reintroduce issue #20432 because the environment variable is read at startup; modifying it at runtime has no effect.

Notes for code reviewers:

  • NewRootStore now takes an Environment* as a parameter. This was done so that ProcessEmitWarning could be called when the extra certificates could not be loaded. As a bonus, the warning can now be programatically read via the process warning event.
  • The new intent of root_certs_vector is that it should contain all certificates added to root_cert_store, not just the ones loaded from node_root_certs.h.
  • The existing code contained an incorrect X509_up_ref call that resulted in the X509_STORE's reference count continually increasing. This issue has been resolved.

Fixes: #32010
Refs: #40524, #23354, #20434

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/crypto

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run. labels Sep 6, 2022
@ebickle ebickle force-pushed the fix/tls-missing-extra-certificates branch from 314bada to 3857c32 Compare September 6, 2022 04:51
src/crypto/crypto_context.cc Outdated Show resolved Hide resolved
src/crypto/crypto_context.cc Outdated Show resolved Hide resolved
src/crypto/crypto_context.cc Show resolved Hide resolved
src/crypto/crypto_context.cc Outdated Show resolved Hide resolved
@ebickle

This comment was marked as outdated.

@ebickle

This comment was marked as outdated.

@aduh95
Copy link
Contributor

aduh95 commented Sep 20, 2023

Ping @nodejs/crypto for reviews

@alex1701c
Copy link

Would this also work with electron? I ask regarding electron/electron#10257

@ebickle ebickle closed this Jul 23, 2024
@ebickle ebickle deleted the fix/tls-missing-extra-certificates branch July 23, 2024 12:42
@ebickle ebickle restored the fix/tls-missing-extra-certificates branch July 23, 2024 15:39
@ebickle ebickle reopened this Jul 23, 2024
@ebickle
Copy link
Contributor Author

ebickle commented Jul 23, 2024

@nodejs/crypto I've resolved the conflicts in this PR - it's ready for review again

ccing @pimterry

Copy link
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

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

Some minor nitpicking about test details but nothing critical (up to you if/how you want to do those). The implementation itself looks great to me 👍

Would be nice to have a review from somebody else from @nodejs/crypto who is a bit more familiar with this if we can, since the core TLS trust store setup is quite sensitive code. Let's give it a few days for anybody else to chime in.

test/parallel/test-tls-env-extra-ca-with-ca.js Outdated Show resolved Hide resolved
// instead of replacing, so connection still succeeds.
copts.secureContext.context.addCACert(
fixtures.readKey('ca1-cert.pem')
);
Copy link
Member

Choose a reason for hiding this comment

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

It would be better if we did this without directly messing with the context like this, but I understand there's no usable API for additional CAs right now - this is really just a note that we should update this as part of adding that API in #27079

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree completely. So long as we land the "additional CA" functionality shortly after and then replace this test, temporarily relying on the 'internal' context behavior makes sense to ensure we have proper coverage in the mean time.

test/parallel/test-tls-env-extra-ca-with-ca.js Outdated Show resolved Hide resolved
@pimterry pimterry added the request-ci Add this label to start a Jenkins CI on a PR. label Jul 24, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jul 24, 2024
@nodejs-github-bot
Copy link
Collaborator

@pimterry pimterry added the request-ci Add this label to start a Jenkins CI on a PR. label Jul 26, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jul 26, 2024
@nodejs-github-bot
Copy link
Collaborator

Copy link
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

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

Test changes look good, thanks 👍

CI is failing because of a conflict with main (https://ci.nodejs.org/job/node-test-commit/72499/console) can you rebase?

Store loaded NODE_EXTRA_CA_CERTS into root_certs_vector, allowing
them to be added to secure contexts when NewRootCertStore() is
called.

When NODE_EXTRA_CA_CERTS is specified, the root certificates
(both bundled and extra) will no longer be preloaded at startup.
This improves Node.js startup time and makes the behavior of
NODE_EXTRA_CA_CERTS consistent with the default behavior when
NODE_EXTRA_CA_CERTS is omitted.

The original reason NODE_EXTRA_CA_CERTS were loaded at startup
(issues nodejs#20432, nodejs#20434) was to prevent the environment variable from
being changed at runtime. This change preserves the runtime consistency
without actually having to load the certs at startup.

Fixes: nodejs#32010
Refs: nodejs#40524
Refs: nodejs#23354
@ebickle ebickle force-pushed the fix/tls-missing-extra-certificates branch from 53ae059 to 61b1f13 Compare July 26, 2024 15:07
@ebickle
Copy link
Contributor Author

ebickle commented Jul 26, 2024

@pimterry Rebased back onto upstream main. Can you give it another try?

@pimterry pimterry added the request-ci Add this label to start a Jenkins CI on a PR. label Jul 29, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jul 29, 2024
@nodejs-github-bot
Copy link
Collaborator

pimterry pushed a commit that referenced this pull request Jul 30, 2024
Store loaded NODE_EXTRA_CA_CERTS into root_certs_vector, allowing
them to be added to secure contexts when NewRootCertStore() is
called, rather than losing them when unrelated options are provided.

When NODE_EXTRA_CA_CERTS is specified, the root certificates
(both bundled and extra) will no longer be preloaded at startup.
This improves Node.js startup time and makes the behavior of
NODE_EXTRA_CA_CERTS consistent with the default behavior when
NODE_EXTRA_CA_CERTS is omitted.

The original reason NODE_EXTRA_CA_CERTS were loaded at startup
(issues #20432, #20434) was to prevent the environment variable from
being changed at runtime. This change preserves the runtime consistency
without actually having to load the certs at startup.

Fixes: #32010
Refs: #40524
Refs: #23354
PR-URL: #44529
Reviewed-By: Tim Perry <pimterry@gmail.com>
@pimterry
Copy link
Member

Landed in 7485ad8

@pimterry pimterry closed this Jul 30, 2024
targos pushed a commit that referenced this pull request Aug 14, 2024
Store loaded NODE_EXTRA_CA_CERTS into root_certs_vector, allowing
them to be added to secure contexts when NewRootCertStore() is
called, rather than losing them when unrelated options are provided.

When NODE_EXTRA_CA_CERTS is specified, the root certificates
(both bundled and extra) will no longer be preloaded at startup.
This improves Node.js startup time and makes the behavior of
NODE_EXTRA_CA_CERTS consistent with the default behavior when
NODE_EXTRA_CA_CERTS is omitted.

The original reason NODE_EXTRA_CA_CERTS were loaded at startup
(issues #20432, #20434) was to prevent the environment variable from
being changed at runtime. This change preserves the runtime consistency
without actually having to load the certs at startup.

Fixes: #32010
Refs: #40524
Refs: #23354
PR-URL: #44529
Reviewed-By: Tim Perry <pimterry@gmail.com>
@RafaelGSS RafaelGSS mentioned this pull request Aug 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extra CA certificates missing when certain TLS options specified
6 participants