diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 48fecc82c159d8..aa5ba34c761224 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -1148,6 +1148,16 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { if (!ret) { // TODO(@jasnell): Should this use ThrowCryptoError? unsigned long err = ERR_get_error(); // NOLINT(runtime/int) + +#if OPENSSL_VERSION_MAJOR >= 3 + if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) { + // OpenSSL's "unsupported" error without any context is very + // common and not very helpful, so we override it: + return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION( + env, "Unsupported PKCS12 PFX data"); + } +#endif + const char* str = ERR_reason_error_string(err); str = str != nullptr ? str : "Unknown error"; diff --git a/test/fixtures/keys/legacy.pfx b/test/fixtures/keys/legacy.pfx new file mode 100644 index 00000000000000..66fa746fa5e573 Binary files /dev/null and b/test/fixtures/keys/legacy.pfx differ diff --git a/test/parallel/test-tls-legacy-pfx.js b/test/parallel/test-tls-legacy-pfx.js new file mode 100644 index 00000000000000..33b4c58fc6ccc3 --- /dev/null +++ b/test/parallel/test-tls-legacy-pfx.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +if (!common.hasOpenSSL3) + common.skip('OpenSSL legacy failures are only testable with OpenSSL 3+'); + +const fixtures = require('../common/fixtures'); + +const { + assert, connect, keys +} = require(fixtures.path('tls-connect')); + +const legacyPfx = fixtures.readKey('legacy.pfx'); + +connect({ + client: { + pfx: legacyPfx, + passphrase: 'legacy', + rejectUnauthorized: false + }, + server: keys.agent1 +}, common.mustCall((e, pair, cleanup) => { + assert.strictEqual(e.code, 'ERR_CRYPTO_UNSUPPORTED_OPERATION'); + assert.strictEqual(e.message, 'Unsupported PKCS12 PFX data'); + cleanup(); +}));