11cb0ef41Sopenharmony_ci#include "crypto/crypto_rsa.h" 21cb0ef41Sopenharmony_ci#include "async_wrap-inl.h" 31cb0ef41Sopenharmony_ci#include "base_object-inl.h" 41cb0ef41Sopenharmony_ci#include "crypto/crypto_bio.h" 51cb0ef41Sopenharmony_ci#include "crypto/crypto_keys.h" 61cb0ef41Sopenharmony_ci#include "crypto/crypto_util.h" 71cb0ef41Sopenharmony_ci#include "env-inl.h" 81cb0ef41Sopenharmony_ci#include "memory_tracker-inl.h" 91cb0ef41Sopenharmony_ci#include "threadpoolwork-inl.h" 101cb0ef41Sopenharmony_ci#include "v8.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include <openssl/bn.h> 131cb0ef41Sopenharmony_ci#include <openssl/rsa.h> 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cinamespace node { 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciusing v8::ArrayBuffer; 181cb0ef41Sopenharmony_ciusing v8::BackingStore; 191cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo; 201cb0ef41Sopenharmony_ciusing v8::Int32; 211cb0ef41Sopenharmony_ciusing v8::Just; 221cb0ef41Sopenharmony_ciusing v8::Local; 231cb0ef41Sopenharmony_ciusing v8::Maybe; 241cb0ef41Sopenharmony_ciusing v8::Nothing; 251cb0ef41Sopenharmony_ciusing v8::Number; 261cb0ef41Sopenharmony_ciusing v8::Object; 271cb0ef41Sopenharmony_ciusing v8::String; 281cb0ef41Sopenharmony_ciusing v8::Uint32; 291cb0ef41Sopenharmony_ciusing v8::Value; 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_cinamespace crypto { 321cb0ef41Sopenharmony_ciEVPKeyCtxPointer RsaKeyGenTraits::Setup(RsaKeyPairGenConfig* params) { 331cb0ef41Sopenharmony_ci EVPKeyCtxPointer ctx( 341cb0ef41Sopenharmony_ci EVP_PKEY_CTX_new_id( 351cb0ef41Sopenharmony_ci params->params.variant == kKeyVariantRSA_PSS 361cb0ef41Sopenharmony_ci ? EVP_PKEY_RSA_PSS 371cb0ef41Sopenharmony_ci : EVP_PKEY_RSA, 381cb0ef41Sopenharmony_ci nullptr)); 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci if (EVP_PKEY_keygen_init(ctx.get()) <= 0) 411cb0ef41Sopenharmony_ci return EVPKeyCtxPointer(); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_keygen_bits( 441cb0ef41Sopenharmony_ci ctx.get(), 451cb0ef41Sopenharmony_ci params->params.modulus_bits) <= 0) { 461cb0ef41Sopenharmony_ci return EVPKeyCtxPointer(); 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci // 0x10001 is the default RSA exponent. 501cb0ef41Sopenharmony_ci if (params->params.exponent != 0x10001) { 511cb0ef41Sopenharmony_ci BignumPointer bn(BN_new()); 521cb0ef41Sopenharmony_ci CHECK_NOT_NULL(bn.get()); 531cb0ef41Sopenharmony_ci CHECK(BN_set_word(bn.get(), params->params.exponent)); 541cb0ef41Sopenharmony_ci // EVP_CTX accepts ownership of bn on success. 551cb0ef41Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx.get(), bn.get()) <= 0) 561cb0ef41Sopenharmony_ci return EVPKeyCtxPointer(); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci bn.release(); 591cb0ef41Sopenharmony_ci } 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci if (params->params.variant == kKeyVariantRSA_PSS) { 621cb0ef41Sopenharmony_ci if (params->params.md != nullptr && 631cb0ef41Sopenharmony_ci EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), params->params.md) <= 0) { 641cb0ef41Sopenharmony_ci return EVPKeyCtxPointer(); 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci // TODO(tniessen): This appears to only be necessary in OpenSSL 3, while 681cb0ef41Sopenharmony_ci // OpenSSL 1.1.1 behaves as recommended by RFC 8017 and defaults the MGF1 691cb0ef41Sopenharmony_ci // hash algorithm to the RSA-PSS hashAlgorithm. Remove this code if the 701cb0ef41Sopenharmony_ci // behavior of OpenSSL 3 changes. 711cb0ef41Sopenharmony_ci const EVP_MD* mgf1_md = params->params.mgf1_md; 721cb0ef41Sopenharmony_ci if (mgf1_md == nullptr && params->params.md != nullptr) { 731cb0ef41Sopenharmony_ci mgf1_md = params->params.md; 741cb0ef41Sopenharmony_ci } 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci if (mgf1_md != nullptr && 771cb0ef41Sopenharmony_ci EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md( 781cb0ef41Sopenharmony_ci ctx.get(), 791cb0ef41Sopenharmony_ci mgf1_md) <= 0) { 801cb0ef41Sopenharmony_ci return EVPKeyCtxPointer(); 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci int saltlen = params->params.saltlen; 841cb0ef41Sopenharmony_ci if (saltlen < 0 && params->params.md != nullptr) { 851cb0ef41Sopenharmony_ci saltlen = EVP_MD_size(params->params.md); 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci if (saltlen >= 0 && 891cb0ef41Sopenharmony_ci EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen( 901cb0ef41Sopenharmony_ci ctx.get(), 911cb0ef41Sopenharmony_ci saltlen) <= 0) { 921cb0ef41Sopenharmony_ci return EVPKeyCtxPointer(); 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci return ctx; 971cb0ef41Sopenharmony_ci} 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci// Input parameters to the RsaKeyGenJob: 1001cb0ef41Sopenharmony_ci// For key variants RSA-OAEP and RSA-SSA-PKCS1-v1_5 1011cb0ef41Sopenharmony_ci// 1. CryptoJobMode 1021cb0ef41Sopenharmony_ci// 2. Key Variant 1031cb0ef41Sopenharmony_ci// 3. Modulus Bits 1041cb0ef41Sopenharmony_ci// 4. Public Exponent 1051cb0ef41Sopenharmony_ci// 5. Public Format 1061cb0ef41Sopenharmony_ci// 6. Public Type 1071cb0ef41Sopenharmony_ci// 7. Private Format 1081cb0ef41Sopenharmony_ci// 8. Private Type 1091cb0ef41Sopenharmony_ci// 9. Cipher 1101cb0ef41Sopenharmony_ci// 10. Passphrase 1111cb0ef41Sopenharmony_ci// 1121cb0ef41Sopenharmony_ci// For RSA-PSS variant 1131cb0ef41Sopenharmony_ci// 1. CryptoJobMode 1141cb0ef41Sopenharmony_ci// 2. Key Variant 1151cb0ef41Sopenharmony_ci// 3. Modulus Bits 1161cb0ef41Sopenharmony_ci// 4. Public Exponent 1171cb0ef41Sopenharmony_ci// 5. Digest 1181cb0ef41Sopenharmony_ci// 6. mgf1 Digest 1191cb0ef41Sopenharmony_ci// 7. Salt length 1201cb0ef41Sopenharmony_ci// 8. Public Format 1211cb0ef41Sopenharmony_ci// 9. Public Type 1221cb0ef41Sopenharmony_ci// 10. Private Format 1231cb0ef41Sopenharmony_ci// 11. Private Type 1241cb0ef41Sopenharmony_ci// 12. Cipher 1251cb0ef41Sopenharmony_ci// 13. Passphrase 1261cb0ef41Sopenharmony_ciMaybe<bool> RsaKeyGenTraits::AdditionalConfig( 1271cb0ef41Sopenharmony_ci CryptoJobMode mode, 1281cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args, 1291cb0ef41Sopenharmony_ci unsigned int* offset, 1301cb0ef41Sopenharmony_ci RsaKeyPairGenConfig* params) { 1311cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci CHECK(args[*offset]->IsUint32()); // Variant 1341cb0ef41Sopenharmony_ci CHECK(args[*offset + 1]->IsUint32()); // Modulus bits 1351cb0ef41Sopenharmony_ci CHECK(args[*offset + 2]->IsUint32()); // Exponent 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci params->params.variant = 1381cb0ef41Sopenharmony_ci static_cast<RSAKeyVariant>(args[*offset].As<Uint32>()->Value()); 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci CHECK_IMPLIES(params->params.variant != kKeyVariantRSA_PSS, 1411cb0ef41Sopenharmony_ci args.Length() == 10); 1421cb0ef41Sopenharmony_ci CHECK_IMPLIES(params->params.variant == kKeyVariantRSA_PSS, 1431cb0ef41Sopenharmony_ci args.Length() == 13); 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci params->params.modulus_bits = args[*offset + 1].As<Uint32>()->Value(); 1461cb0ef41Sopenharmony_ci params->params.exponent = args[*offset + 2].As<Uint32>()->Value(); 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci *offset += 3; 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci if (params->params.variant == kKeyVariantRSA_PSS) { 1511cb0ef41Sopenharmony_ci if (!args[*offset]->IsUndefined()) { 1521cb0ef41Sopenharmony_ci CHECK(args[*offset]->IsString()); 1531cb0ef41Sopenharmony_ci Utf8Value digest(env->isolate(), args[*offset]); 1541cb0ef41Sopenharmony_ci params->params.md = EVP_get_digestbyname(*digest); 1551cb0ef41Sopenharmony_ci if (params->params.md == nullptr) { 1561cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest); 1571cb0ef41Sopenharmony_ci return Nothing<bool>(); 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci } 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci if (!args[*offset + 1]->IsUndefined()) { 1621cb0ef41Sopenharmony_ci CHECK(args[*offset + 1]->IsString()); 1631cb0ef41Sopenharmony_ci Utf8Value digest(env->isolate(), args[*offset + 1]); 1641cb0ef41Sopenharmony_ci params->params.mgf1_md = EVP_get_digestbyname(*digest); 1651cb0ef41Sopenharmony_ci if (params->params.mgf1_md == nullptr) { 1661cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_DIGEST( 1671cb0ef41Sopenharmony_ci env, "Invalid MGF1 digest: %s", *digest); 1681cb0ef41Sopenharmony_ci return Nothing<bool>(); 1691cb0ef41Sopenharmony_ci } 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci if (!args[*offset + 2]->IsUndefined()) { 1731cb0ef41Sopenharmony_ci CHECK(args[*offset + 2]->IsInt32()); 1741cb0ef41Sopenharmony_ci params->params.saltlen = args[*offset + 2].As<Int32>()->Value(); 1751cb0ef41Sopenharmony_ci if (params->params.saltlen < 0) { 1761cb0ef41Sopenharmony_ci THROW_ERR_OUT_OF_RANGE( 1771cb0ef41Sopenharmony_ci env, 1781cb0ef41Sopenharmony_ci "salt length is out of range"); 1791cb0ef41Sopenharmony_ci return Nothing<bool>(); 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci } 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci *offset += 3; 1841cb0ef41Sopenharmony_ci } 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci return Just(true); 1871cb0ef41Sopenharmony_ci} 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_cinamespace { 1901cb0ef41Sopenharmony_ciWebCryptoKeyExportStatus RSA_JWK_Export( 1911cb0ef41Sopenharmony_ci KeyObjectData* key_data, 1921cb0ef41Sopenharmony_ci const RSAKeyExportConfig& params, 1931cb0ef41Sopenharmony_ci ByteSource* out) { 1941cb0ef41Sopenharmony_ci return WebCryptoKeyExportStatus::FAILED; 1951cb0ef41Sopenharmony_ci} 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_citemplate <PublicKeyCipher::EVP_PKEY_cipher_init_t init, 1981cb0ef41Sopenharmony_ci PublicKeyCipher::EVP_PKEY_cipher_t cipher> 1991cb0ef41Sopenharmony_ciWebCryptoCipherStatus RSA_Cipher( 2001cb0ef41Sopenharmony_ci Environment* env, 2011cb0ef41Sopenharmony_ci KeyObjectData* key_data, 2021cb0ef41Sopenharmony_ci const RSACipherConfig& params, 2031cb0ef41Sopenharmony_ci const ByteSource& in, 2041cb0ef41Sopenharmony_ci ByteSource* out) { 2051cb0ef41Sopenharmony_ci CHECK_NE(key_data->GetKeyType(), kKeyTypeSecret); 2061cb0ef41Sopenharmony_ci ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey(); 2071cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(*m_pkey.mutex()); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(m_pkey.get(), nullptr)); 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci if (!ctx || init(ctx.get()) <= 0) 2121cb0ef41Sopenharmony_ci return WebCryptoCipherStatus::FAILED; 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), params.padding) <= 0) { 2151cb0ef41Sopenharmony_ci return WebCryptoCipherStatus::FAILED; 2161cb0ef41Sopenharmony_ci } 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci if (params.digest != nullptr && 2191cb0ef41Sopenharmony_ci (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), params.digest) <= 0 || 2201cb0ef41Sopenharmony_ci EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), params.digest) <= 0)) { 2211cb0ef41Sopenharmony_ci return WebCryptoCipherStatus::FAILED; 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci if (!SetRsaOaepLabel(ctx, params.label)) return WebCryptoCipherStatus::FAILED; 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci size_t out_len = 0; 2271cb0ef41Sopenharmony_ci if (cipher( 2281cb0ef41Sopenharmony_ci ctx.get(), 2291cb0ef41Sopenharmony_ci nullptr, 2301cb0ef41Sopenharmony_ci &out_len, 2311cb0ef41Sopenharmony_ci in.data<unsigned char>(), 2321cb0ef41Sopenharmony_ci in.size()) <= 0) { 2331cb0ef41Sopenharmony_ci return WebCryptoCipherStatus::FAILED; 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci ByteSource::Builder buf(out_len); 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci if (cipher(ctx.get(), 2391cb0ef41Sopenharmony_ci buf.data<unsigned char>(), 2401cb0ef41Sopenharmony_ci &out_len, 2411cb0ef41Sopenharmony_ci in.data<unsigned char>(), 2421cb0ef41Sopenharmony_ci in.size()) <= 0) { 2431cb0ef41Sopenharmony_ci return WebCryptoCipherStatus::FAILED; 2441cb0ef41Sopenharmony_ci } 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_ci *out = std::move(buf).release(out_len); 2471cb0ef41Sopenharmony_ci return WebCryptoCipherStatus::OK; 2481cb0ef41Sopenharmony_ci} 2491cb0ef41Sopenharmony_ci} // namespace 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ciMaybe<bool> RSAKeyExportTraits::AdditionalConfig( 2521cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args, 2531cb0ef41Sopenharmony_ci unsigned int offset, 2541cb0ef41Sopenharmony_ci RSAKeyExportConfig* params) { 2551cb0ef41Sopenharmony_ci CHECK(args[offset]->IsUint32()); // RSAKeyVariant 2561cb0ef41Sopenharmony_ci params->variant = 2571cb0ef41Sopenharmony_ci static_cast<RSAKeyVariant>(args[offset].As<Uint32>()->Value()); 2581cb0ef41Sopenharmony_ci return Just(true); 2591cb0ef41Sopenharmony_ci} 2601cb0ef41Sopenharmony_ci 2611cb0ef41Sopenharmony_ciWebCryptoKeyExportStatus RSAKeyExportTraits::DoExport( 2621cb0ef41Sopenharmony_ci std::shared_ptr<KeyObjectData> key_data, 2631cb0ef41Sopenharmony_ci WebCryptoKeyFormat format, 2641cb0ef41Sopenharmony_ci const RSAKeyExportConfig& params, 2651cb0ef41Sopenharmony_ci ByteSource* out) { 2661cb0ef41Sopenharmony_ci CHECK_NE(key_data->GetKeyType(), kKeyTypeSecret); 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci switch (format) { 2691cb0ef41Sopenharmony_ci case kWebCryptoKeyFormatRaw: 2701cb0ef41Sopenharmony_ci // Not supported for RSA keys of either type 2711cb0ef41Sopenharmony_ci return WebCryptoKeyExportStatus::FAILED; 2721cb0ef41Sopenharmony_ci case kWebCryptoKeyFormatJWK: 2731cb0ef41Sopenharmony_ci return RSA_JWK_Export(key_data.get(), params, out); 2741cb0ef41Sopenharmony_ci case kWebCryptoKeyFormatPKCS8: 2751cb0ef41Sopenharmony_ci if (key_data->GetKeyType() != kKeyTypePrivate) 2761cb0ef41Sopenharmony_ci return WebCryptoKeyExportStatus::INVALID_KEY_TYPE; 2771cb0ef41Sopenharmony_ci return PKEY_PKCS8_Export(key_data.get(), out); 2781cb0ef41Sopenharmony_ci case kWebCryptoKeyFormatSPKI: 2791cb0ef41Sopenharmony_ci if (key_data->GetKeyType() != kKeyTypePublic) 2801cb0ef41Sopenharmony_ci return WebCryptoKeyExportStatus::INVALID_KEY_TYPE; 2811cb0ef41Sopenharmony_ci return PKEY_SPKI_Export(key_data.get(), out); 2821cb0ef41Sopenharmony_ci default: 2831cb0ef41Sopenharmony_ci UNREACHABLE(); 2841cb0ef41Sopenharmony_ci } 2851cb0ef41Sopenharmony_ci} 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ciRSACipherConfig::RSACipherConfig(RSACipherConfig&& other) noexcept 2881cb0ef41Sopenharmony_ci : mode(other.mode), 2891cb0ef41Sopenharmony_ci label(std::move(other.label)), 2901cb0ef41Sopenharmony_ci padding(other.padding), 2911cb0ef41Sopenharmony_ci digest(other.digest) {} 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_civoid RSACipherConfig::MemoryInfo(MemoryTracker* tracker) const { 2941cb0ef41Sopenharmony_ci if (mode == kCryptoJobAsync) 2951cb0ef41Sopenharmony_ci tracker->TrackFieldWithSize("label", label.size()); 2961cb0ef41Sopenharmony_ci} 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ciMaybe<bool> RSACipherTraits::AdditionalConfig( 2991cb0ef41Sopenharmony_ci CryptoJobMode mode, 3001cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args, 3011cb0ef41Sopenharmony_ci unsigned int offset, 3021cb0ef41Sopenharmony_ci WebCryptoCipherMode cipher_mode, 3031cb0ef41Sopenharmony_ci RSACipherConfig* params) { 3041cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci params->mode = mode; 3071cb0ef41Sopenharmony_ci params->padding = RSA_PKCS1_OAEP_PADDING; 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci CHECK(args[offset]->IsUint32()); 3101cb0ef41Sopenharmony_ci RSAKeyVariant variant = 3111cb0ef41Sopenharmony_ci static_cast<RSAKeyVariant>(args[offset].As<Uint32>()->Value()); 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci switch (variant) { 3141cb0ef41Sopenharmony_ci case kKeyVariantRSA_OAEP: { 3151cb0ef41Sopenharmony_ci CHECK(args[offset + 1]->IsString()); // digest 3161cb0ef41Sopenharmony_ci Utf8Value digest(env->isolate(), args[offset + 1]); 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci params->digest = EVP_get_digestbyname(*digest); 3191cb0ef41Sopenharmony_ci if (params->digest == nullptr) { 3201cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest); 3211cb0ef41Sopenharmony_ci return Nothing<bool>(); 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci if (IsAnyByteSource(args[offset + 2])) { 3251cb0ef41Sopenharmony_ci ArrayBufferOrViewContents<char> label(args[offset + 2]); 3261cb0ef41Sopenharmony_ci if (UNLIKELY(!label.CheckSizeInt32())) { 3271cb0ef41Sopenharmony_ci THROW_ERR_OUT_OF_RANGE(env, "label is too big"); 3281cb0ef41Sopenharmony_ci return Nothing<bool>(); 3291cb0ef41Sopenharmony_ci } 3301cb0ef41Sopenharmony_ci params->label = label.ToCopy(); 3311cb0ef41Sopenharmony_ci } 3321cb0ef41Sopenharmony_ci break; 3331cb0ef41Sopenharmony_ci } 3341cb0ef41Sopenharmony_ci default: 3351cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_KEYTYPE(env); 3361cb0ef41Sopenharmony_ci return Nothing<bool>(); 3371cb0ef41Sopenharmony_ci } 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ci return Just(true); 3401cb0ef41Sopenharmony_ci} 3411cb0ef41Sopenharmony_ci 3421cb0ef41Sopenharmony_ciWebCryptoCipherStatus RSACipherTraits::DoCipher( 3431cb0ef41Sopenharmony_ci Environment* env, 3441cb0ef41Sopenharmony_ci std::shared_ptr<KeyObjectData> key_data, 3451cb0ef41Sopenharmony_ci WebCryptoCipherMode cipher_mode, 3461cb0ef41Sopenharmony_ci const RSACipherConfig& params, 3471cb0ef41Sopenharmony_ci const ByteSource& in, 3481cb0ef41Sopenharmony_ci ByteSource* out) { 3491cb0ef41Sopenharmony_ci switch (cipher_mode) { 3501cb0ef41Sopenharmony_ci case kWebCryptoCipherEncrypt: 3511cb0ef41Sopenharmony_ci CHECK_EQ(key_data->GetKeyType(), kKeyTypePublic); 3521cb0ef41Sopenharmony_ci return RSA_Cipher<EVP_PKEY_encrypt_init, EVP_PKEY_encrypt>( 3531cb0ef41Sopenharmony_ci env, key_data.get(), params, in, out); 3541cb0ef41Sopenharmony_ci case kWebCryptoCipherDecrypt: 3551cb0ef41Sopenharmony_ci CHECK_EQ(key_data->GetKeyType(), kKeyTypePrivate); 3561cb0ef41Sopenharmony_ci return RSA_Cipher<EVP_PKEY_decrypt_init, EVP_PKEY_decrypt>( 3571cb0ef41Sopenharmony_ci env, key_data.get(), params, in, out); 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci return WebCryptoCipherStatus::FAILED; 3601cb0ef41Sopenharmony_ci} 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ciMaybe<bool> ExportJWKRsaKey( 3631cb0ef41Sopenharmony_ci Environment* env, 3641cb0ef41Sopenharmony_ci std::shared_ptr<KeyObjectData> key, 3651cb0ef41Sopenharmony_ci Local<Object> target) { 3661cb0ef41Sopenharmony_ci ManagedEVPPKey m_pkey = key->GetAsymmetricKey(); 3671cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(*m_pkey.mutex()); 3681cb0ef41Sopenharmony_ci int type = EVP_PKEY_id(m_pkey.get()); 3691cb0ef41Sopenharmony_ci CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS); 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL 3721cb0ef41Sopenharmony_ci // versions older than 1.1.1e via FIPS / dynamic linking. 3731cb0ef41Sopenharmony_ci const RSA* rsa; 3741cb0ef41Sopenharmony_ci if (OpenSSL_version_num() >= 0x1010105fL) { 3751cb0ef41Sopenharmony_ci rsa = EVP_PKEY_get0_RSA(m_pkey.get()); 3761cb0ef41Sopenharmony_ci } else { 3771cb0ef41Sopenharmony_ci rsa = static_cast<const RSA*>(EVP_PKEY_get0(m_pkey.get())); 3781cb0ef41Sopenharmony_ci } 3791cb0ef41Sopenharmony_ci CHECK_NOT_NULL(rsa); 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci const BIGNUM* n; 3821cb0ef41Sopenharmony_ci const BIGNUM* e; 3831cb0ef41Sopenharmony_ci const BIGNUM* d; 3841cb0ef41Sopenharmony_ci const BIGNUM* p; 3851cb0ef41Sopenharmony_ci const BIGNUM* q; 3861cb0ef41Sopenharmony_ci const BIGNUM* dp; 3871cb0ef41Sopenharmony_ci const BIGNUM* dq; 3881cb0ef41Sopenharmony_ci const BIGNUM* qi; 3891cb0ef41Sopenharmony_ci RSA_get0_key(rsa, &n, &e, &d); 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci if (target->Set( 3921cb0ef41Sopenharmony_ci env->context(), 3931cb0ef41Sopenharmony_ci env->jwk_kty_string(), 3941cb0ef41Sopenharmony_ci env->jwk_rsa_string()).IsNothing()) { 3951cb0ef41Sopenharmony_ci return Nothing<bool>(); 3961cb0ef41Sopenharmony_ci } 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci if (SetEncodedValue(env, target, env->jwk_n_string(), n).IsNothing() || 3991cb0ef41Sopenharmony_ci SetEncodedValue(env, target, env->jwk_e_string(), e).IsNothing()) { 4001cb0ef41Sopenharmony_ci return Nothing<bool>(); 4011cb0ef41Sopenharmony_ci } 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_ci if (key->GetKeyType() == kKeyTypePrivate) { 4041cb0ef41Sopenharmony_ci RSA_get0_factors(rsa, &p, &q); 4051cb0ef41Sopenharmony_ci RSA_get0_crt_params(rsa, &dp, &dq, &qi); 4061cb0ef41Sopenharmony_ci if (SetEncodedValue(env, target, env->jwk_d_string(), d).IsNothing() || 4071cb0ef41Sopenharmony_ci SetEncodedValue(env, target, env->jwk_p_string(), p).IsNothing() || 4081cb0ef41Sopenharmony_ci SetEncodedValue(env, target, env->jwk_q_string(), q).IsNothing() || 4091cb0ef41Sopenharmony_ci SetEncodedValue(env, target, env->jwk_dp_string(), dp).IsNothing() || 4101cb0ef41Sopenharmony_ci SetEncodedValue(env, target, env->jwk_dq_string(), dq).IsNothing() || 4111cb0ef41Sopenharmony_ci SetEncodedValue(env, target, env->jwk_qi_string(), qi).IsNothing()) { 4121cb0ef41Sopenharmony_ci return Nothing<bool>(); 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci } 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci return Just(true); 4171cb0ef41Sopenharmony_ci} 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_cistd::shared_ptr<KeyObjectData> ImportJWKRsaKey( 4201cb0ef41Sopenharmony_ci Environment* env, 4211cb0ef41Sopenharmony_ci Local<Object> jwk, 4221cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args, 4231cb0ef41Sopenharmony_ci unsigned int offset) { 4241cb0ef41Sopenharmony_ci Local<Value> n_value; 4251cb0ef41Sopenharmony_ci Local<Value> e_value; 4261cb0ef41Sopenharmony_ci Local<Value> d_value; 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci if (!jwk->Get(env->context(), env->jwk_n_string()).ToLocal(&n_value) || 4291cb0ef41Sopenharmony_ci !jwk->Get(env->context(), env->jwk_e_string()).ToLocal(&e_value) || 4301cb0ef41Sopenharmony_ci !jwk->Get(env->context(), env->jwk_d_string()).ToLocal(&d_value) || 4311cb0ef41Sopenharmony_ci !n_value->IsString() || 4321cb0ef41Sopenharmony_ci !e_value->IsString()) { 4331cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key"); 4341cb0ef41Sopenharmony_ci return std::shared_ptr<KeyObjectData>(); 4351cb0ef41Sopenharmony_ci } 4361cb0ef41Sopenharmony_ci 4371cb0ef41Sopenharmony_ci if (!d_value->IsUndefined() && !d_value->IsString()) { 4381cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key"); 4391cb0ef41Sopenharmony_ci return std::shared_ptr<KeyObjectData>(); 4401cb0ef41Sopenharmony_ci } 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci KeyType type = d_value->IsString() ? kKeyTypePrivate : kKeyTypePublic; 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_ci RsaPointer rsa(RSA_new()); 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci ByteSource n = ByteSource::FromEncodedString(env, n_value.As<String>()); 4471cb0ef41Sopenharmony_ci ByteSource e = ByteSource::FromEncodedString(env, e_value.As<String>()); 4481cb0ef41Sopenharmony_ci 4491cb0ef41Sopenharmony_ci if (!RSA_set0_key( 4501cb0ef41Sopenharmony_ci rsa.get(), 4511cb0ef41Sopenharmony_ci n.ToBN().release(), 4521cb0ef41Sopenharmony_ci e.ToBN().release(), 4531cb0ef41Sopenharmony_ci nullptr)) { 4541cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key"); 4551cb0ef41Sopenharmony_ci return std::shared_ptr<KeyObjectData>(); 4561cb0ef41Sopenharmony_ci } 4571cb0ef41Sopenharmony_ci 4581cb0ef41Sopenharmony_ci if (type == kKeyTypePrivate) { 4591cb0ef41Sopenharmony_ci Local<Value> p_value; 4601cb0ef41Sopenharmony_ci Local<Value> q_value; 4611cb0ef41Sopenharmony_ci Local<Value> dp_value; 4621cb0ef41Sopenharmony_ci Local<Value> dq_value; 4631cb0ef41Sopenharmony_ci Local<Value> qi_value; 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_ci if (!jwk->Get(env->context(), env->jwk_p_string()).ToLocal(&p_value) || 4661cb0ef41Sopenharmony_ci !jwk->Get(env->context(), env->jwk_q_string()).ToLocal(&q_value) || 4671cb0ef41Sopenharmony_ci !jwk->Get(env->context(), env->jwk_dp_string()).ToLocal(&dp_value) || 4681cb0ef41Sopenharmony_ci !jwk->Get(env->context(), env->jwk_dq_string()).ToLocal(&dq_value) || 4691cb0ef41Sopenharmony_ci !jwk->Get(env->context(), env->jwk_qi_string()).ToLocal(&qi_value)) { 4701cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key"); 4711cb0ef41Sopenharmony_ci return std::shared_ptr<KeyObjectData>(); 4721cb0ef41Sopenharmony_ci } 4731cb0ef41Sopenharmony_ci 4741cb0ef41Sopenharmony_ci if (!p_value->IsString() || 4751cb0ef41Sopenharmony_ci !q_value->IsString() || 4761cb0ef41Sopenharmony_ci !dp_value->IsString() || 4771cb0ef41Sopenharmony_ci !dq_value->IsString() || 4781cb0ef41Sopenharmony_ci !qi_value->IsString()) { 4791cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key"); 4801cb0ef41Sopenharmony_ci return std::shared_ptr<KeyObjectData>(); 4811cb0ef41Sopenharmony_ci } 4821cb0ef41Sopenharmony_ci 4831cb0ef41Sopenharmony_ci ByteSource d = ByteSource::FromEncodedString(env, d_value.As<String>()); 4841cb0ef41Sopenharmony_ci ByteSource q = ByteSource::FromEncodedString(env, q_value.As<String>()); 4851cb0ef41Sopenharmony_ci ByteSource p = ByteSource::FromEncodedString(env, p_value.As<String>()); 4861cb0ef41Sopenharmony_ci ByteSource dp = ByteSource::FromEncodedString(env, dp_value.As<String>()); 4871cb0ef41Sopenharmony_ci ByteSource dq = ByteSource::FromEncodedString(env, dq_value.As<String>()); 4881cb0ef41Sopenharmony_ci ByteSource qi = ByteSource::FromEncodedString(env, qi_value.As<String>()); 4891cb0ef41Sopenharmony_ci 4901cb0ef41Sopenharmony_ci if (!RSA_set0_key(rsa.get(), nullptr, nullptr, d.ToBN().release()) || 4911cb0ef41Sopenharmony_ci !RSA_set0_factors(rsa.get(), p.ToBN().release(), q.ToBN().release()) || 4921cb0ef41Sopenharmony_ci !RSA_set0_crt_params( 4931cb0ef41Sopenharmony_ci rsa.get(), 4941cb0ef41Sopenharmony_ci dp.ToBN().release(), 4951cb0ef41Sopenharmony_ci dq.ToBN().release(), 4961cb0ef41Sopenharmony_ci qi.ToBN().release())) { 4971cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key"); 4981cb0ef41Sopenharmony_ci return std::shared_ptr<KeyObjectData>(); 4991cb0ef41Sopenharmony_ci } 5001cb0ef41Sopenharmony_ci } 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ci EVPKeyPointer pkey(EVP_PKEY_new()); 5031cb0ef41Sopenharmony_ci CHECK_EQ(EVP_PKEY_set1_RSA(pkey.get(), rsa.get()), 1); 5041cb0ef41Sopenharmony_ci 5051cb0ef41Sopenharmony_ci return KeyObjectData::CreateAsymmetric(type, ManagedEVPPKey(std::move(pkey))); 5061cb0ef41Sopenharmony_ci} 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_ciMaybe<bool> GetRsaKeyDetail( 5091cb0ef41Sopenharmony_ci Environment* env, 5101cb0ef41Sopenharmony_ci std::shared_ptr<KeyObjectData> key, 5111cb0ef41Sopenharmony_ci Local<Object> target) { 5121cb0ef41Sopenharmony_ci const BIGNUM* e; // Public Exponent 5131cb0ef41Sopenharmony_ci const BIGNUM* n; // Modulus 5141cb0ef41Sopenharmony_ci 5151cb0ef41Sopenharmony_ci ManagedEVPPKey m_pkey = key->GetAsymmetricKey(); 5161cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(*m_pkey.mutex()); 5171cb0ef41Sopenharmony_ci int type = EVP_PKEY_id(m_pkey.get()); 5181cb0ef41Sopenharmony_ci CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS); 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ci // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL 5211cb0ef41Sopenharmony_ci // versions older than 1.1.1e via FIPS / dynamic linking. 5221cb0ef41Sopenharmony_ci const RSA* rsa; 5231cb0ef41Sopenharmony_ci if (OpenSSL_version_num() >= 0x1010105fL) { 5241cb0ef41Sopenharmony_ci rsa = EVP_PKEY_get0_RSA(m_pkey.get()); 5251cb0ef41Sopenharmony_ci } else { 5261cb0ef41Sopenharmony_ci rsa = static_cast<const RSA*>(EVP_PKEY_get0(m_pkey.get())); 5271cb0ef41Sopenharmony_ci } 5281cb0ef41Sopenharmony_ci CHECK_NOT_NULL(rsa); 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_ci RSA_get0_key(rsa, &n, &e, nullptr); 5311cb0ef41Sopenharmony_ci 5321cb0ef41Sopenharmony_ci size_t modulus_length = BN_num_bits(n); 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci if (target 5351cb0ef41Sopenharmony_ci ->Set( 5361cb0ef41Sopenharmony_ci env->context(), 5371cb0ef41Sopenharmony_ci env->modulus_length_string(), 5381cb0ef41Sopenharmony_ci Number::New(env->isolate(), static_cast<double>(modulus_length))) 5391cb0ef41Sopenharmony_ci .IsNothing()) { 5401cb0ef41Sopenharmony_ci return Nothing<bool>(); 5411cb0ef41Sopenharmony_ci } 5421cb0ef41Sopenharmony_ci 5431cb0ef41Sopenharmony_ci std::unique_ptr<BackingStore> public_exponent; 5441cb0ef41Sopenharmony_ci { 5451cb0ef41Sopenharmony_ci NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); 5461cb0ef41Sopenharmony_ci public_exponent = 5471cb0ef41Sopenharmony_ci ArrayBuffer::NewBackingStore(env->isolate(), BN_num_bytes(e)); 5481cb0ef41Sopenharmony_ci } 5491cb0ef41Sopenharmony_ci CHECK_EQ(BN_bn2binpad(e, 5501cb0ef41Sopenharmony_ci static_cast<unsigned char*>(public_exponent->Data()), 5511cb0ef41Sopenharmony_ci public_exponent->ByteLength()), 5521cb0ef41Sopenharmony_ci static_cast<int>(public_exponent->ByteLength())); 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_ci if (target 5551cb0ef41Sopenharmony_ci ->Set(env->context(), 5561cb0ef41Sopenharmony_ci env->public_exponent_string(), 5571cb0ef41Sopenharmony_ci ArrayBuffer::New(env->isolate(), std::move(public_exponent))) 5581cb0ef41Sopenharmony_ci .IsNothing()) { 5591cb0ef41Sopenharmony_ci return Nothing<bool>(); 5601cb0ef41Sopenharmony_ci } 5611cb0ef41Sopenharmony_ci 5621cb0ef41Sopenharmony_ci if (type == EVP_PKEY_RSA_PSS) { 5631cb0ef41Sopenharmony_ci // Due to the way ASN.1 encoding works, default values are omitted when 5641cb0ef41Sopenharmony_ci // encoding the data structure. However, there are also RSA-PSS keys for 5651cb0ef41Sopenharmony_ci // which no parameters are set. In that case, the ASN.1 RSASSA-PSS-params 5661cb0ef41Sopenharmony_ci // sequence will be missing entirely and RSA_get0_pss_params will return 5671cb0ef41Sopenharmony_ci // nullptr. If parameters are present but all parameters are set to their 5681cb0ef41Sopenharmony_ci // default values, an empty sequence will be stored in the ASN.1 structure. 5691cb0ef41Sopenharmony_ci // In that case, RSA_get0_pss_params does not return nullptr but all fields 5701cb0ef41Sopenharmony_ci // of the returned RSA_PSS_PARAMS will be set to nullptr. 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_ci const RSA_PSS_PARAMS* params = RSA_get0_pss_params(rsa); 5731cb0ef41Sopenharmony_ci if (params != nullptr) { 5741cb0ef41Sopenharmony_ci int hash_nid = NID_sha1; 5751cb0ef41Sopenharmony_ci int mgf_nid = NID_mgf1; 5761cb0ef41Sopenharmony_ci int mgf1_hash_nid = NID_sha1; 5771cb0ef41Sopenharmony_ci int64_t salt_length = 20; 5781cb0ef41Sopenharmony_ci 5791cb0ef41Sopenharmony_ci if (params->hashAlgorithm != nullptr) { 5801cb0ef41Sopenharmony_ci hash_nid = OBJ_obj2nid(params->hashAlgorithm->algorithm); 5811cb0ef41Sopenharmony_ci } 5821cb0ef41Sopenharmony_ci 5831cb0ef41Sopenharmony_ci if (target 5841cb0ef41Sopenharmony_ci ->Set( 5851cb0ef41Sopenharmony_ci env->context(), 5861cb0ef41Sopenharmony_ci env->hash_algorithm_string(), 5871cb0ef41Sopenharmony_ci OneByteString(env->isolate(), OBJ_nid2ln(hash_nid))) 5881cb0ef41Sopenharmony_ci .IsNothing()) { 5891cb0ef41Sopenharmony_ci return Nothing<bool>(); 5901cb0ef41Sopenharmony_ci } 5911cb0ef41Sopenharmony_ci 5921cb0ef41Sopenharmony_ci if (params->maskGenAlgorithm != nullptr) { 5931cb0ef41Sopenharmony_ci mgf_nid = OBJ_obj2nid(params->maskGenAlgorithm->algorithm); 5941cb0ef41Sopenharmony_ci if (mgf_nid == NID_mgf1) { 5951cb0ef41Sopenharmony_ci mgf1_hash_nid = OBJ_obj2nid(params->maskHash->algorithm); 5961cb0ef41Sopenharmony_ci } 5971cb0ef41Sopenharmony_ci } 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci // If, for some reason, the MGF is not MGF1, then the MGF1 hash function 6001cb0ef41Sopenharmony_ci // is intentionally not added to the object. 6011cb0ef41Sopenharmony_ci if (mgf_nid == NID_mgf1) { 6021cb0ef41Sopenharmony_ci if (target 6031cb0ef41Sopenharmony_ci ->Set( 6041cb0ef41Sopenharmony_ci env->context(), 6051cb0ef41Sopenharmony_ci env->mgf1_hash_algorithm_string(), 6061cb0ef41Sopenharmony_ci OneByteString(env->isolate(), OBJ_nid2ln(mgf1_hash_nid))) 6071cb0ef41Sopenharmony_ci .IsNothing()) { 6081cb0ef41Sopenharmony_ci return Nothing<bool>(); 6091cb0ef41Sopenharmony_ci } 6101cb0ef41Sopenharmony_ci } 6111cb0ef41Sopenharmony_ci 6121cb0ef41Sopenharmony_ci if (params->saltLength != nullptr) { 6131cb0ef41Sopenharmony_ci if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) { 6141cb0ef41Sopenharmony_ci ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error"); 6151cb0ef41Sopenharmony_ci return Nothing<bool>(); 6161cb0ef41Sopenharmony_ci } 6171cb0ef41Sopenharmony_ci } 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_ci if (target 6201cb0ef41Sopenharmony_ci ->Set( 6211cb0ef41Sopenharmony_ci env->context(), 6221cb0ef41Sopenharmony_ci env->salt_length_string(), 6231cb0ef41Sopenharmony_ci Number::New(env->isolate(), static_cast<double>(salt_length))) 6241cb0ef41Sopenharmony_ci .IsNothing()) { 6251cb0ef41Sopenharmony_ci return Nothing<bool>(); 6261cb0ef41Sopenharmony_ci } 6271cb0ef41Sopenharmony_ci } 6281cb0ef41Sopenharmony_ci } 6291cb0ef41Sopenharmony_ci 6301cb0ef41Sopenharmony_ci return Just<bool>(true); 6311cb0ef41Sopenharmony_ci} 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_cinamespace RSAAlg { 6341cb0ef41Sopenharmony_civoid Initialize(Environment* env, Local<Object> target) { 6351cb0ef41Sopenharmony_ci RSAKeyPairGenJob::Initialize(env, target); 6361cb0ef41Sopenharmony_ci RSAKeyExportJob::Initialize(env, target); 6371cb0ef41Sopenharmony_ci RSACipherJob::Initialize(env, target); 6381cb0ef41Sopenharmony_ci 6391cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_SSA_PKCS1_v1_5); 6401cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_PSS); 6411cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_OAEP); 6421cb0ef41Sopenharmony_ci} 6431cb0ef41Sopenharmony_ci 6441cb0ef41Sopenharmony_civoid RegisterExternalReferences(ExternalReferenceRegistry* registry) { 6451cb0ef41Sopenharmony_ci RSAKeyPairGenJob::RegisterExternalReferences(registry); 6461cb0ef41Sopenharmony_ci RSAKeyExportJob::RegisterExternalReferences(registry); 6471cb0ef41Sopenharmony_ci RSACipherJob::RegisterExternalReferences(registry); 6481cb0ef41Sopenharmony_ci} 6491cb0ef41Sopenharmony_ci} // namespace RSAAlg 6501cb0ef41Sopenharmony_ci} // namespace crypto 6511cb0ef41Sopenharmony_ci} // namespace node 652