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

Expose security levels #56601

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

mhdawson
Copy link
Member

No description provided.

@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 Jan 14, 2025
@mhdawson
Copy link
Member Author

Run which tests on the different OpenSSL versions - https://ci.nodejs.org/job/node-test-commit-linux-containered/48401/

All passed, so I think that confirms it is working correctly.

In terms of testing I don't think we can change the default except at compile time, and I also think comparing against a specific version could cause problems for the shared library testing.

I can add a test that just calls the method and makes sure it is within the range documented which is currently 1-5. Does that makes sense to people?

Copy link

codecov bot commented Jan 15, 2025

Codecov Report

Attention: Patch coverage is 70.58824% with 5 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (1238f0a) to head (5ec3b6e).
Report is 30 commits behind head on main.

Files with missing lines Patch % Lines
src/crypto/crypto_util.cc 66.66% 2 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #56601      +/-   ##
==========================================
- Coverage   89.20%   89.20%   -0.01%     
==========================================
  Files         662      662              
  Lines      191819   191916      +97     
  Branches    36927    36941      +14     
==========================================
+ Hits       171110   171192      +82     
+ Misses      13565    13548      -17     
- Partials     7144     7176      +32     
Files with missing lines Coverage Δ
lib/internal/crypto/util.js 93.08% <100.00%> (+0.02%) ⬆️
src/crypto/crypto_util.cc 72.01% <66.66%> (-0.46%) ⬇️

... and 52 files with indirect coverage changes

doc/api/crypto.md Outdated Show resolved Hide resolved
src/crypto/crypto_util.cc Outdated Show resolved Hide resolved
src/crypto/crypto_util.cc Outdated Show resolved Hide resolved
lib/crypto.js Outdated Show resolved Hide resolved
lib/crypto.js Outdated Show resolved Hide resolved
@mhdawson
Copy link
Member Author

Yes, the values mean different things for different OpenSSL versions.

@richardlau what are the differences in meaning between the openssl levels ?

They all seem to say 80, 112, 128, 192 and 256 bits in terms of what the security levels map to. The default level might be different but that is what the API exposes.

@mhdawson
Copy link
Member Author

Added the test since I had it ready to go.

@mhdawson
Copy link
Member Author

In terms of doc Returns: {number} The [default OpenSSL security level][]. is a link to the description of the security levels.

@mhdawson
Copy link
Member Author

The main question though is if it should just be private method, if that seems to be the consensus are there suggestions of where I should best add it?

@richardlau
Copy link
Member

richardlau commented Jan 15, 2025

Yes, the values mean different things for different OpenSSL versions.

@richardlau what are the differences in meaning between the openssl levels ?

For example. compare the Level 1 description for OpenSSL 3.0:

The security level corresponds to a minimum of 80 bits of security. Any parameters offering below 80 bits of security are excluded. As a result RSA, DSA and DH keys shorter than 1024 bits and ECC keys shorter than 160 bits are prohibited. All export cipher suites are prohibited since they all offer less than 80 bits of security. SSL version 2 is prohibited. Any cipher suite using MD5 for the MAC is also prohibited. Note that signatures using SHA1 and MD5 are also forbidden at this level as they have less than 80 security bits.

to OpenSSL 3.4 (emphasis is added by me):

The security level corresponds to a minimum of 80 bits of security. Any parameters offering below 80 bits of security are excluded. As a result RSA, DSA and DH keys shorter than 1024 bits and ECC keys shorter than 160 bits are prohibited. Any cipher suite using MD5 for the MAC is also prohibited. Any cipher suites using CCM with a 64 bit authentication tag are prohibited. Note that signatures using SHA1 and MD5 are also forbidden at this level as they have less than 80 security bits. Additionally, SSLv3, TLS 1.0, TLS 1.1 and DTLS 1.0 are all disabled at this level.

OpenSSL 3.4 adds disabling SSLv3, TLS 1.0, TLS 1.1 and DTLS 1.0 at Level 1. In OpenSSL 3.0, SSLv3 is disabled at Level 2, TLS 1.0 at Level 3 and TLS 1.1 at Level 4. Also the OpenSSL 3.4 mentions "Any cipher suites using CCM with a 64 bit authentication tag are prohibited", which is not present in the description for OpenSSL 3.0.

@mhdawson
Copy link
Member Author

Looks like failures were due to changes landed since I rebased yesterday.

@mhdawson
Copy link
Member Author

@richardlau thanks for pointing out the specific differences. Seems odd that they would change what a security level means but some of those do seem like functional changes.

Distros may compile with a different openssl security level than the
default. In addition there has been some discussion with respect
to shipping with a different default security security level in
different Node.js versions in order to main stabilty. Exposing the
default openssl security level with let us have tests that work in
these situations as well as allow applications to better cope with
the avialable crypto algorithms.

- add API to get openssl security level
- modify one test to use security level instead
  of openssl version as an example

Signed-off-by: Michael Dawson <[email protected]>
@mhdawson mhdawson force-pushed the expose_security_levels branch from b5c2a44 to 3f76985 Compare January 15, 2025 23:08
@mhdawson
Copy link
Member Author

mhdawson commented Jan 15, 2025

@jasnell I think I addressed your comments as well as moving the method so it is internal only.

In terms of boringssl one remaining question I had was how version numbers are reported in process.versions when boringssl is used because the existing checks:

const hasOpenSSL = (major = 0, minor = 0, patch = 0) => {
  if (!hasCrypto) return false;
  if (OPENSSL_VERSION_NUMBER === undefined) {
    const regexp = /(?<m>\d+)\.(?<n>\d+)\.(?<p>\d+)/;
    const { m, n, p } = process.versions.openssl.match(regexp).groups;
    OPENSSL_VERSION_NUMBER = opensslVersionNumber(m, n, p);
  }
  return OPENSSL_VERSION_NUMBER >= opensslVersionNumber(major, minor, patch);
};

Only seem to consider openSSL, unless process.versions still look like OpenSSL is being used even though its boringssl under the covers. Do you know how the versions are reported when boringssl is used?

@mhdawson mhdawson added the request-ci Add this label to start a Jenkins CI on a PR. label Jan 20, 2025
@mhdawson
Copy link
Member Author

@richardlau are you ok with the PR after the latest updates?

@jasnell
Copy link
Member

jasnell commented Jan 20, 2025

@mhdawson .... I'm not sure how boringssl is represented in process.versions. This might be helpful https://github.com/search?q=repo%3Aelectron%2Felectron+%22process.versions%22+%22boringssl%22&type=code

@mhdawson
Copy link
Member Author

@jasnell, it looks like that means that if BoringSSL is used then process.vesions.openssl is not defined. In that case none of the existing checks being moved over to the check against the security level should help/hurt the BoringSSL case.

@jasnell
Copy link
Member

jasnell commented Jan 20, 2025

I would confirm that with the electron team before progressing. @codebytere

src/crypto/crypto_util.cc Outdated Show resolved Hide resolved
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jan 21, 2025
@nodejs-github-bot
Copy link
Collaborator

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.

5 participants