diff --git a/node.gypi b/node.gypi index ad088b133be471..f9dba2d4bdd4f4 100644 --- a/node.gypi +++ b/node.gypi @@ -361,7 +361,11 @@ ], }], ], - }]] + }, { + # Set 1.0.0 as the API compability level to avoid the + # deprecation warnings when using OpenSSL 3.0. + 'defines': ['OPENSSL_API_COMPAT=0x10000000L'], + }]] }, { 'defines': [ 'HAVE_OPENSSL=0' ] diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 47764b5bc7f153..c9c3563ef917ec 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -342,8 +342,11 @@ void CipherBase::Init(const char* cipher_type, unsigned int auth_tag_len) { HandleScope scope(env()->isolate()); MarkPopErrorOnReturn mark_pop_error_on_return; - +#if OPENSSL_VERSION_MAJOR >= 3 + if (EVP_default_properties_is_fips_enabled(nullptr)) { +#else if (FIPS_mode()) { +#endif return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(), "crypto.createCipher() is not supported in FIPS mode."); } @@ -527,7 +530,13 @@ bool CipherBase::InitAuthenticated( } // TODO(tniessen) Support CCM decryption in FIPS mode + +#if OPENSSL_VERSION_MAJOR >= 3 + if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && + EVP_default_properties_is_fips_enabled(nullptr)) { +#else if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) { +#endif THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(), "CCM encryption not supported in FIPS mode"); return false; diff --git a/src/crypto/crypto_dsa.cc b/src/crypto/crypto_dsa.cc index d3446eb60a2789..6ee8cf7e18c02e 100644 --- a/src/crypto/crypto_dsa.cc +++ b/src/crypto/crypto_dsa.cc @@ -138,7 +138,7 @@ Maybe GetDsaKeyDetail( int type = EVP_PKEY_id(m_pkey.get()); CHECK(type == EVP_PKEY_DSA); - DSA* dsa = EVP_PKEY_get0_DSA(m_pkey.get()); + const DSA* dsa = EVP_PKEY_get0_DSA(m_pkey.get()); CHECK_NOT_NULL(dsa); DSA_get0_pqg(dsa, &p, &q, nullptr); diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc index 3e2c2031adb8e4..ea4c70ad5d8c84 100644 --- a/src/crypto/crypto_ec.cc +++ b/src/crypto/crypto_ec.cc @@ -463,19 +463,22 @@ bool ECDHBitsTraits::DeriveBits( char* data = nullptr; size_t len = 0; + ManagedEVPPKey m_privkey = params.private_->GetAsymmetricKey(); + ManagedEVPPKey m_pubkey = params.public_->GetAsymmetricKey(); switch (params.id_) { case EVP_PKEY_X25519: // Fall through case EVP_PKEY_X448: { - EVPKeyCtxPointer ctx( - EVP_PKEY_CTX_new( - params.private_->GetAsymmetricKey().get(), - nullptr)); + EVPKeyCtxPointer ctx = nullptr; + { + ctx.reset(EVP_PKEY_CTX_new(m_privkey.get(), nullptr)); + } + Mutex::ScopedLock pub_lock(*m_pubkey.mutex()); if (EVP_PKEY_derive_init(ctx.get()) <= 0 || EVP_PKEY_derive_set_peer( ctx.get(), - params.public_->GetAsymmetricKey().get()) <= 0 || + m_pubkey.get()) <= 0 || EVP_PKEY_derive(ctx.get(), nullptr, &len) <= 0) { return false; } @@ -492,10 +495,14 @@ bool ECDHBitsTraits::DeriveBits( break; } default: { - const EC_KEY* private_key = - EVP_PKEY_get0_EC_KEY(params.private_->GetAsymmetricKey().get()); - const EC_KEY* public_key = - EVP_PKEY_get0_EC_KEY(params.public_->GetAsymmetricKey().get()); + const EC_KEY* private_key; + { + Mutex::ScopedLock priv_lock(*m_privkey.mutex()); + private_key = EVP_PKEY_get0_EC_KEY(m_privkey.get()); + } + + Mutex::ScopedLock pub_lock(*m_pubkey.mutex()); + const EC_KEY* public_key = EVP_PKEY_get0_EC_KEY(m_pubkey.get()); const EC_GROUP* group = EC_KEY_get0_group(private_key); if (group == nullptr) @@ -607,7 +614,7 @@ WebCryptoKeyExportStatus EC_Raw_Export( CHECK(m_pkey); Mutex::ScopedLock lock(*m_pkey.mutex()); - EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(m_pkey.get()); + const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(m_pkey.get()); unsigned char* data; size_t len = 0; @@ -627,10 +634,10 @@ WebCryptoKeyExportStatus EC_Raw_Export( } CHECK_NOT_NULL(fn); // Get the size of the raw key data - if (fn(key_data->GetAsymmetricKey().get(), nullptr, &len) == 0) + if (fn(m_pkey.get(), nullptr, &len) == 0) return WebCryptoKeyExportStatus::INVALID_KEY_TYPE; data = MallocOpenSSL(len); - if (fn(key_data->GetAsymmetricKey().get(), data, &len) == 0) + if (fn(m_pkey.get(), data, &len) == 0) return WebCryptoKeyExportStatus::INVALID_KEY_TYPE; } else { if (key_data->GetKeyType() != kKeyTypePublic) @@ -696,7 +703,7 @@ Maybe ExportJWKEcKey( Mutex::ScopedLock lock(*m_pkey.mutex()); CHECK_EQ(EVP_PKEY_id(m_pkey.get()), EVP_PKEY_EC); - EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get()); + const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get()); CHECK_NOT_NULL(ec); const EC_POINT* pub = EC_KEY_get0_public_key(ec); @@ -751,6 +758,7 @@ Maybe ExportJWKEdKey( std::shared_ptr key, Local target) { ManagedEVPPKey pkey = key->GetAsymmetricKey(); + Mutex::ScopedLock lock(*pkey.mutex()); const char* curve = nullptr; switch (EVP_PKEY_id(pkey.get())) { @@ -902,7 +910,7 @@ Maybe GetEcKeyDetail( Mutex::ScopedLock lock(*m_pkey.mutex()); CHECK_EQ(EVP_PKEY_id(m_pkey.get()), EVP_PKEY_EC); - EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get()); + const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get()); CHECK_NOT_NULL(ec); const EC_GROUP* group = EC_KEY_get0_group(ec); @@ -919,8 +927,8 @@ Maybe GetEcKeyDetail( // implementation here is a adapted from Chromium's impl here: // https://github.com/chromium/chromium/blob/7af6cfd/components/webcrypto/algorithms/ecdsa.cc -size_t GroupOrderSize(ManagedEVPPKey key) { - EC_KEY* ec = EVP_PKEY_get0_EC_KEY(key.get()); +size_t GroupOrderSize(const ManagedEVPPKey& key) { + const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(key.get()); CHECK_NOT_NULL(ec); const EC_GROUP* group = EC_KEY_get0_group(ec); BignumPointer order(BN_new()); diff --git a/src/crypto/crypto_hkdf.cc b/src/crypto/crypto_hkdf.cc index f6339b129baea6..0aa96ada47abe4 100644 --- a/src/crypto/crypto_hkdf.cc +++ b/src/crypto/crypto_hkdf.cc @@ -110,15 +110,15 @@ bool HKDFTraits::DeriveBits( !EVP_PKEY_CTX_set_hkdf_md(ctx.get(), params.digest) || !EVP_PKEY_CTX_set1_hkdf_salt( ctx.get(), - params.salt.get(), + reinterpret_cast(params.salt.get()), params.salt.size()) || !EVP_PKEY_CTX_set1_hkdf_key( ctx.get(), - params.key->GetSymmetricKey(), + reinterpret_cast(params.key->GetSymmetricKey()), params.key->GetSymmetricKeySize()) || !EVP_PKEY_CTX_add1_hkdf_info( ctx.get(), - params.info.get(), + reinterpret_cast(params.info.get()), params.info.size())) { return false; } diff --git a/src/crypto/crypto_keygen.h b/src/crypto/crypto_keygen.h index 6231eb7eef8320..e96d850cee1b5a 100644 --- a/src/crypto/crypto_keygen.h +++ b/src/crypto/crypto_keygen.h @@ -235,6 +235,9 @@ struct KeyPairGenConfig final : public MemoryRetainer { AlgorithmParams params; KeyPairGenConfig() = default; + ~KeyPairGenConfig() { + Mutex::ScopedLock priv_lock(*key.mutex()); + } explicit KeyPairGenConfig(KeyPairGenConfig&& other) noexcept : public_key_encoding(other.public_key_encoding), diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 4f0102a0eede41..f72ca8322db960 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -559,6 +559,8 @@ ManagedEVPPKey::ManagedEVPPKey(const ManagedEVPPKey& that) { } ManagedEVPPKey& ManagedEVPPKey::operator=(const ManagedEVPPKey& that) { + Mutex::ScopedLock lock(*that.mutex_); + pkey_.reset(that.get()); if (pkey_) diff --git a/src/crypto/crypto_keys.h b/src/crypto/crypto_keys.h index 21ccb73e330aa8..bf1498e62851eb 100644 --- a/src/crypto/crypto_keys.h +++ b/src/crypto/crypto_keys.h @@ -74,7 +74,7 @@ struct PrivateKeyEncodingConfig : public AsymmetricKeyEncodingConfig { // use. class ManagedEVPPKey : public MemoryRetainer { public: - ManagedEVPPKey() = default; + ManagedEVPPKey() : mutex_(std::make_shared()) {} explicit ManagedEVPPKey(EVPKeyPointer&& pkey); ManagedEVPPKey(const ManagedEVPPKey& that); ManagedEVPPKey& operator=(const ManagedEVPPKey& that); diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index c3250ea2e42ac1..22c20a3031899c 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -371,11 +371,11 @@ Maybe ExportJWKRsaKey( // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL // versions older than 1.1.1e via FIPS / dynamic linking. - RSA* rsa; + const RSA* rsa; if (OpenSSL_version_num() >= 0x1010105fL) { rsa = EVP_PKEY_get0_RSA(m_pkey.get()); } else { - rsa = static_cast(EVP_PKEY_get0(m_pkey.get())); + rsa = static_cast(EVP_PKEY_get0(m_pkey.get())); } CHECK_NOT_NULL(rsa); @@ -520,11 +520,11 @@ Maybe GetRsaKeyDetail( // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL // versions older than 1.1.1e via FIPS / dynamic linking. - RSA* rsa; + const RSA* rsa; if (OpenSSL_version_num() >= 0x1010105fL) { rsa = EVP_PKEY_get0_RSA(m_pkey.get()); } else { - rsa = static_cast(EVP_PKEY_get0(m_pkey.get())); + rsa = static_cast(EVP_PKEY_get0(m_pkey.get())); } CHECK_NOT_NULL(rsa); diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc index 946ac250f2fa01..cb1ce31be73700 100644 --- a/src/crypto/crypto_sig.cc +++ b/src/crypto/crypto_sig.cc @@ -28,8 +28,13 @@ namespace crypto { namespace { bool ValidateDSAParameters(EVP_PKEY* key) { /* Validate DSA2 parameters from FIPS 186-4 */ +#if OPENSSL_VERSION_MAJOR >= 3 + if (EVP_default_properties_is_fips_enabled(nullptr) && + EVP_PKEY_DSA == EVP_PKEY_base_id(key)) { +#else if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) { - DSA* dsa = EVP_PKEY_get0_DSA(key); +#endif + const DSA* dsa = EVP_PKEY_get0_DSA(key); const BIGNUM* p; DSA_get0_pqg(dsa, &p, nullptr, nullptr); size_t L = BN_num_bits(p); @@ -103,11 +108,11 @@ unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) { int bits, base_id = EVP_PKEY_base_id(pkey.get()); if (base_id == EVP_PKEY_DSA) { - DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get()); + const DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get()); // Both r and s are computed mod q, so their width is limited by that of q. bits = BN_num_bits(DSA_get0_q(dsa_key)); } else if (base_id == EVP_PKEY_EC) { - EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get()); + const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get()); const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key); bits = EC_GROUP_order_bits(ec_group); } else { @@ -873,7 +878,7 @@ bool SignTraits::DeriveBits( case SignConfiguration::kSign: { size_t len; unsigned char* data = nullptr; - if (IsOneShot(params.key->GetAsymmetricKey())) { + if (IsOneShot(m_pkey)) { EVP_DigestSign( context.get(), nullptr, @@ -905,10 +910,7 @@ bool SignTraits::DeriveBits( return false; if (UseP1363Encoding(m_pkey, params.dsa_encoding)) { - *out = ConvertSignatureToP1363( - env, - params.key->GetAsymmetricKey(), - buf); + *out = ConvertSignatureToP1363(env, m_pkey, buf); } else { buf.Resize(len); *out = std::move(buf); diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index 9644dc4dc7f9aa..9c35a7cabbf551 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -137,7 +137,12 @@ void InitCryptoOnce() { unsigned long err = 0; // NOLINT(runtime/int) if (per_process::cli_options->enable_fips_crypto || per_process::cli_options->force_fips_crypto) { +#if OPENSSL_VERSION_MAJOR >= 3 + if (0 == EVP_default_properties_is_fips_enabled(nullptr) && + !EVP_default_properties_enable_fips(nullptr, 1)) { +#else if (0 == FIPS_mode() && !FIPS_mode_set(1)) { +#endif err = ERR_get_error(); } } @@ -160,7 +165,12 @@ void InitCryptoOnce() { } void GetFipsCrypto(const FunctionCallbackInfo& args) { +#if OPENSSL_VERSION_MAJOR >= 3 + args.GetReturnValue().Set(EVP_default_properties_is_fips_enabled(nullptr) ? + 1 : 0); +#else args.GetReturnValue().Set(FIPS_mode() ? 1 : 0); +#endif } void SetFipsCrypto(const FunctionCallbackInfo& args) { @@ -168,10 +178,18 @@ void SetFipsCrypto(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); bool enable = args[0]->BooleanValue(env->isolate()); +#if OPENSSL_VERSION_MAJOR >= 3 + if (enable == EVP_default_properties_is_fips_enabled(nullptr)) +#else if (enable == FIPS_mode()) +#endif return; // No action needed. +#if OPENSSL_VERSION_MAJOR >= 3 + if (!EVP_default_properties_enable_fips(nullptr, enable)) { +#else if (!FIPS_mode_set(enable)) { +#endif unsigned long err = ERR_get_error(); // NOLINT(runtime/int) return ThrowCryptoError(env, err); } diff --git a/src/node.cc b/src/node.cc index c31b2255947255..f02f87a8b45671 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1060,8 +1060,12 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) { } // In the case of FIPS builds we should make sure // the random source is properly initialized first. +#if OPENSSL_VERSION_MAJOR >= 3 + if (EVP_default_properties_is_fips_enabled(nullptr)) { +#else if (FIPS_mode()) { OPENSSL_init(); +#endif } // V8 on Windows doesn't have a good source of entropy. Seed it from // OpenSSL's pool. diff --git a/test/common/index.js b/test/common/index.js index 7d08e5e71e981f..8190be9565e742 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -51,6 +51,9 @@ const noop = () => {}; const hasCrypto = Boolean(process.versions.openssl) && !process.env.NODE_SKIP_CRYPTO; +const hasOpenSSL3 = hasCrypto && + require('crypto').constants.OPENSSL_VERSION_NUMBER >= 805306368; + // Check for flags. Skip this for workers (both, the `cluster` module and // `worker_threads`) and child processes. // If the binary was built without-ssl then the crypto flags are @@ -726,6 +729,7 @@ const common = { getTTYfd, hasIntl, hasCrypto, + hasOpenSSL3, hasMultiLocalhost, invalidArgTypeHelper, isAIX, diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index a2fb2e82670567..ada50d6b9c9656 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -583,7 +583,8 @@ assert.throws( // Test Diffie-Hellman with two parties sharing a secret, // using various encodings as we go along { - const dh1 = crypto.createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); + const size = common.hasFipsCrypto || common.hasOpenSSL3 ? 1024 : 256; + const dh1 = crypto.createDiffieHellman(size); const p1 = dh1.getPrime('buffer'); const dh2 = crypto.createDiffieHellman(p1, 'base64'); const key1 = dh1.generateKeys(); diff --git a/test/parallel/test-crypto-cipheriv-decipheriv.js b/test/parallel/test-crypto-cipheriv-decipheriv.js index ea5b675db13487..87f3641fb188bd 100644 --- a/test/parallel/test-crypto-cipheriv-decipheriv.js +++ b/test/parallel/test-crypto-cipheriv-decipheriv.js @@ -193,7 +193,9 @@ assert.throws( errMessage); // But all other IV lengths should be accepted. -for (let n = 1; n < 256; n += 1) { +const minIvLength = common.hasOpenSSL3 ? 8 : 1; +const maxIvLength = common.hasOpenSSL3 ? 64 : 256; +for (let n = minIvLength; n < maxIvLength; n += 1) { if (common.hasFipsCrypto && n < 12) continue; crypto.createCipheriv('aes-128-gcm', Buffer.alloc(16), Buffer.alloc(n)); } diff --git a/test/parallel/test-crypto-classes.js b/test/parallel/test-crypto-classes.js index ce4e2922de8062..dd073274aef765 100644 --- a/test/parallel/test-crypto-classes.js +++ b/test/parallel/test-crypto-classes.js @@ -24,7 +24,7 @@ const TEST_CASES = { if (!common.hasFipsCrypto) { TEST_CASES.Cipher = ['aes192', 'secret']; TEST_CASES.Decipher = ['aes192', 'secret']; - TEST_CASES.DiffieHellman = [256]; + TEST_CASES.DiffieHellman = [common.hasOpenSSL3 ? 1024 : 256]; } for (const [clazz, args] of Object.entries(TEST_CASES)) { diff --git a/test/parallel/test-crypto-dh-leak.js b/test/parallel/test-crypto-dh-leak.js index 5c4c0c61d4f41c..fe8c138ac2c98f 100644 --- a/test/parallel/test-crypto-dh-leak.js +++ b/test/parallel/test-crypto-dh-leak.js @@ -12,7 +12,8 @@ const crypto = require('crypto'); const before = process.memoryUsage.rss(); { - const dh = crypto.createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); + const size = common.hasFipsCrypto || common.hasOpenSSL3 ? 1024 : 256; + const dh = crypto.createDiffieHellman(size); const publicKey = dh.generateKeys(); const privateKey = dh.getPrivateKey(); for (let i = 0; i < 5e4; i += 1) { diff --git a/test/parallel/test-crypto-dh-odd-key.js b/test/parallel/test-crypto-dh-odd-key.js index d5410daca6fb23..69a1eb56c866b3 100644 --- a/test/parallel/test-crypto-dh-odd-key.js +++ b/test/parallel/test-crypto-dh-odd-key.js @@ -30,7 +30,7 @@ const crypto = require('crypto'); function test() { const odd = Buffer.alloc(39, 'A'); - const c = crypto.createDiffieHellman(32); + const c = crypto.createDiffieHellman(common.hasOpenSSL3 ? 1024 : 32); c.setPrivateKey(odd); c.generateKeys(); } diff --git a/test/parallel/test-crypto-dh-stateless.js b/test/parallel/test-crypto-dh-stateless.js index 3d0c1b497d7adc..9e26a318669c4e 100644 --- a/test/parallel/test-crypto-dh-stateless.js +++ b/test/parallel/test-crypto-dh-stateless.js @@ -57,7 +57,6 @@ const alicePrivateKey = crypto.createPrivateKey({ '-----END PRIVATE KEY-----', format: 'pem' }); - const alicePublicKey = crypto.createPublicKey({ key: '-----BEGIN PUBLIC KEY-----\n' + 'MIIBnzCB1QYJKoZIhvcNAQMBMIHHAoHBAP//////////yQ/aoiFowjTExmKLgNwc\n' + @@ -135,7 +134,6 @@ const dh = crypto.createDiffieHellman(group.getPrime(), group.getGenerator()); dh.setPrivateKey(privateKey); // Test simple Diffie-Hellman, no curves involved. - test({ publicKey: alicePublicKey, privateKey: alicePrivateKey }, { publicKey: bobPublicKey, privateKey: bobPrivateKey }, dh.computeSecret(publicKey)); @@ -146,23 +144,31 @@ test(crypto.generateKeyPairSync('dh', { group: 'modp5' }), test(crypto.generateKeyPairSync('dh', { group: 'modp5' }), crypto.generateKeyPairSync('dh', { prime: group.getPrime() })); -for (const [params1, params2] of [ +const list = [ // Same generator, but different primes. - [{ group: 'modp5' }, { group: 'modp18' }], + [{ group: 'modp5' }, { group: 'modp18' }]]; + +// TODO(danbev): Take a closer look if there should be a check in OpenSSL3 +// when the dh parameters differ. +if (!common.hasOpenSSL3) { // Same primes, but different generator. - [{ group: 'modp5' }, { prime: group.getPrime(), generator: 5 }], + list.push([{ group: 'modp5' }, { prime: group.getPrime(), generator: 5 }]); // Same generator, but different primes. - [{ primeLength: 1024 }, { primeLength: 1024 }] -]) { + list.push([{ primeLength: 1024 }, { primeLength: 1024 }]); +} + +for (const [params1, params2] of list) { assert.throws(() => { test(crypto.generateKeyPairSync('dh', params1), crypto.generateKeyPairSync('dh', params2)); - }, { + }, common.hasOpenSSL3 ? { + name: 'Error', + code: 'ERR_OSSL_DH_INVALID_PUBLIC_KEY' + } : { name: 'Error', code: 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS' }); } - { const privateKey = crypto.createPrivateKey({ key: '-----BEGIN PRIVATE KEY-----\n' + @@ -214,7 +220,10 @@ const not256k1 = crypto.getCurves().find((c) => /^sec.*(224|384|512)/.test(c)); assert.throws(() => { test(crypto.generateKeyPairSync('ec', { namedCurve: 'secp256k1' }), crypto.generateKeyPairSync('ec', { namedCurve: not256k1 })); -}, { +}, common.hasOpenSSL3 ? { + name: 'Error', + code: 'ERR_OSSL_EC_INCOMPATIBLE_OBJECTS' +} : { name: 'Error', code: 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS' }); diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index 5336301391b6c7..d08d07de4f8063 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -8,7 +8,8 @@ const crypto = require('crypto'); // Test Diffie-Hellman with two parties sharing a secret, // using various encodings as we go along -const dh1 = crypto.createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); +const size = common.hasFipsCrypto || common.hasOpenSSL3 ? 1024 : 256; +const dh1 = crypto.createDiffieHellman(size); const p1 = dh1.getPrime('buffer'); const dh2 = crypto.createDiffieHellman(p1, 'buffer'); let key1 = dh1.generateKeys(); @@ -38,11 +39,19 @@ assert.throws(() => crypto.createDiffieHellman('abcdef', 13.37), { }); for (const bits of [-1, 0, 1]) { - assert.throws(() => crypto.createDiffieHellman(bits), { - code: 'ERR_OSSL_BN_BITS_TOO_SMALL', - name: 'Error', - message: /bits too small/, - }); + if (common.hasOpenSSL3) { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_DH_MODULUS_TOO_SMALL', + name: 'Error', + message: /modulus too small/, + }); + } else { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_BN_BITS_TOO_SMALL', + name: 'Error', + message: /bits too small/, + }); + } } // Through a fluke of history, g=0 defaults to DH_GENERATOR (2). @@ -143,13 +152,23 @@ const secret4 = dh4.computeSecret(key2, 'hex', 'base64'); assert.strictEqual(secret1, secret4); -const wrongBlockLength = { - message: 'error:0606506D:digital envelope' + - ' routines:EVP_DecryptFinal_ex:wrong final block length', - code: 'ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH', - library: 'digital envelope routines', - reason: 'wrong final block length' -}; +let wrongBlockLength; +if (common.hasOpenSSL3) { + wrongBlockLength = { + message: 'error:1C80006B:Provider routines::wrong final block length', + code: 'ERR_OSSL_WRONG_FINAL_BLOCK_LENGTH', + library: 'Provider routines', + reason: 'wrong final block length' + }; +} else { + wrongBlockLength = { + message: 'error:0606506D:digital envelope' + + ' routines:EVP_DecryptFinal_ex:wrong final block length', + code: 'ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH', + library: 'digital envelope routines', + reason: 'wrong final block length' + }; +} // Run this one twice to make sure that the dh3 clears its error properly { @@ -168,7 +187,9 @@ const wrongBlockLength = { assert.throws(() => { dh3.computeSecret(''); -}, { message: 'Supplied key is too small' }); +}, { message: common.hasOpenSSL3 ? + 'error:02800066:Diffie-Hellman routines::invalid public key' : + 'Supplied key is too small' }); // Create a shared using a DH group. const alice = crypto.createDiffieHellmanGroup('modp5'); diff --git a/test/parallel/test-crypto-ecb.js b/test/parallel/test-crypto-ecb.js index c88ebaabb05e7f..aecd858ef3bf1e 100644 --- a/test/parallel/test-crypto-ecb.js +++ b/test/parallel/test-crypto-ecb.js @@ -27,6 +27,10 @@ if (!common.hasCrypto) if (common.hasFipsCrypto) common.skip('BF-ECB is not FIPS 140-2 compatible'); +if (common.hasOpenSSL3) + common.skip('Blowfish is only available with the legacy provider in ' + + 'OpenSSl 3.x'); + const assert = require('assert'); const crypto = require('crypto'); diff --git a/test/parallel/test-crypto-fips.js b/test/parallel/test-crypto-fips.js index a1ed6451842c54..204951514a8ede 100644 --- a/test/parallel/test-crypto-fips.js +++ b/test/parallel/test-crypto-fips.js @@ -66,21 +66,6 @@ testHelper( 'require("crypto").getFips()', { ...process.env, 'OPENSSL_CONF': '' }); -// --enable-fips should turn FIPS mode on -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips'], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); - -// --force-fips should turn FIPS mode on -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips'], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); // If Node was configured using --shared-openssl fips support might be // available depending on how OpenSSL was built. If fips support is @@ -120,120 +105,140 @@ if (!sharedOpenSSL()) { Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); } -testHelper( - 'stdout', - [`--openssl-config=${CNF_FIPS_OFF}`], - FIPS_DISABLED, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_ON })); +// OpenSSL 3.x has changed the configuration files so the following tests +// will not work as expected with that version. +// TODO(danbev) Revisit these test once FIPS support is available in +// OpenSSL 3.x. +if (!common.hasOpenSSL3) { + testHelper( + 'stdout', + [`--openssl-config=${CNF_FIPS_OFF}`], + FIPS_DISABLED, + 'require("crypto").getFips()', + Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_ON })); -// --enable-fips should take precedence over OpenSSL config file -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips', `--openssl-config=${CNF_FIPS_OFF}`], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); + // --enable-fips should take precedence over OpenSSL config file + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--enable-fips', `--openssl-config=${CNF_FIPS_OFF}`], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").getFips()', + process.env); + // --force-fips should take precedence over OpenSSL config file + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--force-fips', `--openssl-config=${CNF_FIPS_OFF}`], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").getFips()', + process.env); + // --enable-fips should turn FIPS mode on + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--enable-fips'], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").getFips()', + process.env); -// OPENSSL_CONF should _not_ make a difference to --enable-fips -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips'], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); + // --force-fips should turn FIPS mode on + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--force-fips'], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").getFips()', + process.env); -// --force-fips should take precedence over OpenSSL config file -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips', `--openssl-config=${CNF_FIPS_OFF}`], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); + // OPENSSL_CONF should _not_ make a difference to --enable-fips + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--enable-fips'], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").getFips()', + Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); -// Using OPENSSL_CONF should not make a difference to --force-fips -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips'], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); + // Using OPENSSL_CONF should not make a difference to --force-fips + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--force-fips'], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").getFips()', + Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); -// setFipsCrypto should be able to turn FIPS mode on -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - [], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").getFips())', - process.env); + // setFipsCrypto should be able to turn FIPS mode on + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + [], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + '(require("crypto").setFips(true),' + + 'require("crypto").getFips())', + process.env); -// setFipsCrypto should be able to turn FIPS mode on and off -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - [], - testFipsCrypto() ? FIPS_DISABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").setFips(false),' + - 'require("crypto").getFips())', - process.env); + // setFipsCrypto should be able to turn FIPS mode on and off + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + [], + testFipsCrypto() ? FIPS_DISABLED : FIPS_UNSUPPORTED_ERROR_STRING, + '(require("crypto").setFips(true),' + + 'require("crypto").setFips(false),' + + 'require("crypto").getFips())', + process.env); -// setFipsCrypto takes precedence over OpenSSL config file, FIPS on -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - [`--openssl-config=${CNF_FIPS_OFF}`], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").getFips())', - process.env); - -// setFipsCrypto takes precedence over OpenSSL config file, FIPS off -testHelper( - 'stdout', - [`--openssl-config=${CNF_FIPS_ON}`], - FIPS_DISABLED, - '(require("crypto").setFips(false),' + - 'require("crypto").getFips())', - process.env); + // setFipsCrypto takes precedence over OpenSSL config file, FIPS on + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + [`--openssl-config=${CNF_FIPS_OFF}`], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + '(require("crypto").setFips(true),' + + 'require("crypto").getFips())', + process.env); -// --enable-fips does not prevent use of setFipsCrypto API -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips'], - testFipsCrypto() ? FIPS_DISABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(false),' + - 'require("crypto").getFips())', - process.env); - -// --force-fips prevents use of setFipsCrypto API -testHelper( - 'stderr', - ['--force-fips'], - testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").setFips(false)', - process.env); + // setFipsCrypto takes precedence over OpenSSL config file, FIPS off + testHelper( + 'stdout', + [`--openssl-config=${CNF_FIPS_ON}`], + FIPS_DISABLED, + '(require("crypto").setFips(false),' + + 'require("crypto").getFips())', + process.env); -// --force-fips makes setFipsCrypto enable a no-op (FIPS stays on) -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips'], - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").getFips())', - process.env); - -// --force-fips and --enable-fips order does not matter -testHelper( - 'stderr', - ['--force-fips', '--enable-fips'], - testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").setFips(false)', - process.env); + // --enable-fips does not prevent use of setFipsCrypto API + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--enable-fips'], + testFipsCrypto() ? FIPS_DISABLED : FIPS_UNSUPPORTED_ERROR_STRING, + '(require("crypto").setFips(false),' + + 'require("crypto").getFips())', + process.env); -// --enable-fips and --force-fips order does not matter -testHelper( - 'stderr', - ['--enable-fips', '--force-fips'], - testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").setFips(false)', - process.env); + // --force-fips prevents use of setFipsCrypto API + testHelper( + 'stderr', + ['--force-fips'], + testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").setFips(false)', + process.env); + + // --force-fips makes setFipsCrypto enable a no-op (FIPS stays on) + testHelper( + testFipsCrypto() ? 'stdout' : 'stderr', + ['--force-fips'], + testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, + '(require("crypto").setFips(true),' + + 'require("crypto").getFips())', + process.env); + + // --force-fips and --enable-fips order does not matter + testHelper( + 'stderr', + ['--force-fips', '--enable-fips'], + testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").setFips(false)', + process.env); + + // --enable-fips and --force-fips order does not matter + testHelper( + 'stderr', + ['--enable-fips', '--force-fips'], + testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, + 'require("crypto").setFips(false)', + process.env); +} diff --git a/test/parallel/test-crypto-hkdf.js b/test/parallel/test-crypto-hkdf.js index 777f184d6b8366..ee9f56c87c430d 100644 --- a/test/parallel/test-crypto-hkdf.js +++ b/test/parallel/test-crypto-hkdf.js @@ -113,11 +113,14 @@ const { }); } -[ +const algorithms = [ ['sha256', 'secret', 'salt', 'info', 10], ['sha512', 'secret', 'salt', '', 15], - ['whirlpool', 'secret', '', 'info', 20], -].forEach(([ hash, secret, salt, info, length ]) => { +]; +if (!common.hasOpenSSL3) + algorithms.push(['whirlpool', 'secret', '', 'info', 20]); + +algorithms.forEach(([ hash, secret, salt, info, length ]) => { { const syncResult = hkdfSync(hash, secret, salt, info, length); assert(syncResult instanceof ArrayBuffer); @@ -204,7 +207,8 @@ const { } }); -{ + +if (!common.hasOpenSSL3) { const kKnownUnsupported = ['shake128', 'shake256']; getHashes() .filter((hash) => !kKnownUnsupported.includes(hash)) diff --git a/test/parallel/test-crypto-key-objects.js b/test/parallel/test-crypto-key-objects.js index 6ee5334851dace..871d5da66c2bd3 100644 --- a/test/parallel/test-crypto-key-objects.js +++ b/test/parallel/test-crypto-key-objects.js @@ -292,7 +292,9 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', // This should not cause a crash: https://github.com/nodejs/node/issues/25247 assert.throws(() => { createPrivateKey({ key: '' }); - }, { + }, common.hasOpenSSL3 ? { + message: 'Failed to read private key', + } : { message: 'error:0909006C:PEM routines:get_name:no start line', code: 'ERR_OSSL_PEM_NO_START_LINE', reason: 'no start line', @@ -500,7 +502,10 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', { // Reading an encrypted key without a passphrase should fail. - assert.throws(() => createPrivateKey(privateDsa), { + assert.throws(() => createPrivateKey(privateDsa), common.hasOpenSSL3 ? { + name: 'Error', + message: 'Failed to read private key', + } : { name: 'TypeError', code: 'ERR_MISSING_PASSPHRASE', message: 'Passphrase required for encrypted key' @@ -512,7 +517,7 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', key: privateDsa, format: 'pem', passphrase: Buffer.alloc(1025, 'a') - }), { + }), common.hasOpenSSL3 ? { name: 'Error' } : { code: 'ERR_OSSL_PEM_BAD_PASSWORD_READ', name: 'Error' }); @@ -524,7 +529,9 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', format: 'pem', passphrase: Buffer.alloc(1024, 'a') }), { - message: /bad decrypt/ + message: common.hasOpenSSL3 ? + 'Failed to read private key' : + /bad decrypt/ }); const publicKey = createPublicKey(publicDsa); diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js index b80b35135743d9..af73d5a6b45fd6 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -192,7 +192,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); // Now do the same with an encrypted private key. generateKeyPair('rsa', { - publicExponent: 0x1001, + publicExponent: 0x10001, modulusLength: 512, publicKeyEncoding, privateKeyEncoding: { @@ -210,11 +210,15 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); // Since the private key is encrypted, signing shouldn't work anymore. const publicKey = { key: publicKeyDER, ...publicKeyEncoding }; - assert.throws(() => testSignVerify(publicKey, privateKey), { + const expectedError = common.hasOpenSSL3 ? { + name: 'Error', + message: 'Failed to read private key' + } : { name: 'TypeError', code: 'ERR_MISSING_PASSPHRASE', message: 'Passphrase required for encrypted key' - }); + }; + assert.throws(() => testSignVerify(publicKey, privateKey), expectedError); const key = { key: privateKey, passphrase: 'secret' }; testEncryptDecrypt(publicKey, key); @@ -342,7 +346,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); // Test async DSA key generation. generateKeyPair('dsa', { - modulusLength: 512, + modulusLength: common.hasOpenSSL3 ? 2048 : 512, divisorLength: 256, publicKeyEncoding: { type: 'spki', @@ -359,8 +363,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); // The private key is DER-encoded. assert(Buffer.isBuffer(privateKeyDER)); - assertApproximateSize(publicKey, 440); - assertApproximateSize(privateKeyDER, 336); + assertApproximateSize(publicKey, common.hasOpenSSL3 ? 1194 : 440); + assertApproximateSize(privateKeyDER, common.hasOpenSSL3 ? 721 : 336); // Since the private key is encrypted, signing shouldn't work anymore. assert.throws(() => { @@ -382,7 +386,6 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); }); })); } - { // Test async DSA key object generation. generateKeyPair('dsa', { @@ -471,11 +474,14 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); assert(sec1EncExp('AES-128-CBC').test(privateKey)); // Since the private key is encrypted, signing shouldn't work anymore. - assert.throws(() => testSignVerify(publicKey, privateKey), { - name: 'TypeError', - code: 'ERR_MISSING_PASSPHRASE', - message: 'Passphrase required for encrypted key' - }); + assert.throws(() => testSignVerify(publicKey, privateKey), + common.hasOpenSSL3 ? { + message: 'Failed to read private key' + } : { + name: 'TypeError', + code: 'ERR_MISSING_PASSPHRASE', + message: 'Passphrase required for encrypted key' + }); testSignVerify(publicKey, { key: privateKey, passphrase: 'secret' }); })); @@ -501,11 +507,14 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); assert(sec1EncExp('AES-128-CBC').test(privateKey)); // Since the private key is encrypted, signing shouldn't work anymore. - assert.throws(() => testSignVerify(publicKey, privateKey), { - name: 'TypeError', - code: 'ERR_MISSING_PASSPHRASE', - message: 'Passphrase required for encrypted key' - }); + assert.throws(() => testSignVerify(publicKey, privateKey), + common.hasOpenSSL3 ? { + message: 'Failed to read private key' + } : { + name: 'TypeError', + code: 'ERR_MISSING_PASSPHRASE', + message: 'Passphrase required for encrypted key' + }); testSignVerify(publicKey, { key: privateKey, passphrase: 'secret' }); })); @@ -534,11 +543,14 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); assert(pkcs8EncExp.test(privateKey)); // Since the private key is encrypted, signing shouldn't work anymore. - assert.throws(() => testSignVerify(publicKey, privateKey), { - name: 'TypeError', - code: 'ERR_MISSING_PASSPHRASE', - message: 'Passphrase required for encrypted key' - }); + assert.throws(() => testSignVerify(publicKey, privateKey), + common.hasOpenSSL3 ? { + message: 'Failed to read private key' + } : { + name: 'TypeError', + code: 'ERR_MISSING_PASSPHRASE', + message: 'Passphrase required for encrypted key' + }); testSignVerify(publicKey, { key: privateKey, @@ -568,11 +580,14 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); assert(pkcs8EncExp.test(privateKey)); // Since the private key is encrypted, signing shouldn't work anymore. - assert.throws(() => testSignVerify(publicKey, privateKey), { - name: 'TypeError', - code: 'ERR_MISSING_PASSPHRASE', - message: 'Passphrase required for encrypted key' - }); + assert.throws(() => testSignVerify(publicKey, privateKey), + common.hasOpenSSL3 ? { + message: 'Failed to read private key' + } : { + name: 'TypeError', + code: 'ERR_MISSING_PASSPHRASE', + message: 'Passphrase required for encrypted key' + }); testSignVerify(publicKey, { key: privateKey, @@ -1246,7 +1261,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); } } -{ +if (!common.hasOpenSSL3) { // Passing an empty passphrase string should not cause OpenSSL's default // passphrase prompt in the terminal. // See https://github.com/nodejs/node/issues/35898. diff --git a/test/parallel/test-crypto-padding.js b/test/parallel/test-crypto-padding.js index 909c014bd0f87a..f1f14b472997e7 100644 --- a/test/parallel/test-crypto-padding.js +++ b/test/parallel/test-crypto-padding.js @@ -82,12 +82,17 @@ assert.strictEqual(enc(EVEN_LENGTH_PLAIN, true), EVEN_LENGTH_ENCRYPTED); assert.throws(function() { // Input must have block length %. enc(ODD_LENGTH_PLAIN, false); -}, { +}, common.hasOpenSSL3 ? { + message: 'error:1C80006B:Provider routines::wrong final block length', + code: 'ERR_OSSL_WRONG_FINAL_BLOCK_LENGTH', + reason: 'wrong final block length', +} : { message: 'error:0607F08A:digital envelope routines:EVP_EncryptFinal_ex:' + 'data not multiple of block length', code: 'ERR_OSSL_EVP_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH', reason: 'data not multiple of block length', -}); +} +); assert.strictEqual( enc(EVEN_LENGTH_PLAIN, false), EVEN_LENGTH_ENCRYPTED_NOPAD @@ -104,7 +109,11 @@ assert.strictEqual(dec(EVEN_LENGTH_ENCRYPTED, false).length, 48); assert.throws(function() { // Must have at least 1 byte of padding (PKCS): assert.strictEqual(dec(EVEN_LENGTH_ENCRYPTED_NOPAD, true), EVEN_LENGTH_PLAIN); -}, { +}, common.hasOpenSSL3 ? { + message: 'error:1C800064:Provider routines::bad decrypt', + reason: 'bad decrypt', + code: 'ERR_OSSL_BAD_DECRYPT', +} : { message: 'error:06065064:digital envelope routines:EVP_DecryptFinal_ex:' + 'bad decrypt', reason: 'bad decrypt', diff --git a/test/parallel/test-crypto-pbkdf2.js b/test/parallel/test-crypto-pbkdf2.js index ea0fbab7744b1f..260bdd394ce05e 100644 --- a/test/parallel/test-crypto-pbkdf2.js +++ b/test/parallel/test-crypto-pbkdf2.js @@ -223,9 +223,11 @@ assert.throws( } ); -const kNotPBKDF2Supported = ['shake128', 'shake256']; -crypto.getHashes() - .filter((hash) => !kNotPBKDF2Supported.includes(hash)) - .forEach((hash) => { - runPBKDF2(new Uint8Array(10), 'salt', 8, 8, hash); - }); +if (!common.hasOpenSSL3) { + const kNotPBKDF2Supported = ['shake128', 'shake256']; + crypto.getHashes() + .filter((hash) => !kNotPBKDF2Supported.includes(hash)) + .forEach((hash) => { + runPBKDF2(new Uint8Array(10), 'salt', 8, 8, hash); + }); +} diff --git a/test/parallel/test-crypto-private-decrypt-gh32240.js b/test/parallel/test-crypto-private-decrypt-gh32240.js index 4b48774145a3f8..875888622cb5f7 100644 --- a/test/parallel/test-crypto-private-decrypt-gh32240.js +++ b/test/parallel/test-crypto-private-decrypt-gh32240.js @@ -34,5 +34,7 @@ function decrypt(key) { } decrypt(pkey); -assert.throws(() => decrypt(pkeyEncrypted), { code: 'ERR_MISSING_PASSPHRASE' }); +assert.throws(() => decrypt(pkeyEncrypted), common.hasOpenSSL3 ? + { message: 'Failed to read asymmetric key' } : + { code: 'ERR_MISSING_PASSPHRASE' }); decrypt(pkey); // Should not throw. diff --git a/test/parallel/test-crypto-rsa-dsa.js b/test/parallel/test-crypto-rsa-dsa.js index 04de044be69aaa..94c810fa6f24c6 100644 --- a/test/parallel/test-crypto-rsa-dsa.js +++ b/test/parallel/test-crypto-rsa-dsa.js @@ -27,7 +27,7 @@ const dsaPkcs8KeyPem = fixtures.readKey('dsa_private_pkcs8.pem'); const ec = new TextEncoder(); -const decryptError = { +const openssl1DecryptError = { message: 'error:06065064:digital envelope routines:EVP_DecryptFinal_ex:' + 'bad decrypt', code: 'ERR_OSSL_EVP_BAD_DECRYPT', @@ -36,6 +36,13 @@ const decryptError = { library: 'digital envelope routines', }; +const decryptError = common.hasOpenSSL3 ? + { message: 'Failed to read asymmetric key' } : openssl1DecryptError; + +const decryptPrivateKeyError = common.hasOpenSSL3 ? { + message: 'Failed to read private key', +} : openssl1DecryptError; + function getBufferCopy(buf) { return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); } @@ -136,19 +143,25 @@ function getBufferCopy(buf) { assert.strictEqual(decryptedBufferWithPassword.toString(), input); // Now with RSA_NO_PADDING. Plaintext needs to match key size. - const plaintext = 'x'.repeat(rsaKeySize / 8); - encryptedBuffer = crypto.privateEncrypt({ - padding: crypto.constants.RSA_NO_PADDING, - key: rsaKeyPemEncrypted, - passphrase: bufferPassword - }, Buffer.from(plaintext)); - - decryptedBufferWithPassword = crypto.publicDecrypt({ - padding: crypto.constants.RSA_NO_PADDING, - key: rsaKeyPemEncrypted, - passphrase: bufferPassword - }, encryptedBuffer); - assert.strictEqual(decryptedBufferWithPassword.toString(), plaintext); + // OpenSSL 3.x has a rsa_check_padding that will cause an error if + // RSA_NO_PADDING is used. + if (!common.hasOpenSSL3) { + { + const plaintext = 'x'.repeat(rsaKeySize / 8); + encryptedBuffer = crypto.privateEncrypt({ + padding: crypto.constants.RSA_NO_PADDING, + key: rsaKeyPemEncrypted, + passphrase: bufferPassword + }, Buffer.from(plaintext)); + + decryptedBufferWithPassword = crypto.publicDecrypt({ + padding: crypto.constants.RSA_NO_PADDING, + key: rsaKeyPemEncrypted, + passphrase: bufferPassword + }, encryptedBuffer); + assert.strictEqual(decryptedBufferWithPassword.toString(), plaintext); + } + } encryptedBuffer = crypto.publicEncrypt(certPem, bufferToEncrypt); @@ -343,7 +356,7 @@ rsaSign.update(rsaPubPem); assert.throws(() => { const signOptions = { key: rsaKeyPemEncrypted, passphrase: 'wrong' }; rsaSign.sign(signOptions, 'hex'); -}, decryptError); +}, decryptPrivateKeyError); // // Test RSA signing and verification @@ -442,7 +455,7 @@ const input = 'I AM THE WALRUS'; sign.update(input); assert.throws(() => { sign.sign({ key: dsaKeyPemEncrypted, passphrase: 'wrong' }, 'hex'); - }, decryptError); + }, decryptPrivateKeyError); } { diff --git a/test/parallel/test-crypto-secure-heap.js b/test/parallel/test-crypto-secure-heap.js index f6bdc3a2d8a05c..fd6a90658d129d 100644 --- a/test/parallel/test-crypto-secure-heap.js +++ b/test/parallel/test-crypto-secure-heap.js @@ -29,7 +29,8 @@ if (process.argv[2] === 'child') { assert.strictEqual(a.used, 0); { - const dh1 = createDiffieHellman(common.hasFipsCrypto ? 1024 : 256); + const size = common.hasFipsCrypto || common.hasOpenSSL3 ? 1024 : 256; + const dh1 = createDiffieHellman(size); const p1 = dh1.getPrime('buffer'); const dh2 = createDiffieHellman(p1, 'buffer'); const key1 = dh1.generateKeys(); diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index 8240e3685a42ee..dc90e5b311bdf3 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -44,7 +44,9 @@ const keySize = 2048; `-----BEGIN RSA PRIVATE KEY----- AAAAAAAAAAAA -----END RSA PRIVATE KEY-----`); - }, { message: 'bye, bye, library' }); + }, { message: common.hasOpenSSL3 ? + 'Failed to read private key' : + 'bye, bye, library' }); delete Object.prototype.library; @@ -63,7 +65,9 @@ const keySize = 2048; key: keyPem, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING }); - }, { message: 'bye, bye, error stack' }); + }, { message: common.hasOpenSSL3 ? + 'error:1C8000A5:Provider routines::illegal or unsupported padding mode' : + 'bye, bye, error stack' }); delete Object.prototype.opensslErrorStack; } @@ -339,7 +343,10 @@ assert.throws( key: keyPem, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING }); - }, { + }, common.hasOpenSSL3 ? { + code: 'ERR_OSSL_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE', + message: /illegal or unsupported padding mode/, + } : { code: 'ERR_OSSL_RSA_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE', message: /illegal or unsupported padding mode/, opensslErrorStack: [ diff --git a/test/parallel/test-crypto-stream.js b/test/parallel/test-crypto-stream.js index 2d005c89db3f09..008ab129f0e019 100644 --- a/test/parallel/test-crypto-stream.js +++ b/test/parallel/test-crypto-stream.js @@ -71,7 +71,11 @@ const cipher = crypto.createCipheriv('aes-128-cbc', key, iv); const decipher = crypto.createDecipheriv('aes-128-cbc', badkey, iv); cipher.pipe(decipher) - .on('error', common.expectsError({ + .on('error', common.expectsError(common.hasOpenSSL3 ? { + message: /bad decrypt/, + library: 'Provider routines', + reason: 'bad decrypt', + } : { message: /bad decrypt/, function: 'EVP_DecryptFinal_ex', library: 'digital envelope routines', diff --git a/test/parallel/test-crypto-x509.js b/test/parallel/test-crypto-x509.js index d768a1b9c5e661..0915cb61fd4226 100644 --- a/test/parallel/test-crypto-x509.js +++ b/test/parallel/test-crypto-x509.js @@ -46,9 +46,10 @@ OU=Node.js CN=ca1 emailAddress=ry@tinyclouds.org`; -const infoAccessCheck = `OCSP - URI:http://ocsp.nodejs.org/ -CA Issuers - URI:http://ca.nodejs.org/ca.cert -`; +let infoAccessCheck = `OCSP - URI:http://ocsp.nodejs.org/ +CA Issuers - URI:http://ca.nodejs.org/ca.cert`; +if (!common.hasOpenSSL3) + infoAccessCheck += '\n'; const der = Buffer.from( '308202d830820241a003020102020900ecc9b856270da9a830' + @@ -207,8 +208,11 @@ const der = Buffer.from( 'CN=ca1\n' + 'emailAddress=ry@tinyclouds.org', infoAccess: - 'OCSP - URI:http://ocsp.nodejs.org/\n' + - 'CA Issuers - URI:http://ca.nodejs.org/ca.cert\n', + common.hasOpenSSL3 ? + 'OCSP - URI:http://ocsp.nodejs.org/\n' + + 'CA Issuers - URI:http://ca.nodejs.org/ca.cert' : + 'OCSP - URI:http://ocsp.nodejs.org/\n' + + 'CA Issuers - URI:http://ca.nodejs.org/ca.cert\n', modulus: 'EF5440701637E28ABB038E5641F828D834C342A9D25EDBB86A2BF' + '6FBD809CB8E037A98B71708E001242E4DEB54C6164885F599DD87' + 'A23215745955BE20417E33C4D0D1B80C9DA3DE419A2607195D2FB' + diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index 6b72dbd21cd07d..623320fb1907f1 100644 --- a/test/parallel/test-crypto.js +++ b/test/parallel/test-crypto.js @@ -216,8 +216,13 @@ assert.throws(() => { ].join('\n'); crypto.createSign('SHA256').update('test').sign(priv); }, (err) => { - assert.ok(!('opensslErrorStack' in err)); - assert.throws(() => { throw err; }, { + if (!common.hasOpenSSL3) + assert.ok(!('opensslErrorStack' in err)); + assert.throws(() => { throw err; }, common.hasOpenSSL3 ? { + name: 'Error', + message: 'error:02000070:rsa routines::digest too big for rsa key', + library: 'rsa routines', + } : { name: 'Error', message: /routines:RSA_sign:digest too big for rsa key$/, library: 'rsa routines', @@ -228,30 +233,33 @@ assert.throws(() => { return true; }); -assert.throws(() => { - // The correct header inside `rsa_private_pkcs8_bad.pem` should have been - // -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- - // instead of - // -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- - const sha1_privateKey = fixtures.readKey('rsa_private_pkcs8_bad.pem', - 'ascii'); - // This would inject errors onto OpenSSL's error stack - crypto.createSign('sha1').sign(sha1_privateKey); -}, (err) => { - // Do the standard checks, but then do some custom checks afterwards. - assert.throws(() => { throw err; }, { - message: 'error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag', - library: 'asn1 encoding routines', - function: 'asn1_check_tlen', - reason: 'wrong tag', - code: 'ERR_OSSL_ASN1_WRONG_TAG', +if (!common.hasOpenSSL3) { + assert.throws(() => { + // The correct header inside `rsa_private_pkcs8_bad.pem` should have been + // -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- + // instead of + // -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- + const sha1_privateKey = fixtures.readKey('rsa_private_pkcs8_bad.pem', + 'ascii'); + // This would inject errors onto OpenSSL's error stack + crypto.createSign('sha1').sign(sha1_privateKey); + }, (err) => { + // Do the standard checks, but then do some custom checks afterwards. + assert.throws(() => { throw err; }, { + message: 'error:0D0680A8:asn1 encoding routines:asn1_check_tlen:' + + 'wrong tag', + library: 'asn1 encoding routines', + function: 'asn1_check_tlen', + reason: 'wrong tag', + code: 'ERR_OSSL_ASN1_WRONG_TAG', + }); + // Throws crypto error, so there is an opensslErrorStack property. + // The openSSL stack should have content. + assert(Array.isArray(err.opensslErrorStack)); + assert(err.opensslErrorStack.length > 0); + return true; }); - // Throws crypto error, so there is an opensslErrorStack property. - // The openSSL stack should have content. - assert(Array.isArray(err.opensslErrorStack)); - assert(err.opensslErrorStack.length > 0); - return true; -}); +} // Make sure memory isn't released before being returned console.log(crypto.randomBytes(16)); diff --git a/test/parallel/test-https-agent-additional-options.js b/test/parallel/test-https-agent-additional-options.js index 2b5446b9e3d194..c92b17641d0b58 100644 --- a/test/parallel/test-https-agent-additional-options.js +++ b/test/parallel/test-https-agent-additional-options.js @@ -13,6 +13,7 @@ const options = { cert: fixtures.readKey('agent1-cert.pem'), ca: fixtures.readKey('ca1-cert.pem'), minVersion: 'TLSv1.1', + ciphers: 'ALL@SECLEVEL=0' }; const server = https.Server(options, (req, res) => { @@ -27,6 +28,7 @@ function getBaseOptions(port) { ca: options.ca, rejectUnauthorized: true, servername: 'agent1', + ciphers: 'ALL@SECLEVEL=0' }; } diff --git a/test/parallel/test-https-agent-session-eviction.js b/test/parallel/test-https-agent-session-eviction.js index 3f5cd36e8b1799..940c43cc40bf15 100644 --- a/test/parallel/test-https-agent-session-eviction.js +++ b/test/parallel/test-https-agent-session-eviction.js @@ -13,7 +13,8 @@ const { SSL_OP_NO_TICKET } = require('crypto').constants; const options = { key: readKey('agent1-key.pem'), cert: readKey('agent1-cert.pem'), - secureOptions: SSL_OP_NO_TICKET + secureOptions: SSL_OP_NO_TICKET, + ciphers: 'RSA@SECLEVEL=0' }; // Create TLS1.2 server diff --git a/test/parallel/test-process-versions.js b/test/parallel/test-process-versions.js index 788c380449b802..666c8ead3b15d2 100644 --- a/test/parallel/test-process-versions.js +++ b/test/parallel/test-process-versions.js @@ -35,7 +35,13 @@ assert(/^\d+\.\d+\.\d+(?:\.\d+)?-node\.\d+(?: \(candidate\))?$/ assert(/^\d+$/.test(process.versions.modules)); if (common.hasCrypto) { - assert(/^\d+\.\d+\.\d+[a-z]?(\+quic)?(-fips)?$/.test(process.versions.openssl)); + const versionRegex = common.hasOpenSSL3 ? + // The following also matches a development version of OpenSSL 3.x which + // can be in the format '3.0.0-alpha4-dev'. This can be handy when building + // and linking against the main development branch of OpenSSL. + /^\d+\.\d+\.\d+(-[-a-z0-9]+)?$/ : + /^\d+\.\d+\.\d+[a-z]?(\+quic)?(-fips)?$/; + assert(versionRegex.test(process.versions.openssl)); } for (let i = 0; i < expected_keys.length; i++) { diff --git a/test/parallel/test-tls-alert-handling.js b/test/parallel/test-tls-alert-handling.js index f9f42e2d51c04d..bd86149bc5ac22 100644 --- a/test/parallel/test-tls-alert-handling.js +++ b/test/parallel/test-tls-alert-handling.js @@ -33,7 +33,7 @@ let iter = 0; const errorHandler = common.mustCall((err) => { assert.strictEqual(err.code, 'ERR_SSL_WRONG_VERSION_NUMBER'); assert.strictEqual(err.library, 'SSL routines'); - assert.strictEqual(err.function, 'ssl3_get_record'); + if (!common.hasOpenSSL3) assert.strictEqual(err.function, 'ssl3_get_record'); assert.strictEqual(err.reason, 'wrong version number'); errorReceived = true; if (canCloseServer()) @@ -89,7 +89,8 @@ function sendBADTLSRecord() { client.on('error', common.mustCall((err) => { assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION'); assert.strictEqual(err.library, 'SSL routines'); - assert.strictEqual(err.function, 'ssl3_read_bytes'); + if (!common.hasOpenSSL3) + assert.strictEqual(err.function, 'ssl3_read_bytes'); assert.strictEqual(err.reason, 'tlsv1 alert protocol version'); })); } diff --git a/test/parallel/test-tls-cert-ext-encoding.js b/test/parallel/test-tls-cert-ext-encoding.js index d4b89473dc126d..4556b5791851c5 100644 --- a/test/parallel/test-tls-cert-ext-encoding.js +++ b/test/parallel/test-tls-cert-ext-encoding.js @@ -3,6 +3,16 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); +if (common.hasOpenSSL3) + // TODO(danbev) This test fails with the following error: + // error:0D00008F:asn1 encoding routines::no matching choice type + // + // I've not been able to figure out the reason for this but there + // is a note in https://wiki.openssl.org/index.php/OpenSSL_3.0 which + // indicates that this might not work at the moment: + // "OCSP, PEM, ASN.1 have some very limited library context support" + common.skip('when using OpenSSL 3.x'); + // NOTE: This certificate is hand-generated, hence it is not located in // `test/fixtures/keys` to avoid confusion. // diff --git a/test/parallel/test-tls-client-renegotiation-13.js b/test/parallel/test-tls-client-renegotiation-13.js index 075eb70e917c06..a32baed0249a0a 100644 --- a/test/parallel/test-tls-client-renegotiation-13.js +++ b/test/parallel/test-tls-client-renegotiation-13.js @@ -29,7 +29,9 @@ connect({ const ok = client.renegotiate({}, common.mustCall((err) => { assert.throws(() => { throw err; }, { - message: 'error:1420410A:SSL routines:SSL_renegotiate:wrong ssl version', + message: common.hasOpenSSL3 ? + 'error:0A00010A:SSL routines::wrong ssl version' : + 'error:1420410A:SSL routines:SSL_renegotiate:wrong ssl version', code: 'ERR_SSL_WRONG_SSL_VERSION', library: 'SSL routines', reason: 'wrong ssl version', diff --git a/test/parallel/test-tls-getprotocol.js b/test/parallel/test-tls-getprotocol.js index a76ff0f3442a97..e4a16a818b5ba1 100644 --- a/test/parallel/test-tls-getprotocol.js +++ b/test/parallel/test-tls-getprotocol.js @@ -18,6 +18,7 @@ const clientConfigs = [ const serverConfig = { secureProtocol: 'TLS_method', + ciphers: 'RSA@SECLEVEL=0', key: fixtures.readKey('agent2-key.pem'), cert: fixtures.readKey('agent2-cert.pem') }; diff --git a/test/parallel/test-tls-key-mismatch.js b/test/parallel/test-tls-key-mismatch.js index b0c8affadefe95..fdbb3676267a9d 100644 --- a/test/parallel/test-tls-key-mismatch.js +++ b/test/parallel/test-tls-key-mismatch.js @@ -29,7 +29,8 @@ const fixtures = require('../common/fixtures'); const assert = require('assert'); const tls = require('tls'); -const errorMessageRegex = +const errorMessageRegex = common.hasOpenSSL3 ? + /^Error: error:05800074:x509 certificate routines::key values mismatch$/ : /^Error: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch$/; const options = { diff --git a/test/parallel/test-tls-min-max-version.js b/test/parallel/test-tls-min-max-version.js index 7ef0f12426537c..8dbef1fa37aa2d 100644 --- a/test/parallel/test-tls-min-max-version.js +++ b/test/parallel/test-tls-min-max-version.js @@ -14,6 +14,14 @@ const DEFAULT_MAX_VERSION = tls.DEFAULT_MAX_VERSION; function test(cmin, cmax, cprot, smin, smax, sprot, proto, cerr, serr) { assert(proto || cerr || serr, 'test missing any expectations'); + + let ciphers; + if (common.hasOpenSSL3 && (proto === 'TLSv1' || proto === 'TLSv1.1' || + proto === 'TLSv1_1_method' || proto === 'TLSv1_method' || + sprot === 'TLSv1_1_method' || sprot === 'TLSv1_method')) { + if (serr !== 'ERR_SSL_UNSUPPORTED_PROTOCOL') + ciphers = 'ALL@SECLEVEL=0'; + } // Report where test was called from. Strip leading garbage from // at Object. (file:line) // from the stack location, we only want the file:line part. @@ -25,6 +33,7 @@ function test(cmin, cmax, cprot, smin, smax, sprot, proto, cerr, serr) { minVersion: cmin, maxVersion: cmax, secureProtocol: cprot, + ciphers: ciphers }, server: { cert: keys.agent6.cert, @@ -32,11 +41,12 @@ function test(cmin, cmax, cprot, smin, smax, sprot, proto, cerr, serr) { minVersion: smin, maxVersion: smax, secureProtocol: sprot, + ciphers: ciphers }, }, common.mustCall((err, pair, cleanup) => { function u(_) { return _ === undefined ? 'U' : _; } console.log('test:', u(cmin), u(cmax), u(cprot), u(smin), u(smax), u(sprot), - 'expect', u(proto), u(cerr), u(serr)); + u(ciphers), 'expect', u(proto), u(cerr), u(serr)); console.log(' ', where); if (!proto) { console.log('client', pair.client.err ? pair.client.err.code : undefined); @@ -109,16 +119,19 @@ test(U, U, 'TLS_method', U, U, 'TLSv1_method', 'TLSv1'); // minimum (which is configurable via command line). if (DEFAULT_MIN_VERSION === 'TLSv1.3') { test(U, U, 'TLSv1_2_method', U, U, 'SSLv23_method', - U, 'ECONNRESET', 'ERR_SSL_INTERNAL_ERROR'); + U, 'ECONNRESET', common.hasOpenSSL3 ? + 'ERR_SSL_NO_PROTOCOLS_AVAILABLE' : 'ERR_SSL_INTERNAL_ERROR'); } else { test(U, U, 'TLSv1_2_method', U, U, 'SSLv23_method', 'TLSv1.2'); } if (DEFAULT_MIN_VERSION === 'TLSv1.3') { test(U, U, 'TLSv1_1_method', U, U, 'SSLv23_method', - U, 'ECONNRESET', 'ERR_SSL_INTERNAL_ERROR'); + U, 'ECONNRESET', common.hasOpenSSL3 ? + 'ERR_SSL_NO_PROTOCOLS_AVAILABLE' : 'ERR_SSL_INTERNAL_ERROR'); test(U, U, 'TLSv1_method', U, U, 'SSLv23_method', - U, 'ECONNRESET', 'ERR_SSL_INTERNAL_ERROR'); + U, 'ECONNRESET', common.hasOpenSSL3 ? + 'ERR_SSL_NO_PROTOCOLS_AVAILABLE' : 'ERR_SSL_INTERNAL_ERROR'); test(U, U, 'SSLv23_method', U, U, 'TLSv1_1_method', U, 'ERR_SSL_NO_PROTOCOLS_AVAILABLE', 'ERR_SSL_UNEXPECTED_MESSAGE'); test(U, U, 'SSLv23_method', U, U, 'TLSv1_method', diff --git a/test/parallel/test-tls-passphrase.js b/test/parallel/test-tls-passphrase.js index c3a99c3eb34833..610bbefe46c9c0 100644 --- a/test/parallel/test-tls-passphrase.js +++ b/test/parallel/test-tls-passphrase.js @@ -223,7 +223,8 @@ server.listen(0, common.mustCall(function() { }, onSecureConnect()); })).unref(); -const errMessagePassword = /bad decrypt/; +const errMessagePassword = common.hasOpenSSL3 ? + /processing error/ : /bad decrypt/; // Missing passphrase assert.throws(function() { diff --git a/test/parallel/test-tls-session-cache.js b/test/parallel/test-tls-session-cache.js index 2be093a4f596fc..92d39f763fc3b8 100644 --- a/test/parallel/test-tls-session-cache.js +++ b/test/parallel/test-tls-session-cache.js @@ -50,6 +50,7 @@ function doTest(testOptions, callback) { requestCert: true, rejectUnauthorized: false, secureProtocol: 'TLS_method', + ciphers: 'RSA@SECLEVEL=0' }; let requestCount = 0; let resumeCount = 0; diff --git a/test/parallel/test-tls-set-secure-context.js b/test/parallel/test-tls-set-secure-context.js index f72daff6ef14fb..1e2abffa98bf67 100644 --- a/test/parallel/test-tls-set-secure-context.js +++ b/test/parallel/test-tls-set-secure-context.js @@ -53,9 +53,12 @@ server.listen(0, common.mustCall(() => { server.setSecureContext(credentialOptions[1]); firstResponse.write('request-'); + const errorMessageRegex = common.hasOpenSSL3 ? + /^Error: self-signed certificate$/ : + /^Error: self signed certificate$/; await assert.rejects(async () => { await makeRequest(port, 3); - }, /^Error: self signed certificate$/); + }, errorMessageRegex); server.setSecureContext(credentialOptions[0]); assert.strictEqual(await makeRequest(port, 4), 'success'); @@ -64,7 +67,7 @@ server.listen(0, common.mustCall(() => { firstResponse.end('fun!'); await assert.rejects(async () => { await makeRequest(port, 5); - }, /^Error: self signed certificate$/); + }, errorMessageRegex); assert.strictEqual(await firstRequest, 'multi-request-success-fun!'); server.close(); diff --git a/test/parallel/test-tls-write-error.js b/test/parallel/test-tls-write-error.js index 2783e62d063a28..776fe65c722637 100644 --- a/test/parallel/test-tls-write-error.js +++ b/test/parallel/test-tls-write-error.js @@ -16,7 +16,8 @@ const server_cert = fixtures.readKey('agent1-cert.pem'); const opts = { key: server_key, - cert: server_cert + cert: server_cert, + ciphers: 'ALL@SECLEVEL=0' }; const server = https.createServer(opts, (req, res) => {