Skip to content

Commit 3f76985

Browse files
committed
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]>
1 parent 58ac655 commit 3f76985

File tree

4 files changed

+47
-3
lines changed

4 files changed

+47
-3
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 = 1;
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()) {
@@ -704,6 +727,9 @@ void Initialize(Environment* env, Local<Object> target) {
704727

705728
SetMethod(context, target, "secureBuffer", SecureBuffer);
706729
SetMethod(context, target, "secureHeapUsed", SecureHeapUsed);
730+
731+
SetMethodNoSideEffect(
732+
context, target, "getOpenSSLSecLevelCrypto", GetOpenSSLSecLevelCrypto);
707733
}
708734
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
709735
#ifndef OPENSSL_NO_ENGINE
@@ -715,6 +741,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
715741
registry->Register(TestFipsCrypto);
716742
registry->Register(SecureBuffer);
717743
registry->Register(SecureHeapUsed);
744+
registry->Register(GetOpenSSLSecLevelCrypto);
718745
}
719746

720747
} // namespace Util
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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+
const secLevel = require('internal/crypto/util').getOpenSSLSecLevel();
11+
assert.ok(secLevel >= 0 && secLevel <= 5);

test/parallel/test-tls-dhe.js

+7-3
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
@@ -25,6 +25,8 @@ const common = require('../common');
2525
if (!common.hasCrypto)
2626
common.skip('missing crypto');
2727

28+
const secLevel = require('internal/crypto/util').getOpenSSLSecLevel();
29+
2830
if (!common.opensslCli)
2931
common.skip('missing openssl-cli');
3032

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

46-
if (!common.hasOpenSSL(3, 2)) {
48+
if (secLevel < 2) {
4749
// Test will emit a warning because the DH parameter size is < 2048 bits
4850
// when the test is run on versions lower than OpenSSL32
4951
common.expectWarning('SecurityWarning',
@@ -107,7 +109,9 @@ function testCustomParam(keylen, expectedCipher) {
107109
}, /DH parameter is less than 1024 bits/);
108110

109111
// Custom DHE parameters are supported (but discouraged).
110-
if (!common.hasOpenSSL(3, 2)) {
112+
// 1024 is disallowed at security level 2 and above so use 3072 instead
113+
// for higher security levels
114+
if (secLevel < 2) {
111115
await testCustomParam(1024, dheCipher);
112116
} else {
113117
await testCustomParam(3072, dheCipher);

0 commit comments

Comments
 (0)