Skip to content

Commit 5470cab

Browse files
mhdawsonaduh95
authored andcommitted
crypto: add api to get openssl security level
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 <midawson@redhat.com> PR-URL: #56601 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
1 parent 642959b commit 5470cab

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

lib/internal/crypto/util.js

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const {
3232
setEngine: _setEngine,
3333
secureHeapUsed: _secureHeapUsed,
3434
getCachedAliases,
35+
getOpenSSLSecLevelCrypto: getOpenSSLSecLevel,
3536
} = internalBinding('crypto');
3637

3738
const { getOptionValue } = require('internal/options');
@@ -631,4 +632,5 @@ module.exports = {
631632
secureHeapUsed,
632633
getCachedHashId,
633634
getHashCache,
635+
getOpenSSLSecLevel,
634636
};

src/crypto/crypto_util.cc

+27
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ using ncrypto::BIOPointer;
3131
using ncrypto::CryptoErrorList;
3232
using ncrypto::EnginePointer;
3333
using ncrypto::EVPKeyCtxPointer;
34+
using ncrypto::SSLCtxPointer;
35+
using ncrypto::SSLPointer;
3436
using v8::ArrayBuffer;
3537
using v8::BackingStore;
3638
using v8::BigInt;
@@ -201,6 +203,27 @@ void TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value>& args) {
201203
args.GetReturnValue().Set(ncrypto::testFipsEnabled() ? 1 : 0);
202204
}
203205

206+
void GetOpenSSLSecLevelCrypto(const FunctionCallbackInfo<Value>& args) {
207+
// for BoringSSL assume the same as the default
208+
int sec_level = OPENSSL_TLS_SECURITY_LEVEL;
209+
#ifndef OPENSSL_IS_BORINGSSL
210+
Environment* env = Environment::GetCurrent(args);
211+
212+
auto ctx = SSLCtxPointer::New();
213+
if (!ctx) {
214+
return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new");
215+
}
216+
217+
auto ssl = SSLPointer::New(ctx);
218+
if (!ssl) {
219+
return ThrowCryptoError(env, ERR_get_error(), "SSL_new");
220+
}
221+
222+
sec_level = SSL_get_security_level(ssl);
223+
#endif // OPENSSL_IS_BORINGSSL
224+
args.GetReturnValue().Set(sec_level);
225+
}
226+
204227
void CryptoErrorStore::Capture() {
205228
errors_.clear();
206229
while (const uint32_t err = ERR_get_error()) {
@@ -703,6 +726,9 @@ void Initialize(Environment* env, Local<Object> target) {
703726

704727
SetMethod(context, target, "secureBuffer", SecureBuffer);
705728
SetMethod(context, target, "secureHeapUsed", SecureHeapUsed);
729+
730+
SetMethodNoSideEffect(
731+
context, target, "getOpenSSLSecLevelCrypto", GetOpenSSLSecLevelCrypto);
706732
}
707733
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
708734
#ifndef OPENSSL_NO_ENGINE
@@ -714,6 +740,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
714740
registry->Register(TestFipsCrypto);
715741
registry->Register(SecureBuffer);
716742
registry->Register(SecureHeapUsed);
743+
registry->Register(GetOpenSSLSecLevelCrypto);
717744
}
718745

719746
} // namespace Util
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
4+
const common = require('../common');
5+
if (!common.hasCrypto)
6+
common.skip('missing crypto');
7+
8+
const assert = require('assert');
9+
10+
// OpenSSL has a set of security levels which affect what algorithms
11+
// are available by default. Different OpenSSL veresions have different
12+
// default security levels and we use this value to adjust what a test
13+
// expects based on the security level. You can read more in
14+
// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour
15+
// This test simply validates that we can get some value for the secLevel
16+
// when needed by tests.
17+
const secLevel = require('internal/crypto/util').getOpenSSLSecLevel();
18+
assert.ok(secLevel >= 0 && secLevel <= 5);

test/parallel/test-tls-dhe.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Flags: --no-warnings
1+
// Flags: --no-warnings --expose-internals
22
// Copyright Joyent, Inc. and other Node contributors.
33
//
44
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -27,10 +27,16 @@ if (!common.hasCrypto) {
2727
}
2828

2929
const {
30-
hasOpenSSL,
3130
opensslCli,
3231
} = require('../common/crypto');
3332

33+
// OpenSSL has a set of security levels which affect what algorithms
34+
// are available by default. Different OpenSSL veresions have different
35+
// default security levels and we use this value to adjust what a test
36+
// expects based on the security level. You can read more in
37+
// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour
38+
const secLevel = require('internal/crypto/util').getOpenSSLSecLevel();
39+
3440
if (!opensslCli) {
3541
common.skip('missing openssl-cli');
3642
}
@@ -50,7 +56,7 @@ const dheCipher = 'DHE-RSA-AES128-SHA256';
5056
const ecdheCipher = 'ECDHE-RSA-AES128-SHA256';
5157
const ciphers = `${dheCipher}:${ecdheCipher}`;
5258

53-
if (!hasOpenSSL(3, 2)) {
59+
if (secLevel < 2) {
5460
// Test will emit a warning because the DH parameter size is < 2048 bits
5561
// when the test is run on versions lower than OpenSSL32
5662
common.expectWarning('SecurityWarning',
@@ -114,7 +120,9 @@ function testCustomParam(keylen, expectedCipher) {
114120
}, /DH parameter is less than 1024 bits/);
115121

116122
// Custom DHE parameters are supported (but discouraged).
117-
if (!hasOpenSSL(3, 2)) {
123+
// 1024 is disallowed at security level 2 and above so use 3072 instead
124+
// for higher security levels
125+
if (secLevel < 2) {
118126
await testCustomParam(1024, dheCipher);
119127
} else {
120128
await testCustomParam(3072, dheCipher);

0 commit comments

Comments
 (0)