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.

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]>
@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 75.00000% with 5 lines in your changes missing coverage. Please review.

Project coverage is 89.19%. Comparing base (93c15bf) to head (18370e6).
Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
src/crypto/crypto_util.cc 64.28% 2 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #56601      +/-   ##
==========================================
- Coverage   89.19%   89.19%   -0.01%     
==========================================
  Files         662      662              
  Lines      191797   191858      +61     
  Branches    36923    36925       +2     
==========================================
+ Hits       171074   171124      +50     
- Misses      13569    13572       +3     
- Partials     7154     7162       +8     
Files with missing lines Coverage Δ
lib/crypto.js 92.93% <100.00%> (+0.11%) ⬆️
src/crypto/crypto_util.cc 72.19% <64.28%> (-0.28%) ⬇️

... and 38 files with indirect coverage changes


* Returns: {number} The [`default OpenSSL security level`][].
Useful to be able to adjust based on the algorithms available given the
security level.
Copy link
Member

Choose a reason for hiding this comment

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

Some explanation as to how to interpret the returned values would be helpful.

And just for my knowledge because I'm not that familiar with the security levels... are the return values specific at all the version of OpenSSL? Is it supported by BoringSSL?

Copy link
Member

@jasnell jasnell Jan 15, 2025

Choose a reason for hiding this comment

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

Ok just digging into the API a bit more ... https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#description

Looks like there are six security levels 0 through 5.... honestly we should document these and/or link to the relevant openssl definitions of them here.

The docs should also acknowledge that the API will not work when Node.js is compiled to use BoringSSL.

Copy link
Member

Choose a reason for hiding this comment

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

And just for my knowledge because I'm not that familiar with the security levels... are the return values specific at all the version of OpenSSL? Is it supported by BoringSSL?

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

Compare the level descriptions for 1.1.1, 3.0 and 3.4:

return ThrowCryptoError(env, ERR_get_error(), "SSL_new");
}

int sec_level = SSL_get_security_level(ssl);
Copy link
Member

Choose a reason for hiding this comment

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

consider adding a method to ncrypto::SSLPointer?

return ThrowCryptoError(env, ERR_get_error(), "SSL_new");
}

int sec_level = SSL_get_security_level(ssl);
Copy link
Member

@jasnell jasnell Jan 15, 2025

Choose a reason for hiding this comment

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

I could be missing it but based on a code search it does not appear as if this is implemented in boringssl at the moment so this will need to be gated and will need to have a good fallback behavior defined when openssl is not used.

https://issues.chromium.org/issues/42290521

@@ -44,6 +44,7 @@ const { getOptionValue } = require('internal/options');
const {
getFipsCrypto,
setFipsCrypto,
getOpenSSLSecLevelCrypto,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
getOpenSSLSecLevelCrypto,
getOpenSSLSecLevelCrypto: getOpenSSLSecLevel,

Comment on lines +261 to +264
function getOpenSSLSecLevel() {
return getOpenSSLSecLevelCrypto();
}

Copy link
Member

Choose a reason for hiding this comment

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

Can remove the indirection through the function by aliasing the import

Suggested change
function getOpenSSLSecLevel() {
return getOpenSSLSecLevelCrypto();
}

@@ -43,7 +44,7 @@ const dheCipher = 'DHE-RSA-AES128-SHA256';
const ecdheCipher = 'ECDHE-RSA-AES128-SHA256';
const ciphers = `${dheCipher}:${ecdheCipher}`;

if (!common.hasOpenSSL(3, 2)) {
if (secLevel < 2) {
Copy link
Member

Choose a reason for hiding this comment

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

I know this was a problem with the original code here also but it would be helpful to add a comment explaining what the 2 here is.... a pointer to the docs would suffice.

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.

4 participants