diff --git a/test/addons/openssl-providers/binding.cc b/test/addons/openssl-providers/binding.cc new file mode 100644 index 00000000000000..b65f168fdaf4cd --- /dev/null +++ b/test/addons/openssl-providers/binding.cc @@ -0,0 +1,46 @@ +#include +#include +#include + +namespace { + +using v8::Array; +using v8::Context; +using v8::FunctionCallbackInfo; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; + +#if OPENSSL_VERSION_MAJOR >= 3 +int collectProviders(OSSL_PROVIDER* provider, void* cbdata) { + static_cast*>(cbdata)->push_back(provider); + return 1; +} +#endif + +inline void GetProviders(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + std::vector> arr = {}; +#if OPENSSL_VERSION_MAJOR >= 3 + std::vector providers; + OSSL_PROVIDER_do_all(nullptr, &collectProviders, &providers); + for (auto provider : providers) { + arr.push_back( + String::NewFromUtf8(isolate, OSSL_PROVIDER_get0_name(provider)) + .ToLocalChecked()); + } +#endif + args.GetReturnValue().Set(Array::New(isolate, arr.data(), arr.size())); +} + +inline void Initialize(Local exports, + Local module, + Local context) { + NODE_SET_METHOD(exports, "getProviders", GetProviders); +} + +} // anonymous namespace + +NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, Initialize) diff --git a/test/addons/openssl-providers/binding.gyp b/test/addons/openssl-providers/binding.gyp new file mode 100644 index 00000000000000..c9ce9f1b2a6f6a --- /dev/null +++ b/test/addons/openssl-providers/binding.gyp @@ -0,0 +1,38 @@ +{ + 'targets': [ + { + 'target_name': 'binding', + 'includes': ['../common.gypi'], + 'conditions': [ + ['node_use_openssl=="true"', { + 'conditions': [ + ['OS=="aix"', { + 'variables': { + # Used to differentiate `AIX` and `OS400`(IBM i). + 'aix_variant_name': ' { createHash(hash); }, { code: 'ERR_OSSL_EVP_UNSUPPORTED' }); + } +} diff --git a/test/addons/openssl-providers/test-default-only-config.js b/test/addons/openssl-providers/test-default-only-config.js new file mode 100644 index 00000000000000..257f21819c31c0 --- /dev/null +++ b/test/addons/openssl-providers/test-default-only-config.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../../common'); +const { path: fixture } = require('../../common/fixtures'); +const providers = require('./providers.cjs'); + +const assert = require('node:assert'); +const { fork } = require('node:child_process'); +const option = `--openssl-config=${fixture('openssl3-conf', 'default_only.cnf')}`; + +if (!process.execArgv.includes(option)) { + const cp = fork(__filename, { execArgv: [option] }); + cp.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); + return; +} + +providers.testProviderPresent('default'); +providers.testProviderAbsent('legacy'); diff --git a/test/addons/openssl-providers/test-legacy-provider-config.js b/test/addons/openssl-providers/test-legacy-provider-config.js new file mode 100644 index 00000000000000..ff3800bf861dd1 --- /dev/null +++ b/test/addons/openssl-providers/test-legacy-provider-config.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../../common'); +const { path: fixture } = require('../../common/fixtures'); +const providers = require('./providers.cjs'); + +const assert = require('node:assert'); +const { fork } = require('node:child_process'); +const option = `--openssl-config=${fixture('openssl3-conf', 'legacy_provider_enabled.cnf')}`; + +if (!process.execArgv.includes(option)) { + const cp = fork(__filename, { execArgv: [option] }); + cp.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); + return; +} + +providers.testProviderPresent('default'); +providers.testProviderPresent('legacy'); diff --git a/test/addons/openssl-providers/test-legacy-provider-inactive-config.js b/test/addons/openssl-providers/test-legacy-provider-inactive-config.js new file mode 100644 index 00000000000000..dc7e9a4aea6625 --- /dev/null +++ b/test/addons/openssl-providers/test-legacy-provider-inactive-config.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../../common'); +const { path: fixture } = require('../../common/fixtures'); +const providers = require('./providers.cjs'); + +const assert = require('node:assert'); +const { fork } = require('node:child_process'); +const option = `--openssl-config=${fixture('openssl3-conf', 'legacy_provider_inactive.cnf')}`; + +if (!process.execArgv.includes(option)) { + const cp = fork(__filename, { execArgv: [option] }); + cp.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); + return; +} + +providers.testProviderPresent('default'); +providers.testProviderAbsent('legacy'); diff --git a/test/addons/openssl-providers/test-legacy-provider-option.js b/test/addons/openssl-providers/test-legacy-provider-option.js new file mode 100644 index 00000000000000..5ad60dac9b8625 --- /dev/null +++ b/test/addons/openssl-providers/test-legacy-provider-option.js @@ -0,0 +1,24 @@ +'use strict'; + +const common = require('../../common'); +const providers = require('./providers.cjs'); +const assert = require('node:assert'); +const { fork } = require('node:child_process'); +const { getFips } = require('node:crypto'); + +const option = '--openssl-legacy-provider'; +const execArgv = process.execArgv; +if (!execArgv.includes(option)) { + const cp = fork(__filename, { execArgv: [ option ] }); + cp.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); + return; +} + +// Enabling FIPS will make all legacy provider algorithms unavailable. +if (getFips()) { + common.skip('this test cannot be run in FIPS mode'); +} +providers.testProviderPresent('legacy'); diff --git a/test/addons/openssl-providers/test-no-legacy-provider-option.js b/test/addons/openssl-providers/test-no-legacy-provider-option.js new file mode 100644 index 00000000000000..8a6f9ef32f54d8 --- /dev/null +++ b/test/addons/openssl-providers/test-no-legacy-provider-option.js @@ -0,0 +1,18 @@ +'use strict'; + +const common = require('../../common'); +const providers = require('./providers.cjs'); +const assert = require('node:assert'); +const { fork } = require('node:child_process'); + +const option = '--no-openssl-legacy-provider'; +if (!process.execArgv.includes(option)) { + const cp = fork(__filename, { execArgv: [ option ] }); + cp.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); + return; +} + +providers.testProviderAbsent('legacy'); diff --git a/test/fixtures/openssl3-conf/default_only.cnf b/test/fixtures/openssl3-conf/default_only.cnf new file mode 100644 index 00000000000000..1cde58effb94a1 --- /dev/null +++ b/test/fixtures/openssl3-conf/default_only.cnf @@ -0,0 +1,11 @@ +nodejs_conf = nodejs_init + +[nodejs_init] +providers = provider_sect + +# List of providers to load +[provider_sect] +default = default_sect + +[default_sect] +activate = 1 diff --git a/test/fixtures/openssl3-conf/legacy_provider_enabled.cnf b/test/fixtures/openssl3-conf/legacy_provider_enabled.cnf new file mode 100644 index 00000000000000..5119ea52102568 --- /dev/null +++ b/test/fixtures/openssl3-conf/legacy_provider_enabled.cnf @@ -0,0 +1,15 @@ +nodejs_conf = nodejs_init + +[nodejs_init] +providers = provider_sect + +# List of providers to load +[provider_sect] +default = default_sect +legacy = legacy_sect + +[default_sect] +activate = 1 + +[legacy_sect] +activate = 1 diff --git a/test/fixtures/openssl3-conf/legacy_provider_inactive.cnf b/test/fixtures/openssl3-conf/legacy_provider_inactive.cnf new file mode 100644 index 00000000000000..5e9a8672405971 --- /dev/null +++ b/test/fixtures/openssl3-conf/legacy_provider_inactive.cnf @@ -0,0 +1,15 @@ +nodejs_conf = nodejs_init + +[nodejs_init] +providers = provider_sect + +# List of providers to load +[provider_sect] +default = default_sect +legacy = legacy_sect + +[default_sect] +activate = 1 + +[legacy_sect] +# 'activate' line intentionally omitted -- legacy provider should not be loaded.