Skip to content

Commit 60039a2

Browse files
mhdawsontargos
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 <[email protected]> PR-URL: #56601 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]>
1 parent 50ebd5f commit 60039a2

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()) {
@@ -699,6 +722,9 @@ void Initialize(Environment* env, Local<Object> target) {
699722

700723
SetMethod(context, target, "secureBuffer", SecureBuffer);
701724
SetMethod(context, target, "secureHeapUsed", SecureHeapUsed);
725+
726+
SetMethodNoSideEffect(
727+
context, target, "getOpenSSLSecLevelCrypto", GetOpenSSLSecLevelCrypto);
702728
}
703729
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
704730
#ifndef OPENSSL_NO_ENGINE
@@ -710,6 +736,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
710736
registry->Register(TestFipsCrypto);
711737
registry->Register(SecureBuffer);
712738
registry->Register(SecureHeapUsed);
739+
registry->Register(GetOpenSSLSecLevelCrypto);
713740
}
714741

715742
} // 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)