diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 771589ed69b421..796aa77a6224d1 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -93,8 +93,24 @@ const EVP_MD* GetDigestCtxMd(const EVP_MD_CTX* ctx) { } #if NCRYPTO_USE_OPENSSL3_PROVIDER +using ASN1StringPointer = DeleteFnPtr; using OSSLParamBldPointer = DeleteFnPtr; -using OSSLParamPointer = DeleteFnPtr; +using RsaPssParamsPointer = DeleteFnPtr; +using X509AlgorPointer = DeleteFnPtr; +using X509PubkeyPointer = DeleteFnPtr; +struct OSSLParamDeleter { + void operator()(OSSL_PARAM* params) const { + if (params == nullptr) return; + for (OSSL_PARAM* param = params; param->key != nullptr; param++) { + if (param->data != nullptr && param->data_type != OSSL_PARAM_UTF8_PTR && + param->data_type != OSSL_PARAM_OCTET_PTR) { + OPENSSL_cleanse(param->data, param->data_size); + } + } + OSSL_PARAM_free(params); + } +}; +using OSSLParamPointer = std::unique_ptr; struct OpenSSLBufferDeleter { void operator()(unsigned char* pointer) const { OPENSSL_free(pointer); } }; @@ -106,9 +122,8 @@ static constexpr int kX509NameFlagsRFC2253WithinUtf8JSON = XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB & ~ASN1_STRFLGS_ESC_CTRL; #if NCRYPTO_USE_OPENSSL3_PROVIDER -bool GetPKeyBnParam(const EVP_PKEY* pkey, - const char* name, - DeleteFnPtr* out) { +template +bool GetPKeyBnParam(const EVP_PKEY* pkey, const char* name, Pointer* out) { BIGNUM* bn = nullptr; if (pkey == nullptr) return false; if (EVP_PKEY_get_bn_param(pkey, name, &bn) == 1) { @@ -135,9 +150,10 @@ bool GetPKeyBnParam(const EVP_PKEY* pkey, return true; } +template bool GetOptionalPKeyBnParam(const EVP_PKEY* pkey, const char* name, - DeleteFnPtr* out) { + Pointer* out) { BIGNUM* bn = nullptr; if (pkey == nullptr) { out->reset(); @@ -273,9 +289,11 @@ bool GetDhParams(const EVP_PKEY* pkey, bool GetDhKeys(const EVP_PKEY* pkey, DeleteFnPtr* pub, - DeleteFnPtr* priv) { - return GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_PUB_KEY, pub) && - GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_PRIV_KEY, priv); + DeleteFnPtr* priv) { + return (pub == nullptr || + GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_PUB_KEY, pub)) && + (priv == nullptr || + GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_PRIV_KEY, priv)); } #endif @@ -2287,8 +2305,7 @@ DataPointer DHPointer::getPublicKey() const { if (!dh_) return {}; DeleteFnPtr pub_key; - DeleteFnPtr pvt_key; - if (!GetDhKeys(dh_.get(), &pub_key, &pvt_key)) return {}; + if (!GetDhKeys(dh_.get(), &pub_key, nullptr)) return {}; return BignumPointer::Encode(pub_key.get()); #else const BIGNUM* pub_key; @@ -2303,9 +2320,8 @@ DataPointer DHPointer::getPrivateKey() const { if (pvt_key_) return pvt_key_.encode(); if (!dh_) return {}; - DeleteFnPtr pub_key; - DeleteFnPtr pvt_key; - if (!GetDhKeys(dh_.get(), &pub_key, &pvt_key)) return {}; + DeleteFnPtr pvt_key; + if (!GetDhKeys(dh_.get(), nullptr, &pvt_key)) return {}; return BignumPointer::Encode(pvt_key.get()); #else const BIGNUM* pvt_key; @@ -2320,9 +2336,8 @@ bool DHPointer::hasPrivateKey() const { if (pvt_key_) return true; if (!dh_) return false; - DeleteFnPtr pub_key; - DeleteFnPtr pvt_key; - if (!GetDhKeys(dh_.get(), &pub_key, &pvt_key)) return false; + DeleteFnPtr pvt_key; + if (!GetDhKeys(dh_.get(), nullptr, &pvt_key)) return false; return pvt_key != nullptr; #else const BIGNUM* pvt_key = nullptr; @@ -2358,7 +2373,7 @@ DataPointer DHPointer::generateKeys() { DeleteFnPtr p; DeleteFnPtr g; DeleteFnPtr pub_key; - DeleteFnPtr pvt_key; + DeleteFnPtr pvt_key; if (!GetDhParams(dh_.get(), &p, &g) || !GetDhKeys(dh_.get(), &pub_key, &pvt_key)) { return {}; @@ -2493,9 +2508,8 @@ bool DHPointer::setPublicKey(BignumPointer&& key) { return true; } - DeleteFnPtr pub_key; - DeleteFnPtr pvt_key; - if (!GetDhKeys(dh_.get(), &pub_key, &pvt_key)) { + DeleteFnPtr pvt_key; + if (!GetDhKeys(dh_.get(), nullptr, &pvt_key)) { return false; } EVPKeyPointer pkey; @@ -2532,8 +2546,7 @@ bool DHPointer::setPrivateKey(BignumPointer&& key) { } DeleteFnPtr pub_key; - DeleteFnPtr pvt_key; - if (!GetDhKeys(dh_.get(), &pub_key, &pvt_key)) { + if (!GetDhKeys(dh_.get(), &pub_key, nullptr)) { return false; } EVPKeyPointer pkey; @@ -3525,12 +3538,13 @@ bool WriteEncryptedTraditionalPEM(BIO* bio, size_t der_len = 0; OSSLEncoderCtxPointer ctx(OSSL_ENCODER_CTX_new_for_pkey( pkey, OSSL_KEYMGMT_SELECT_KEYPAIR, "DER", "pkcs1", nullptr)); - if (!ctx || OSSL_ENCODER_to_data(ctx.get(), &der, &der_len) != 1) { - return false; - } + if (!ctx) return false; + + const int result = OSSL_ENCODER_to_data(ctx.get(), &der, &der_len); + DataPointer der_storage(der, der_len); + if (result != 1) return false; - OpenSSLBufferPointer der_storage(der); - DERView der_view{der_storage.get(), der_len}; + DERView der_view{der_storage.get(), der_len}; return PEM_ASN1_write_bio( WriteDERView, PEM_STRING_RSA, @@ -4959,7 +4973,7 @@ bool ECKeyPointer::generate() { if (EVP_PKEY_keygen(ctx.get(), &raw) != 1) return false; EVPKeyPointer pkey(raw); - DeleteFnPtr priv; + DeleteFnPtr priv; if (!GetPKeyBnParam(pkey.get(), OSSL_PKEY_PARAM_PRIV_KEY, &priv)) { return false; } @@ -5674,6 +5688,66 @@ bool ReadRsaPssParams(const EVP_PKEY* pkey, Rsa::PssParams* params) { return true; } + +bool SetRsaPssHashAlgorithm(X509_ALGOR** out, const Digest& digest) { + if (EVP_MD_is_a(digest.get(), "SHA1")) return true; + + X509AlgorPointer algorithm(X509_ALGOR_new()); + if (!algorithm) return false; + X509_ALGOR_set_md(algorithm.get(), digest.get()); + *out = algorithm.release(); + return true; +} + +bool SetRsaPssMaskGenAlgorithm(X509_ALGOR** out, const Digest& digest) { + if (EVP_MD_is_a(digest.get(), "SHA1")) return true; + + X509AlgorPointer hash_algorithm(X509_ALGOR_new()); + if (!hash_algorithm) return false; + X509_ALGOR_set_md(hash_algorithm.get(), digest.get()); + + ASN1StringPointer hash_algorithm_der(ASN1_item_pack( + hash_algorithm.get(), ASN1_ITEM_rptr(X509_ALGOR), nullptr)); + if (!hash_algorithm_der) return false; + + X509AlgorPointer algorithm(X509_ALGOR_new()); + if (!algorithm || X509_ALGOR_set0(algorithm.get(), + OBJ_nid2obj(NID_mgf1), + V_ASN1_SEQUENCE, + hash_algorithm_der.get()) != 1) { + return false; + } + hash_algorithm_der.release(); + *out = algorithm.release(); + return true; +} + +ASN1StringPointer EncodeRsaPssParams(const Rsa::PssParams& params) { + const Digest digest = Digest::FromName(params.digest.data()); + if (!digest) return {}; + + const Digest mgf1_digest = params.mgf1_digest + ? Digest::FromName(params.mgf1_digest->data()) + : digest; + if (!mgf1_digest) return {}; + + RsaPssParamsPointer pss(RSA_PSS_PARAMS_new()); + if (!pss || !SetRsaPssHashAlgorithm(&pss->hashAlgorithm, digest) || + !SetRsaPssMaskGenAlgorithm(&pss->maskGenAlgorithm, mgf1_digest)) { + return {}; + } + + if (params.salt_length != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (pss->saltLength == nullptr || + ASN1_INTEGER_set_int64(pss->saltLength, params.salt_length) != 1) { + return {}; + } + } + + return ASN1StringPointer( + ASN1_item_pack(pss.get(), ASN1_ITEM_rptr(RSA_PSS_PARAMS), nullptr)); +} } // namespace Rsa::Rsa() : rsa_(false) {} @@ -5681,16 +5755,19 @@ Rsa::Rsa() : rsa_(false) {} Rsa::Rsa(const EVP_PKEY* pkey) : Rsa() { const int type = EVPKeyPointer::id(pkey); if (type != EVP_PKEY_RSA && type != EVP_PKEY_RSA_PSS) return; + rsa_pss_ = type == EVP_PKEY_RSA_PSS; if (!GetPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_N, &n_) || !GetPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_E, &e_)) { return; } - GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_D, &d_); - GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &p_); - GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &q_); - GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &dp_); - GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &dq_); - GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &qi_); + if (!GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_D, &d_) || + !GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &p_) || + !GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &q_) || + !GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &dp_) || + !GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &dq_) || + !GetOptionalPKeyBnParam(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &qi_)) { + return; + } if (type == EVP_PKEY_RSA_PSS) { MarkPopErrorOnReturn pop_errors; @@ -5774,7 +5851,35 @@ BIOPointer Rsa::derPublicKey() const { if (!bio) return {}; #if NCRYPTO_USE_OPENSSL3_PROVIDER auto pkey = EVPKeyPointer::NewRSA(*this); - if (!pkey || i2d_PUBKEY_bio(bio.get(), pkey.get()) != 1) return {}; + if (!pkey) return {}; + if (!rsa_pss_) { + if (i2d_PUBKEY_bio(bio.get(), pkey.get()) != 1) return {}; + return bio; + } + + X509_PUBKEY* raw_pubkey = nullptr; + const int result = X509_PUBKEY_set(&raw_pubkey, pkey.get()); + X509PubkeyPointer pubkey(raw_pubkey); + if (result != 1) return {}; + + int parameter_type = V_ASN1_UNDEF; + ASN1StringPointer parameters; + if (pss_params_) { + parameters = EncodeRsaPssParams(*pss_params_); + if (!parameters) return {}; + parameter_type = V_ASN1_SEQUENCE; + } + + if (X509_PUBKEY_set0_param(pubkey.get(), + OBJ_nid2obj(NID_rsaEncryption), + parameter_type, + parameters.get(), + nullptr, + 0) != 1) { + return {}; + } + parameters.release(); + if (i2d_X509_PUBKEY_bio(bio.get(), pubkey.get()) != 1) return {}; #else if (rsa_ == nullptr || i2d_RSA_PUBKEY_bio(bio.get(), rsa_) != 1) return {}; #endif diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 92b36a15dd6250..6fb6b384fd4fa4 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -639,14 +639,15 @@ class Rsa final { private: #if NCRYPTO_USE_OPENSSL3_PROVIDER bool rsa_ = false; + bool rsa_pss_ = false; DeleteFnPtr n_; DeleteFnPtr e_; - DeleteFnPtr d_; - DeleteFnPtr p_; - DeleteFnPtr q_; - DeleteFnPtr dp_; - DeleteFnPtr dq_; - DeleteFnPtr qi_; + DeleteFnPtr d_; + DeleteFnPtr p_; + DeleteFnPtr q_; + DeleteFnPtr dp_; + DeleteFnPtr dq_; + DeleteFnPtr qi_; std::optional pss_params_; #else OSSL3_CONST RSA* rsa_; @@ -1634,7 +1635,7 @@ class ECKeyPointer final { #if NCRYPTO_USE_OPENSSL3_PROVIDER DeleteFnPtr group_; DeleteFnPtr pub_; - DeleteFnPtr priv_; + DeleteFnPtr priv_; #else DeleteFnPtr key_; #endif diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index 2af9aacaefe460..a824e4e0ce90d2 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -206,7 +206,7 @@ void New(const FunctionCallbackInfo& args) { } } -#ifndef OPENSSL_IS_BORINGSSL +#if NCRYPTO_USE_OPENSSL3_PROVIDER if (BN_num_bits(bn_p.get()) >= 512 && BN_cmp(bn_g.get(), bn_p.get()) >= 0) { PutDhError(DH_R_BAD_GENERATOR); return ThrowCryptoError(env, ERR_get_error(), "Invalid generator"); diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index ad27108418353f..56fbde663cd1bb 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -315,6 +315,13 @@ bool ExportJWKRsaKey(Environment* env, if (key.GetKeyType() == kKeyTypePrivate) { auto pvt_key = rsa.getPrivateKey(); + if (pub_key.d == nullptr || pvt_key.p == nullptr || pvt_key.q == nullptr || + pvt_key.dp == nullptr || pvt_key.dq == nullptr || + pvt_key.qi == nullptr) { + THROW_ERR_CRYPTO_OPERATION_FAILED(env, + "Failed to export RSA private key"); + return false; + } if (SetEncodedValue(env, target, env->jwk_d_string(), pub_key.d) .IsNothing() || SetEncodedValue(env, target, env->jwk_p_string(), pvt_key.p) diff --git a/test/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index 77aab8f4182d4f..fddf584d7d41f7 100644 --- a/test/cctest/test_node_crypto_env.cc +++ b/test/cctest/test_node_crypto_env.cc @@ -1,11 +1,14 @@ #include #include "crypto/crypto_bio.h" +#include "crypto/crypto_keys.h" +#include "crypto/crypto_rsa.h" #include "gtest/gtest.h" #include "node_options.h" #include "node_test_fixture.h" #include "openssl/err.h" using v8::Local; +using v8::Object; using v8::String; /* @@ -31,3 +34,27 @@ TEST_F(NodeCryptoEnv, LoadBIO) { ASSERT_EQ(ERR_peek_error(), 0UL) << "There should not have left " "any errors on the OpenSSL error stack\n"; } + +#if NCRYPTO_USE_OPENSSL3_PROVIDER +TEST_F(NodeCryptoEnv, ExportIncompleteRsaPrivateKeyAsJwk) { + v8::HandleScope handle_scope(isolate_); + Argv argv; + Env env{handle_scope, argv}; + + ncrypto::Rsa rsa; + auto n = ncrypto::BignumPointer::New(); + auto e = ncrypto::BignumPointer::New(); + ASSERT_TRUE(n.setWord(3233)); + ASSERT_TRUE(e.setWord(17)); + ASSERT_TRUE(rsa.setPublicKey(std::move(n), std::move(e))); + + auto pkey = ncrypto::EVPKeyPointer::NewRSA(rsa); + ASSERT_TRUE(pkey); + auto key = node::crypto::KeyObjectData::CreateAsymmetric( + node::crypto::kKeyTypePrivate, std::move(pkey)); + + v8::TryCatch try_catch(isolate_); + EXPECT_FALSE(node::crypto::ExportJWKRsaKey(*env, key, Object::New(isolate_))); + EXPECT_TRUE(try_catch.HasCaught()); +} +#endif diff --git a/test/fixtures/keys/Makefile b/test/fixtures/keys/Makefile index c1e2fde9c3874b..128e928a59168e 100644 --- a/test/fixtures/keys/Makefile +++ b/test/fixtures/keys/Makefile @@ -71,6 +71,8 @@ all: \ rsa_private_4096.pem \ rsa_public_2048.pem \ rsa_public_4096.pem \ + rsa_pss_cert_2048.pem \ + rsa_pss_cert_2048_sha256_sha256_16.pem \ rsa_pss_private_2048.pem \ rsa_pss_private_2048_sha256_sha256_16.pem \ rsa_pss_private_2048_sha512_sha256_20.pem \ @@ -918,6 +920,12 @@ rsa_pss_private_2048_sha512_sha256_20.pem: rsa_pss_private_2048_sha1_sha1_20.pem: openssl genpkey -algorithm RSA-PSS -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 -pkeyopt rsa_pss_keygen_md:sha1 -pkeyopt rsa_pss_keygen_mgf1_md:sha1 -pkeyopt rsa_pss_keygen_saltlen:20 -out rsa_pss_private_2048_sha1_sha1_20.pem +rsa_pss_cert_2048.pem: rsa_pss_private_2048.pem + openssl req -new -x509 -key rsa_pss_private_2048.pem -subj "/CN=Node.js" -days 36500 -set_serial 1 -out rsa_pss_cert_2048.pem + +rsa_pss_cert_2048_sha256_sha256_16.pem: rsa_pss_private_2048_sha256_sha256_16.pem + openssl req -new -x509 -key rsa_pss_private_2048_sha256_sha256_16.pem -subj "/CN=Node.js" -days 36500 -set_serial 1 -out rsa_pss_cert_2048_sha256_sha256_16.pem + rsa_pss_public_2048.pem: rsa_pss_private_2048.pem openssl pkey -in rsa_pss_private_2048.pem -pubout -out rsa_pss_public_2048.pem diff --git a/test/fixtures/keys/rsa_pss_cert_2048.pem b/test/fixtures/keys/rsa_pss_cert_2048.pem new file mode 100644 index 00000000000000..33834d7f0eb385 --- /dev/null +++ b/test/fixtures/keys/rsa_pss_cert_2048.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAg6gAwIBAgIBATBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwEjEQMA4GA1UEAwwH +Tm9kZS5qczAgFw0yNjA3MTYyMjE4MzJaGA8yMTI2MDYyMjIyMTgzMlowEjEQMA4G +A1UEAwwHTm9kZS5qczCCASAwCwYJKoZIhvcNAQEKA4IBDwAwggEKAoIBAQDLg4x1 +Lzg+WAjkJEtt1u531G7u+msWvZg01SZ1PsPdiACmK/wKPMpcuJUOdswRP6XCa1qD +8RxmzFUIqi+y7fSlgBIGuIc6IxVi6L35lomhD3IjqU6MbVFu5QElc1KMcEnGoGqZ +yBk5vWZ1Gv95fOkAxYneF+4uiNTb7NRInf+u96l6lwsUbar2cDT48myQns+eHcvT +J2e/dTeF24yfk5V+b8nHUU/JmkPXzi0l9/434xjezeEhx+46cv0+XhE8Z5pMLhPW +jjrQ1obpsbtzZaGDo05pWBoUhqI1utNM0KlWN5PJqWxNdiVBDeGIqOy3RDul8USQ +kOjyqKotp3UyyXn3AgMBAAGjUzBRMB0GA1UdDgQWBBQDCGflRn9LTmklPpSFii4J +fQiQjTAfBgNVHSMEGDAWgBQDCGflRn9LTmklPpSFii4JfQiQjTAPBgNVHRMBAf8E +BTADAQH/MEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG +9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAsXJk8iu+XNSmIheNPvzfSoNp +7kkFqFjWRwo/a4vXb4Y7DRDsMeUM4dGNtN75Gj5bppnYtQ3ku/DWGLrVRPGs/sRx +itOJxvJzPNCv4yYUwm8p8ua7l1Sdmrder84XTG/Dm3dOoUOxCmEQzzjghXE0mRih +UC4aPyOGNHNlQg5YyEmfEnltlL12ls8cHE+5R56xeI34T/MukH0NVf7wNNfqrMqy +PrrXG79+D3+Jeu3ddtwvoKQyQ/VuszJGjdplkDodttyTfu3GOgC/bbR9iz2GkcTV +NEkjJHenMzpoAoNZukeuClOHF6NT3hBnKPmcZYlLPgIY1iOBYoGwctgb5pPxNg== +-----END CERTIFICATE----- diff --git a/test/fixtures/keys/rsa_pss_cert_2048_sha256_sha256_16.pem b/test/fixtures/keys/rsa_pss_cert_2048_sha256_sha256_16.pem new file mode 100644 index 00000000000000..5740ae9cff0659 --- /dev/null +++ b/test/fixtures/keys/rsa_pss_cert_2048_sha256_sha256_16.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkDCCAkSgAwIBAgIBATBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCARAwEjEQMA4GA1UEAwwH +Tm9kZS5qczAgFw0yNjA3MTYyMjAyMzVaGA8yMTI2MDYyMjIyMDIzNVowEjEQMA4G +A1UEAwwHTm9kZS5qczCCAVYwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEF +AKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEQA4IBDwAwggEKAoIB +AQDfqNM4C+QtD73iILqOkqfV8ha3O19jpX8UujIk1Z72bbbuwEzh0+sBw0dD0N8C +gkXnePOEEd6q7HNmbyCNqRpDK6NDvaCMDWgEaD/PlHkRntvKh81IXSMC5imjRfOc +ZIE/Gnw7h8tanab0n75+ODvLJrmEWUG2q79Im1mWMx7Spod+Np6XEY+7I7nAUUWi +vr35Yx5DeyxY8rxFGpsLtGsi7JNQO4aHyeBpj8tz0Fhv23uPywE2nGmPHfnkXWbr +TcHGbzYBgEbeSH9KUkRwczqDXNOPhtfaEHEFTm0MoeKCnJe1VOjSywev77dV1KZf +pVh3Kh0ZRQIe9YOVJhj4lMx3AgMBAAGjUzBRMB0GA1UdDgQWBBRrGC6N4gEM/Il9 +PMkKs+dhCbldkjAfBgNVHSMEGDAWgBRrGC6N4gEM/Il9PMkKs+dhCbldkjAPBgNV +HRMBAf8EBTADAQH/MEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAa +BgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBEAOCAQEA1SP4HNSgQm2OpuRb +VjEDyVANpCyuKjUFY0FAwart4YSKHwERuR5VccugGwlbnH0vKQ2uwTB/a5BlXssg +0KB8qjDoOoxzhgZTA7yuHuQLpgCQhd00ORpxFYI1CyB+HywrpbuV4LHJoZjO7B6O +Z0PPRs77023WkT/O4KRrFH8uaMgPMwUIjIGXzSp+TYObLnYTWmGyJ7rJVwOPH30z ++BY++W0ZhkCuJveajuF3vGpA4o/lA0kcf6Hz2Prl28kHu0hOpZNTx2zMl+GFtlWE +TIybjAvbA4TJW0rAURRuP4lhYsPJAnZDAnxHFvLeLKypfctv7eAc82U8rVjT+DIA +NjayPQ== +-----END CERTIFICATE----- diff --git a/test/parallel/test-crypto-dh-curves.js b/test/parallel/test-crypto-dh-curves.js index be4c2079d99884..f14c58e7c200c1 100644 --- a/test/parallel/test-crypto-dh-curves.js +++ b/test/parallel/test-crypto-dh-curves.js @@ -9,6 +9,7 @@ const { hasOpenSSL } = require('../common/crypto'); const { DH_CHECK_P_NOT_PRIME, DH_CHECK_P_NOT_SAFE_PRIME, + DH_NOT_SUITABLE_GENERATOR, } = crypto.constants; // Second OAKLEY group, see @@ -76,6 +77,11 @@ if (hasOpenSSL(3)) { () => crypto.createDiffieHellman(Buffer.from(p, 'hex'), Buffer.from(p, 'hex')), { code: 'ERR_OSSL_DH_BAD_GENERATOR' }); +} else if (!process.features.openssl_is_boringssl) { + assert.strictEqual( + crypto.createDiffieHellman(Buffer.from(p, 'hex'), + Buffer.from(p, 'hex')).verifyError, + DH_NOT_SUITABLE_GENERATOR); } const availableCurves = new Set(crypto.getCurves()); diff --git a/test/parallel/test-crypto-x509.js b/test/parallel/test-crypto-x509.js index a122ee9e300f30..353699cf911725 100644 --- a/test/parallel/test-crypto-x509.js +++ b/test/parallel/test-crypto-x509.js @@ -7,6 +7,7 @@ if (!common.hasCrypto) const { X509Certificate, + createHash, createPrivateKey, generateKeyPairSync, createSign, @@ -27,6 +28,42 @@ const ca = readFileSync(fixtures.path('keys', 'ca1-cert.pem')); const privateKey = createPrivateKey(key); +if (!process.features.openssl_is_boringssl) { + const expectedPubkeys = hasOpenSSL3 ? [ + [ + 'rsa_pss_cert_2048.pem', + 292, + 'dff998a209bfa2e6ded1208c6e57f5b6bdedfa44b631265e3e244f38e637f6e4', + ], + [ + 'rsa_pss_cert_2048_sha256_sha256_16.pem', + 342, + 'da0bcd53fbe3969c7cc2730f86abc34e0e1c340264bbdfa3faf01484c2eeece0', + ], + ] : [ + [ + 'rsa_pss_cert_2048.pem', + 294, + '4d4f2f076aced4f0df922b84b466b0a60ba4cb50a23d695ae12ddc5fff7aca14', + ], + [ + 'rsa_pss_cert_2048_sha256_sha256_16.pem', + 294, + 'd37942c3bd02bc25c724fcd31efd647824e536c13d62d9ad0b5db8c0900d3cba', + ], + ]; + + for (const [name, length, digest] of expectedPubkeys) { + const pssCert = new X509Certificate( + readFileSync(fixtures.path('keys', name))); + const pubkey = pssCert.toLegacyObject().pubkey; + assert.strictEqual(pubkey.length, length); + assert.strictEqual( + createHash('sha256').update(pubkey).digest('hex'), + digest); + } +} + [1, {}, false, null].forEach((i) => { assert.throws(() => new X509Certificate(i), { code: 'ERR_INVALID_ARG_TYPE'