11cb0ef41Sopenharmony_ci#include "crypto/crypto_sig.h" 21cb0ef41Sopenharmony_ci#include "async_wrap-inl.h" 31cb0ef41Sopenharmony_ci#include "base_object-inl.h" 41cb0ef41Sopenharmony_ci#include "crypto/crypto_ec.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_cinamespace node { 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciusing v8::ArrayBuffer; 151cb0ef41Sopenharmony_ciusing v8::BackingStore; 161cb0ef41Sopenharmony_ciusing v8::Boolean; 171cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo; 181cb0ef41Sopenharmony_ciusing v8::FunctionTemplate; 191cb0ef41Sopenharmony_ciusing v8::HandleScope; 201cb0ef41Sopenharmony_ciusing v8::Int32; 211cb0ef41Sopenharmony_ciusing v8::Isolate; 221cb0ef41Sopenharmony_ciusing v8::Just; 231cb0ef41Sopenharmony_ciusing v8::Local; 241cb0ef41Sopenharmony_ciusing v8::Maybe; 251cb0ef41Sopenharmony_ciusing v8::Nothing; 261cb0ef41Sopenharmony_ciusing v8::Object; 271cb0ef41Sopenharmony_ciusing v8::Uint32; 281cb0ef41Sopenharmony_ciusing v8::Value; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_cinamespace crypto { 311cb0ef41Sopenharmony_cinamespace { 321cb0ef41Sopenharmony_cibool ValidateDSAParameters(EVP_PKEY* key) { 331cb0ef41Sopenharmony_ci /* Validate DSA2 parameters from FIPS 186-4 */ 341cb0ef41Sopenharmony_ci#if OPENSSL_VERSION_MAJOR >= 3 351cb0ef41Sopenharmony_ci if (EVP_default_properties_is_fips_enabled(nullptr) && 361cb0ef41Sopenharmony_ci EVP_PKEY_DSA == EVP_PKEY_base_id(key)) { 371cb0ef41Sopenharmony_ci#else 381cb0ef41Sopenharmony_ci if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) { 391cb0ef41Sopenharmony_ci#endif 401cb0ef41Sopenharmony_ci const DSA* dsa = EVP_PKEY_get0_DSA(key); 411cb0ef41Sopenharmony_ci const BIGNUM* p; 421cb0ef41Sopenharmony_ci DSA_get0_pqg(dsa, &p, nullptr, nullptr); 431cb0ef41Sopenharmony_ci size_t L = BN_num_bits(p); 441cb0ef41Sopenharmony_ci const BIGNUM* q; 451cb0ef41Sopenharmony_ci DSA_get0_pqg(dsa, nullptr, &q, nullptr); 461cb0ef41Sopenharmony_ci size_t N = BN_num_bits(q); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci return (L == 1024 && N == 160) || 491cb0ef41Sopenharmony_ci (L == 2048 && N == 224) || 501cb0ef41Sopenharmony_ci (L == 2048 && N == 256) || 511cb0ef41Sopenharmony_ci (L == 3072 && N == 256); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci return true; 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_cibool ApplyRSAOptions(const ManagedEVPPKey& pkey, 581cb0ef41Sopenharmony_ci EVP_PKEY_CTX* pkctx, 591cb0ef41Sopenharmony_ci int padding, 601cb0ef41Sopenharmony_ci const Maybe<int>& salt_len) { 611cb0ef41Sopenharmony_ci if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA || 621cb0ef41Sopenharmony_ci EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 || 631cb0ef41Sopenharmony_ci EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) { 641cb0ef41Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0) 651cb0ef41Sopenharmony_ci return false; 661cb0ef41Sopenharmony_ci if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) { 671cb0ef41Sopenharmony_ci if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0) 681cb0ef41Sopenharmony_ci return false; 691cb0ef41Sopenharmony_ci } 701cb0ef41Sopenharmony_ci } 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci return true; 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_cistd::unique_ptr<BackingStore> Node_SignFinal(Environment* env, 761cb0ef41Sopenharmony_ci EVPMDPointer&& mdctx, 771cb0ef41Sopenharmony_ci const ManagedEVPPKey& pkey, 781cb0ef41Sopenharmony_ci int padding, 791cb0ef41Sopenharmony_ci Maybe<int> pss_salt_len) { 801cb0ef41Sopenharmony_ci unsigned char m[EVP_MAX_MD_SIZE]; 811cb0ef41Sopenharmony_ci unsigned int m_len; 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len)) 841cb0ef41Sopenharmony_ci return nullptr; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci int signed_sig_len = EVP_PKEY_size(pkey.get()); 871cb0ef41Sopenharmony_ci CHECK_GE(signed_sig_len, 0); 881cb0ef41Sopenharmony_ci size_t sig_len = static_cast<size_t>(signed_sig_len); 891cb0ef41Sopenharmony_ci std::unique_ptr<BackingStore> sig; 901cb0ef41Sopenharmony_ci { 911cb0ef41Sopenharmony_ci NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); 921cb0ef41Sopenharmony_ci sig = ArrayBuffer::NewBackingStore(env->isolate(), sig_len); 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); 951cb0ef41Sopenharmony_ci if (pkctx && 961cb0ef41Sopenharmony_ci EVP_PKEY_sign_init(pkctx.get()) && 971cb0ef41Sopenharmony_ci ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) && 981cb0ef41Sopenharmony_ci EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) && 991cb0ef41Sopenharmony_ci EVP_PKEY_sign(pkctx.get(), static_cast<unsigned char*>(sig->Data()), 1001cb0ef41Sopenharmony_ci &sig_len, m, m_len)) { 1011cb0ef41Sopenharmony_ci CHECK_LE(sig_len, sig->ByteLength()); 1021cb0ef41Sopenharmony_ci if (sig_len == 0) 1031cb0ef41Sopenharmony_ci sig = ArrayBuffer::NewBackingStore(env->isolate(), 0); 1041cb0ef41Sopenharmony_ci else 1051cb0ef41Sopenharmony_ci sig = BackingStore::Reallocate(env->isolate(), std::move(sig), sig_len); 1061cb0ef41Sopenharmony_ci return sig; 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci return nullptr; 1101cb0ef41Sopenharmony_ci} 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ciint GetDefaultSignPadding(const ManagedEVPPKey& m_pkey) { 1131cb0ef41Sopenharmony_ci return EVP_PKEY_id(m_pkey.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING : 1141cb0ef41Sopenharmony_ci RSA_PKCS1_PADDING; 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ciunsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) { 1181cb0ef41Sopenharmony_ci int bits, base_id = EVP_PKEY_base_id(pkey.get()); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci if (base_id == EVP_PKEY_DSA) { 1211cb0ef41Sopenharmony_ci const DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get()); 1221cb0ef41Sopenharmony_ci // Both r and s are computed mod q, so their width is limited by that of q. 1231cb0ef41Sopenharmony_ci bits = BN_num_bits(DSA_get0_q(dsa_key)); 1241cb0ef41Sopenharmony_ci } else if (base_id == EVP_PKEY_EC) { 1251cb0ef41Sopenharmony_ci const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get()); 1261cb0ef41Sopenharmony_ci const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key); 1271cb0ef41Sopenharmony_ci bits = EC_GROUP_order_bits(ec_group); 1281cb0ef41Sopenharmony_ci } else { 1291cb0ef41Sopenharmony_ci return kNoDsaSignature; 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci return (bits + 7) / 8; 1331cb0ef41Sopenharmony_ci} 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_cibool ExtractP1363( 1361cb0ef41Sopenharmony_ci const unsigned char* sig_data, 1371cb0ef41Sopenharmony_ci unsigned char* out, 1381cb0ef41Sopenharmony_ci size_t len, 1391cb0ef41Sopenharmony_ci size_t n) { 1401cb0ef41Sopenharmony_ci ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len)); 1411cb0ef41Sopenharmony_ci if (!asn1_sig) 1421cb0ef41Sopenharmony_ci return false; 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci const BIGNUM* pr = ECDSA_SIG_get0_r(asn1_sig.get()); 1451cb0ef41Sopenharmony_ci const BIGNUM* ps = ECDSA_SIG_get0_s(asn1_sig.get()); 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci return BN_bn2binpad(pr, out, n) > 0 && BN_bn2binpad(ps, out + n, n) > 0; 1481cb0ef41Sopenharmony_ci} 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci// Returns the maximum size of each of the integers (r, s) of the DSA signature. 1511cb0ef41Sopenharmony_cistd::unique_ptr<BackingStore> ConvertSignatureToP1363(Environment* env, 1521cb0ef41Sopenharmony_ci const ManagedEVPPKey& pkey, std::unique_ptr<BackingStore>&& signature) { 1531cb0ef41Sopenharmony_ci unsigned int n = GetBytesOfRS(pkey); 1541cb0ef41Sopenharmony_ci if (n == kNoDsaSignature) 1551cb0ef41Sopenharmony_ci return std::move(signature); 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci std::unique_ptr<BackingStore> buf; 1581cb0ef41Sopenharmony_ci { 1591cb0ef41Sopenharmony_ci NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); 1601cb0ef41Sopenharmony_ci buf = ArrayBuffer::NewBackingStore(env->isolate(), 2 * n); 1611cb0ef41Sopenharmony_ci } 1621cb0ef41Sopenharmony_ci if (!ExtractP1363(static_cast<unsigned char*>(signature->Data()), 1631cb0ef41Sopenharmony_ci static_cast<unsigned char*>(buf->Data()), 1641cb0ef41Sopenharmony_ci signature->ByteLength(), n)) 1651cb0ef41Sopenharmony_ci return std::move(signature); 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci return buf; 1681cb0ef41Sopenharmony_ci} 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci// Returns the maximum size of each of the integers (r, s) of the DSA signature. 1711cb0ef41Sopenharmony_ciByteSource ConvertSignatureToP1363( 1721cb0ef41Sopenharmony_ci Environment* env, 1731cb0ef41Sopenharmony_ci const ManagedEVPPKey& pkey, 1741cb0ef41Sopenharmony_ci const ByteSource& signature) { 1751cb0ef41Sopenharmony_ci unsigned int n = GetBytesOfRS(pkey); 1761cb0ef41Sopenharmony_ci if (n == kNoDsaSignature) 1771cb0ef41Sopenharmony_ci return ByteSource(); 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci const unsigned char* sig_data = signature.data<unsigned char>(); 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci ByteSource::Builder out(n * 2); 1821cb0ef41Sopenharmony_ci memset(out.data<void>(), 0, n * 2); 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci if (!ExtractP1363(sig_data, out.data<unsigned char>(), signature.size(), n)) 1851cb0ef41Sopenharmony_ci return ByteSource(); 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci return std::move(out).release(); 1881cb0ef41Sopenharmony_ci} 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ciByteSource ConvertSignatureToDER( 1911cb0ef41Sopenharmony_ci const ManagedEVPPKey& pkey, 1921cb0ef41Sopenharmony_ci ByteSource&& out) { 1931cb0ef41Sopenharmony_ci unsigned int n = GetBytesOfRS(pkey); 1941cb0ef41Sopenharmony_ci if (n == kNoDsaSignature) 1951cb0ef41Sopenharmony_ci return std::move(out); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci const unsigned char* sig_data = out.data<unsigned char>(); 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci if (out.size() != 2 * n) 2001cb0ef41Sopenharmony_ci return ByteSource(); 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci ECDSASigPointer asn1_sig(ECDSA_SIG_new()); 2031cb0ef41Sopenharmony_ci CHECK(asn1_sig); 2041cb0ef41Sopenharmony_ci BIGNUM* r = BN_new(); 2051cb0ef41Sopenharmony_ci CHECK_NOT_NULL(r); 2061cb0ef41Sopenharmony_ci BIGNUM* s = BN_new(); 2071cb0ef41Sopenharmony_ci CHECK_NOT_NULL(s); 2081cb0ef41Sopenharmony_ci CHECK_EQ(r, BN_bin2bn(sig_data, n, r)); 2091cb0ef41Sopenharmony_ci CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s)); 2101cb0ef41Sopenharmony_ci CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s)); 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci unsigned char* data = nullptr; 2131cb0ef41Sopenharmony_ci int len = i2d_ECDSA_SIG(asn1_sig.get(), &data); 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci if (len <= 0) 2161cb0ef41Sopenharmony_ci return ByteSource(); 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci CHECK_NOT_NULL(data); 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci return ByteSource::Allocated(data, len); 2211cb0ef41Sopenharmony_ci} 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_civoid CheckThrow(Environment* env, SignBase::Error error) { 2241cb0ef41Sopenharmony_ci HandleScope scope(env->isolate()); 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci switch (error) { 2271cb0ef41Sopenharmony_ci case SignBase::Error::kSignUnknownDigest: 2281cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_INVALID_DIGEST(env); 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci case SignBase::Error::kSignNotInitialised: 2311cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_INVALID_STATE(env, "Not initialised"); 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci case SignBase::Error::kSignMalformedSignature: 2341cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Malformed signature"); 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci case SignBase::Error::kSignInit: 2371cb0ef41Sopenharmony_ci case SignBase::Error::kSignUpdate: 2381cb0ef41Sopenharmony_ci case SignBase::Error::kSignPrivateKey: 2391cb0ef41Sopenharmony_ci case SignBase::Error::kSignPublicKey: 2401cb0ef41Sopenharmony_ci { 2411cb0ef41Sopenharmony_ci unsigned long err = ERR_get_error(); // NOLINT(runtime/int) 2421cb0ef41Sopenharmony_ci if (err) 2431cb0ef41Sopenharmony_ci return ThrowCryptoError(env, err); 2441cb0ef41Sopenharmony_ci switch (error) { 2451cb0ef41Sopenharmony_ci case SignBase::Error::kSignInit: 2461cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 2471cb0ef41Sopenharmony_ci "EVP_SignInit_ex failed"); 2481cb0ef41Sopenharmony_ci case SignBase::Error::kSignUpdate: 2491cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 2501cb0ef41Sopenharmony_ci "EVP_SignUpdate failed"); 2511cb0ef41Sopenharmony_ci case SignBase::Error::kSignPrivateKey: 2521cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 2531cb0ef41Sopenharmony_ci "PEM_read_bio_PrivateKey failed"); 2541cb0ef41Sopenharmony_ci case SignBase::Error::kSignPublicKey: 2551cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 2561cb0ef41Sopenharmony_ci "PEM_read_bio_PUBKEY failed"); 2571cb0ef41Sopenharmony_ci default: 2581cb0ef41Sopenharmony_ci ABORT(); 2591cb0ef41Sopenharmony_ci } 2601cb0ef41Sopenharmony_ci } 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci case SignBase::Error::kSignOk: 2631cb0ef41Sopenharmony_ci return; 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci} 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_cibool IsOneShot(const ManagedEVPPKey& key) { 2681cb0ef41Sopenharmony_ci switch (EVP_PKEY_id(key.get())) { 2691cb0ef41Sopenharmony_ci case EVP_PKEY_ED25519: 2701cb0ef41Sopenharmony_ci case EVP_PKEY_ED448: 2711cb0ef41Sopenharmony_ci return true; 2721cb0ef41Sopenharmony_ci default: 2731cb0ef41Sopenharmony_ci return false; 2741cb0ef41Sopenharmony_ci } 2751cb0ef41Sopenharmony_ci} 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_cibool UseP1363Encoding(const ManagedEVPPKey& key, 2781cb0ef41Sopenharmony_ci const DSASigEnc& dsa_encoding) { 2791cb0ef41Sopenharmony_ci switch (EVP_PKEY_id(key.get())) { 2801cb0ef41Sopenharmony_ci case EVP_PKEY_EC: 2811cb0ef41Sopenharmony_ci case EVP_PKEY_DSA: 2821cb0ef41Sopenharmony_ci return dsa_encoding == kSigEncP1363; 2831cb0ef41Sopenharmony_ci default: 2841cb0ef41Sopenharmony_ci return false; 2851cb0ef41Sopenharmony_ci } 2861cb0ef41Sopenharmony_ci} 2871cb0ef41Sopenharmony_ci} // namespace 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ciSignBase::Error SignBase::Init(const char* sign_type) { 2901cb0ef41Sopenharmony_ci CHECK_NULL(mdctx_); 2911cb0ef41Sopenharmony_ci // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1 2921cb0ef41Sopenharmony_ci // exposed through the public API. 2931cb0ef41Sopenharmony_ci if (strcmp(sign_type, "dss1") == 0 || 2941cb0ef41Sopenharmony_ci strcmp(sign_type, "DSS1") == 0) { 2951cb0ef41Sopenharmony_ci sign_type = "SHA1"; 2961cb0ef41Sopenharmony_ci } 2971cb0ef41Sopenharmony_ci const EVP_MD* md = EVP_get_digestbyname(sign_type); 2981cb0ef41Sopenharmony_ci if (md == nullptr) 2991cb0ef41Sopenharmony_ci return kSignUnknownDigest; 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ci mdctx_.reset(EVP_MD_CTX_new()); 3021cb0ef41Sopenharmony_ci if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) { 3031cb0ef41Sopenharmony_ci mdctx_.reset(); 3041cb0ef41Sopenharmony_ci return kSignInit; 3051cb0ef41Sopenharmony_ci } 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_ci return kSignOk; 3081cb0ef41Sopenharmony_ci} 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ciSignBase::Error SignBase::Update(const char* data, size_t len) { 3111cb0ef41Sopenharmony_ci if (mdctx_ == nullptr) 3121cb0ef41Sopenharmony_ci return kSignNotInitialised; 3131cb0ef41Sopenharmony_ci if (!EVP_DigestUpdate(mdctx_.get(), data, len)) 3141cb0ef41Sopenharmony_ci return kSignUpdate; 3151cb0ef41Sopenharmony_ci return kSignOk; 3161cb0ef41Sopenharmony_ci} 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ciSignBase::SignBase(Environment* env, Local<Object> wrap) 3191cb0ef41Sopenharmony_ci : BaseObject(env, wrap) {} 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_civoid SignBase::MemoryInfo(MemoryTracker* tracker) const { 3221cb0ef41Sopenharmony_ci tracker->TrackFieldWithSize("mdctx", mdctx_ ? kSizeOf_EVP_MD_CTX : 0); 3231cb0ef41Sopenharmony_ci} 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ciSign::Sign(Environment* env, Local<Object> wrap) : SignBase(env, wrap) { 3261cb0ef41Sopenharmony_ci MakeWeak(); 3271cb0ef41Sopenharmony_ci} 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_civoid Sign::Initialize(Environment* env, Local<Object> target) { 3301cb0ef41Sopenharmony_ci Isolate* isolate = env->isolate(); 3311cb0ef41Sopenharmony_ci Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New); 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_ci t->InstanceTemplate()->SetInternalFieldCount( 3341cb0ef41Sopenharmony_ci SignBase::kInternalFieldCount); 3351cb0ef41Sopenharmony_ci t->Inherit(BaseObject::GetConstructorTemplate(env)); 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_ci SetProtoMethod(isolate, t, "init", SignInit); 3381cb0ef41Sopenharmony_ci SetProtoMethod(isolate, t, "update", SignUpdate); 3391cb0ef41Sopenharmony_ci SetProtoMethod(isolate, t, "sign", SignFinal); 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_ci SetConstructorFunction(env->context(), target, "Sign", t); 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci SignJob::Initialize(env, target); 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci constexpr int kSignJobModeSign = SignConfiguration::kSign; 3461cb0ef41Sopenharmony_ci constexpr int kSignJobModeVerify = SignConfiguration::kVerify; 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, kSignJobModeSign); 3491cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, kSignJobModeVerify); 3501cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, kSigEncDER); 3511cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, kSigEncP1363); 3521cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING); 3531cb0ef41Sopenharmony_ci} 3541cb0ef41Sopenharmony_ci 3551cb0ef41Sopenharmony_civoid Sign::RegisterExternalReferences(ExternalReferenceRegistry* registry) { 3561cb0ef41Sopenharmony_ci registry->Register(New); 3571cb0ef41Sopenharmony_ci registry->Register(SignInit); 3581cb0ef41Sopenharmony_ci registry->Register(SignUpdate); 3591cb0ef41Sopenharmony_ci registry->Register(SignFinal); 3601cb0ef41Sopenharmony_ci SignJob::RegisterExternalReferences(registry); 3611cb0ef41Sopenharmony_ci} 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_civoid Sign::New(const FunctionCallbackInfo<Value>& args) { 3641cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3651cb0ef41Sopenharmony_ci new Sign(env, args.This()); 3661cb0ef41Sopenharmony_ci} 3671cb0ef41Sopenharmony_ci 3681cb0ef41Sopenharmony_civoid Sign::SignInit(const FunctionCallbackInfo<Value>& args) { 3691cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3701cb0ef41Sopenharmony_ci Sign* sign; 3711cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci const node::Utf8Value sign_type(args.GetIsolate(), args[0]); 3741cb0ef41Sopenharmony_ci crypto::CheckThrow(env, sign->Init(*sign_type)); 3751cb0ef41Sopenharmony_ci} 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_civoid Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) { 3781cb0ef41Sopenharmony_ci Decode<Sign>(args, [](Sign* sign, const FunctionCallbackInfo<Value>& args, 3791cb0ef41Sopenharmony_ci const char* data, size_t size) { 3801cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3811cb0ef41Sopenharmony_ci if (UNLIKELY(size > INT_MAX)) 3821cb0ef41Sopenharmony_ci return THROW_ERR_OUT_OF_RANGE(env, "data is too long"); 3831cb0ef41Sopenharmony_ci Error err = sign->Update(data, size); 3841cb0ef41Sopenharmony_ci crypto::CheckThrow(sign->env(), err); 3851cb0ef41Sopenharmony_ci }); 3861cb0ef41Sopenharmony_ci} 3871cb0ef41Sopenharmony_ci 3881cb0ef41Sopenharmony_ciSign::SignResult Sign::SignFinal( 3891cb0ef41Sopenharmony_ci const ManagedEVPPKey& pkey, 3901cb0ef41Sopenharmony_ci int padding, 3911cb0ef41Sopenharmony_ci const Maybe<int>& salt_len, 3921cb0ef41Sopenharmony_ci DSASigEnc dsa_sig_enc) { 3931cb0ef41Sopenharmony_ci if (!mdctx_) 3941cb0ef41Sopenharmony_ci return SignResult(kSignNotInitialised); 3951cb0ef41Sopenharmony_ci 3961cb0ef41Sopenharmony_ci EVPMDPointer mdctx = std::move(mdctx_); 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci if (!ValidateDSAParameters(pkey.get())) 3991cb0ef41Sopenharmony_ci return SignResult(kSignPrivateKey); 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci std::unique_ptr<BackingStore> buffer = 4021cb0ef41Sopenharmony_ci Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len); 4031cb0ef41Sopenharmony_ci Error error = buffer ? kSignOk : kSignPrivateKey; 4041cb0ef41Sopenharmony_ci if (error == kSignOk && dsa_sig_enc == kSigEncP1363) { 4051cb0ef41Sopenharmony_ci buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer)); 4061cb0ef41Sopenharmony_ci CHECK_NOT_NULL(buffer->Data()); 4071cb0ef41Sopenharmony_ci } 4081cb0ef41Sopenharmony_ci return SignResult(error, std::move(buffer)); 4091cb0ef41Sopenharmony_ci} 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_civoid Sign::SignFinal(const FunctionCallbackInfo<Value>& args) { 4121cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 4131cb0ef41Sopenharmony_ci Sign* sign; 4141cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 4171cb0ef41Sopenharmony_ci 4181cb0ef41Sopenharmony_ci unsigned int offset = 0; 4191cb0ef41Sopenharmony_ci ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true); 4201cb0ef41Sopenharmony_ci if (!key) 4211cb0ef41Sopenharmony_ci return; 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ci int padding = GetDefaultSignPadding(key); 4241cb0ef41Sopenharmony_ci if (!args[offset]->IsUndefined()) { 4251cb0ef41Sopenharmony_ci CHECK(args[offset]->IsInt32()); 4261cb0ef41Sopenharmony_ci padding = args[offset].As<Int32>()->Value(); 4271cb0ef41Sopenharmony_ci } 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci Maybe<int> salt_len = Nothing<int>(); 4301cb0ef41Sopenharmony_ci if (!args[offset + 1]->IsUndefined()) { 4311cb0ef41Sopenharmony_ci CHECK(args[offset + 1]->IsInt32()); 4321cb0ef41Sopenharmony_ci salt_len = Just<int>(args[offset + 1].As<Int32>()->Value()); 4331cb0ef41Sopenharmony_ci } 4341cb0ef41Sopenharmony_ci 4351cb0ef41Sopenharmony_ci CHECK(args[offset + 2]->IsInt32()); 4361cb0ef41Sopenharmony_ci DSASigEnc dsa_sig_enc = 4371cb0ef41Sopenharmony_ci static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value()); 4381cb0ef41Sopenharmony_ci 4391cb0ef41Sopenharmony_ci SignResult ret = sign->SignFinal( 4401cb0ef41Sopenharmony_ci key, 4411cb0ef41Sopenharmony_ci padding, 4421cb0ef41Sopenharmony_ci salt_len, 4431cb0ef41Sopenharmony_ci dsa_sig_enc); 4441cb0ef41Sopenharmony_ci 4451cb0ef41Sopenharmony_ci if (ret.error != kSignOk) 4461cb0ef41Sopenharmony_ci return crypto::CheckThrow(env, ret.error); 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_ci Local<ArrayBuffer> ab = 4491cb0ef41Sopenharmony_ci ArrayBuffer::New(env->isolate(), std::move(ret.signature)); 4501cb0ef41Sopenharmony_ci args.GetReturnValue().Set( 4511cb0ef41Sopenharmony_ci Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>())); 4521cb0ef41Sopenharmony_ci} 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ciVerify::Verify(Environment* env, Local<Object> wrap) 4551cb0ef41Sopenharmony_ci : SignBase(env, wrap) { 4561cb0ef41Sopenharmony_ci MakeWeak(); 4571cb0ef41Sopenharmony_ci} 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_civoid Verify::Initialize(Environment* env, Local<Object> target) { 4601cb0ef41Sopenharmony_ci Isolate* isolate = env->isolate(); 4611cb0ef41Sopenharmony_ci Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New); 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci t->InstanceTemplate()->SetInternalFieldCount( 4641cb0ef41Sopenharmony_ci SignBase::kInternalFieldCount); 4651cb0ef41Sopenharmony_ci t->Inherit(BaseObject::GetConstructorTemplate(env)); 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ci SetProtoMethod(isolate, t, "init", VerifyInit); 4681cb0ef41Sopenharmony_ci SetProtoMethod(isolate, t, "update", VerifyUpdate); 4691cb0ef41Sopenharmony_ci SetProtoMethod(isolate, t, "verify", VerifyFinal); 4701cb0ef41Sopenharmony_ci 4711cb0ef41Sopenharmony_ci SetConstructorFunction(env->context(), target, "Verify", t); 4721cb0ef41Sopenharmony_ci} 4731cb0ef41Sopenharmony_ci 4741cb0ef41Sopenharmony_civoid Verify::RegisterExternalReferences(ExternalReferenceRegistry* registry) { 4751cb0ef41Sopenharmony_ci registry->Register(New); 4761cb0ef41Sopenharmony_ci registry->Register(VerifyInit); 4771cb0ef41Sopenharmony_ci registry->Register(VerifyUpdate); 4781cb0ef41Sopenharmony_ci registry->Register(VerifyFinal); 4791cb0ef41Sopenharmony_ci} 4801cb0ef41Sopenharmony_ci 4811cb0ef41Sopenharmony_civoid Verify::New(const FunctionCallbackInfo<Value>& args) { 4821cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 4831cb0ef41Sopenharmony_ci new Verify(env, args.This()); 4841cb0ef41Sopenharmony_ci} 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_civoid Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) { 4871cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 4881cb0ef41Sopenharmony_ci Verify* verify; 4891cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder()); 4901cb0ef41Sopenharmony_ci 4911cb0ef41Sopenharmony_ci const node::Utf8Value verify_type(args.GetIsolate(), args[0]); 4921cb0ef41Sopenharmony_ci crypto::CheckThrow(env, verify->Init(*verify_type)); 4931cb0ef41Sopenharmony_ci} 4941cb0ef41Sopenharmony_ci 4951cb0ef41Sopenharmony_civoid Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) { 4961cb0ef41Sopenharmony_ci Decode<Verify>(args, [](Verify* verify, 4971cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args, 4981cb0ef41Sopenharmony_ci const char* data, size_t size) { 4991cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 5001cb0ef41Sopenharmony_ci if (UNLIKELY(size > INT_MAX)) 5011cb0ef41Sopenharmony_ci return THROW_ERR_OUT_OF_RANGE(env, "data is too long"); 5021cb0ef41Sopenharmony_ci Error err = verify->Update(data, size); 5031cb0ef41Sopenharmony_ci crypto::CheckThrow(verify->env(), err); 5041cb0ef41Sopenharmony_ci }); 5051cb0ef41Sopenharmony_ci} 5061cb0ef41Sopenharmony_ci 5071cb0ef41Sopenharmony_ciSignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey, 5081cb0ef41Sopenharmony_ci const ByteSource& sig, 5091cb0ef41Sopenharmony_ci int padding, 5101cb0ef41Sopenharmony_ci const Maybe<int>& saltlen, 5111cb0ef41Sopenharmony_ci bool* verify_result) { 5121cb0ef41Sopenharmony_ci if (!mdctx_) 5131cb0ef41Sopenharmony_ci return kSignNotInitialised; 5141cb0ef41Sopenharmony_ci 5151cb0ef41Sopenharmony_ci unsigned char m[EVP_MAX_MD_SIZE]; 5161cb0ef41Sopenharmony_ci unsigned int m_len; 5171cb0ef41Sopenharmony_ci *verify_result = false; 5181cb0ef41Sopenharmony_ci EVPMDPointer mdctx = std::move(mdctx_); 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ci if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len)) 5211cb0ef41Sopenharmony_ci return kSignPublicKey; 5221cb0ef41Sopenharmony_ci 5231cb0ef41Sopenharmony_ci EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); 5241cb0ef41Sopenharmony_ci if (pkctx && 5251cb0ef41Sopenharmony_ci EVP_PKEY_verify_init(pkctx.get()) > 0 && 5261cb0ef41Sopenharmony_ci ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) && 5271cb0ef41Sopenharmony_ci EVP_PKEY_CTX_set_signature_md(pkctx.get(), 5281cb0ef41Sopenharmony_ci EVP_MD_CTX_md(mdctx.get())) > 0) { 5291cb0ef41Sopenharmony_ci const unsigned char* s = sig.data<unsigned char>(); 5301cb0ef41Sopenharmony_ci const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len); 5311cb0ef41Sopenharmony_ci *verify_result = r == 1; 5321cb0ef41Sopenharmony_ci } 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci return kSignOk; 5351cb0ef41Sopenharmony_ci} 5361cb0ef41Sopenharmony_ci 5371cb0ef41Sopenharmony_civoid Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) { 5381cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 5391cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 5401cb0ef41Sopenharmony_ci 5411cb0ef41Sopenharmony_ci Verify* verify; 5421cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder()); 5431cb0ef41Sopenharmony_ci 5441cb0ef41Sopenharmony_ci unsigned int offset = 0; 5451cb0ef41Sopenharmony_ci ManagedEVPPKey pkey = 5461cb0ef41Sopenharmony_ci ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset); 5471cb0ef41Sopenharmony_ci if (!pkey) 5481cb0ef41Sopenharmony_ci return; 5491cb0ef41Sopenharmony_ci 5501cb0ef41Sopenharmony_ci ArrayBufferOrViewContents<char> hbuf(args[offset]); 5511cb0ef41Sopenharmony_ci if (UNLIKELY(!hbuf.CheckSizeInt32())) 5521cb0ef41Sopenharmony_ci return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big"); 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_ci int padding = GetDefaultSignPadding(pkey); 5551cb0ef41Sopenharmony_ci if (!args[offset + 1]->IsUndefined()) { 5561cb0ef41Sopenharmony_ci CHECK(args[offset + 1]->IsInt32()); 5571cb0ef41Sopenharmony_ci padding = args[offset + 1].As<Int32>()->Value(); 5581cb0ef41Sopenharmony_ci } 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ci Maybe<int> salt_len = Nothing<int>(); 5611cb0ef41Sopenharmony_ci if (!args[offset + 2]->IsUndefined()) { 5621cb0ef41Sopenharmony_ci CHECK(args[offset + 2]->IsInt32()); 5631cb0ef41Sopenharmony_ci salt_len = Just<int>(args[offset + 2].As<Int32>()->Value()); 5641cb0ef41Sopenharmony_ci } 5651cb0ef41Sopenharmony_ci 5661cb0ef41Sopenharmony_ci CHECK(args[offset + 3]->IsInt32()); 5671cb0ef41Sopenharmony_ci DSASigEnc dsa_sig_enc = 5681cb0ef41Sopenharmony_ci static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value()); 5691cb0ef41Sopenharmony_ci 5701cb0ef41Sopenharmony_ci ByteSource signature = hbuf.ToByteSource(); 5711cb0ef41Sopenharmony_ci if (dsa_sig_enc == kSigEncP1363) { 5721cb0ef41Sopenharmony_ci signature = ConvertSignatureToDER(pkey, hbuf.ToByteSource()); 5731cb0ef41Sopenharmony_ci if (signature.data() == nullptr) 5741cb0ef41Sopenharmony_ci return crypto::CheckThrow(env, Error::kSignMalformedSignature); 5751cb0ef41Sopenharmony_ci } 5761cb0ef41Sopenharmony_ci 5771cb0ef41Sopenharmony_ci bool verify_result; 5781cb0ef41Sopenharmony_ci Error err = verify->VerifyFinal(pkey, signature, padding, 5791cb0ef41Sopenharmony_ci salt_len, &verify_result); 5801cb0ef41Sopenharmony_ci if (err != kSignOk) 5811cb0ef41Sopenharmony_ci return crypto::CheckThrow(env, err); 5821cb0ef41Sopenharmony_ci args.GetReturnValue().Set(verify_result); 5831cb0ef41Sopenharmony_ci} 5841cb0ef41Sopenharmony_ci 5851cb0ef41Sopenharmony_ciSignConfiguration::SignConfiguration(SignConfiguration&& other) noexcept 5861cb0ef41Sopenharmony_ci : job_mode(other.job_mode), 5871cb0ef41Sopenharmony_ci mode(other.mode), 5881cb0ef41Sopenharmony_ci key(std::move(other.key)), 5891cb0ef41Sopenharmony_ci data(std::move(other.data)), 5901cb0ef41Sopenharmony_ci signature(std::move(other.signature)), 5911cb0ef41Sopenharmony_ci digest(other.digest), 5921cb0ef41Sopenharmony_ci flags(other.flags), 5931cb0ef41Sopenharmony_ci padding(other.padding), 5941cb0ef41Sopenharmony_ci salt_length(other.salt_length), 5951cb0ef41Sopenharmony_ci dsa_encoding(other.dsa_encoding) {} 5961cb0ef41Sopenharmony_ci 5971cb0ef41Sopenharmony_ciSignConfiguration& SignConfiguration::operator=( 5981cb0ef41Sopenharmony_ci SignConfiguration&& other) noexcept { 5991cb0ef41Sopenharmony_ci if (&other == this) return *this; 6001cb0ef41Sopenharmony_ci this->~SignConfiguration(); 6011cb0ef41Sopenharmony_ci return *new (this) SignConfiguration(std::move(other)); 6021cb0ef41Sopenharmony_ci} 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_civoid SignConfiguration::MemoryInfo(MemoryTracker* tracker) const { 6051cb0ef41Sopenharmony_ci tracker->TrackField("key", key); 6061cb0ef41Sopenharmony_ci if (job_mode == kCryptoJobAsync) { 6071cb0ef41Sopenharmony_ci tracker->TrackFieldWithSize("data", data.size()); 6081cb0ef41Sopenharmony_ci tracker->TrackFieldWithSize("signature", signature.size()); 6091cb0ef41Sopenharmony_ci } 6101cb0ef41Sopenharmony_ci} 6111cb0ef41Sopenharmony_ci 6121cb0ef41Sopenharmony_ciMaybe<bool> SignTraits::AdditionalConfig( 6131cb0ef41Sopenharmony_ci CryptoJobMode mode, 6141cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args, 6151cb0ef41Sopenharmony_ci unsigned int offset, 6161cb0ef41Sopenharmony_ci SignConfiguration* params) { 6171cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 6181cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 6191cb0ef41Sopenharmony_ci 6201cb0ef41Sopenharmony_ci params->job_mode = mode; 6211cb0ef41Sopenharmony_ci 6221cb0ef41Sopenharmony_ci CHECK(args[offset]->IsUint32()); // Sign Mode 6231cb0ef41Sopenharmony_ci 6241cb0ef41Sopenharmony_ci params->mode = 6251cb0ef41Sopenharmony_ci static_cast<SignConfiguration::Mode>(args[offset].As<Uint32>()->Value()); 6261cb0ef41Sopenharmony_ci 6271cb0ef41Sopenharmony_ci ManagedEVPPKey key; 6281cb0ef41Sopenharmony_ci unsigned int keyParamOffset = offset + 1; 6291cb0ef41Sopenharmony_ci if (params->mode == SignConfiguration::kVerify) { 6301cb0ef41Sopenharmony_ci key = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &keyParamOffset); 6311cb0ef41Sopenharmony_ci } else { 6321cb0ef41Sopenharmony_ci key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &keyParamOffset, true); 6331cb0ef41Sopenharmony_ci } 6341cb0ef41Sopenharmony_ci if (!key) 6351cb0ef41Sopenharmony_ci return Nothing<bool>(); 6361cb0ef41Sopenharmony_ci params->key = key; 6371cb0ef41Sopenharmony_ci 6381cb0ef41Sopenharmony_ci ArrayBufferOrViewContents<char> data(args[offset + 5]); 6391cb0ef41Sopenharmony_ci if (UNLIKELY(!data.CheckSizeInt32())) { 6401cb0ef41Sopenharmony_ci THROW_ERR_OUT_OF_RANGE(env, "data is too big"); 6411cb0ef41Sopenharmony_ci return Nothing<bool>(); 6421cb0ef41Sopenharmony_ci } 6431cb0ef41Sopenharmony_ci params->data = mode == kCryptoJobAsync 6441cb0ef41Sopenharmony_ci ? data.ToCopy() 6451cb0ef41Sopenharmony_ci : data.ToByteSource(); 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_ci if (args[offset + 6]->IsString()) { 6481cb0ef41Sopenharmony_ci Utf8Value digest(env->isolate(), args[offset + 6]); 6491cb0ef41Sopenharmony_ci params->digest = EVP_get_digestbyname(*digest); 6501cb0ef41Sopenharmony_ci if (params->digest == nullptr) { 6511cb0ef41Sopenharmony_ci THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest); 6521cb0ef41Sopenharmony_ci return Nothing<bool>(); 6531cb0ef41Sopenharmony_ci } 6541cb0ef41Sopenharmony_ci } 6551cb0ef41Sopenharmony_ci 6561cb0ef41Sopenharmony_ci if (args[offset + 7]->IsInt32()) { // Salt length 6571cb0ef41Sopenharmony_ci params->flags |= SignConfiguration::kHasSaltLength; 6581cb0ef41Sopenharmony_ci params->salt_length = args[offset + 7].As<Int32>()->Value(); 6591cb0ef41Sopenharmony_ci } 6601cb0ef41Sopenharmony_ci if (args[offset + 8]->IsUint32()) { // Padding 6611cb0ef41Sopenharmony_ci params->flags |= SignConfiguration::kHasPadding; 6621cb0ef41Sopenharmony_ci params->padding = args[offset + 8].As<Uint32>()->Value(); 6631cb0ef41Sopenharmony_ci } 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci if (args[offset + 9]->IsUint32()) { // DSA Encoding 6661cb0ef41Sopenharmony_ci params->dsa_encoding = 6671cb0ef41Sopenharmony_ci static_cast<DSASigEnc>(args[offset + 9].As<Uint32>()->Value()); 6681cb0ef41Sopenharmony_ci if (params->dsa_encoding != kSigEncDER && 6691cb0ef41Sopenharmony_ci params->dsa_encoding != kSigEncP1363) { 6701cb0ef41Sopenharmony_ci THROW_ERR_OUT_OF_RANGE(env, "invalid signature encoding"); 6711cb0ef41Sopenharmony_ci return Nothing<bool>(); 6721cb0ef41Sopenharmony_ci } 6731cb0ef41Sopenharmony_ci } 6741cb0ef41Sopenharmony_ci 6751cb0ef41Sopenharmony_ci if (params->mode == SignConfiguration::kVerify) { 6761cb0ef41Sopenharmony_ci ArrayBufferOrViewContents<char> signature(args[offset + 10]); 6771cb0ef41Sopenharmony_ci if (UNLIKELY(!signature.CheckSizeInt32())) { 6781cb0ef41Sopenharmony_ci THROW_ERR_OUT_OF_RANGE(env, "signature is too big"); 6791cb0ef41Sopenharmony_ci return Nothing<bool>(); 6801cb0ef41Sopenharmony_ci } 6811cb0ef41Sopenharmony_ci // If this is an EC key (assuming ECDSA) we need to convert the 6821cb0ef41Sopenharmony_ci // the signature from WebCrypto format into DER format... 6831cb0ef41Sopenharmony_ci ManagedEVPPKey m_pkey = params->key; 6841cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(*m_pkey.mutex()); 6851cb0ef41Sopenharmony_ci if (UseP1363Encoding(m_pkey, params->dsa_encoding)) { 6861cb0ef41Sopenharmony_ci params->signature = 6871cb0ef41Sopenharmony_ci ConvertSignatureToDER(m_pkey, signature.ToByteSource()); 6881cb0ef41Sopenharmony_ci } else { 6891cb0ef41Sopenharmony_ci params->signature = mode == kCryptoJobAsync 6901cb0ef41Sopenharmony_ci ? signature.ToCopy() 6911cb0ef41Sopenharmony_ci : signature.ToByteSource(); 6921cb0ef41Sopenharmony_ci } 6931cb0ef41Sopenharmony_ci } 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ci return Just(true); 6961cb0ef41Sopenharmony_ci} 6971cb0ef41Sopenharmony_ci 6981cb0ef41Sopenharmony_cibool SignTraits::DeriveBits( 6991cb0ef41Sopenharmony_ci Environment* env, 7001cb0ef41Sopenharmony_ci const SignConfiguration& params, 7011cb0ef41Sopenharmony_ci ByteSource* out) { 7021cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 7031cb0ef41Sopenharmony_ci EVPMDPointer context(EVP_MD_CTX_new()); 7041cb0ef41Sopenharmony_ci EVP_PKEY_CTX* ctx = nullptr; 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_ci switch (params.mode) { 7071cb0ef41Sopenharmony_ci case SignConfiguration::kSign: 7081cb0ef41Sopenharmony_ci if (!EVP_DigestSignInit( 7091cb0ef41Sopenharmony_ci context.get(), 7101cb0ef41Sopenharmony_ci &ctx, 7111cb0ef41Sopenharmony_ci params.digest, 7121cb0ef41Sopenharmony_ci nullptr, 7131cb0ef41Sopenharmony_ci params.key.get())) { 7141cb0ef41Sopenharmony_ci crypto::CheckThrow(env, SignBase::Error::kSignInit); 7151cb0ef41Sopenharmony_ci return false; 7161cb0ef41Sopenharmony_ci } 7171cb0ef41Sopenharmony_ci break; 7181cb0ef41Sopenharmony_ci case SignConfiguration::kVerify: 7191cb0ef41Sopenharmony_ci if (!EVP_DigestVerifyInit( 7201cb0ef41Sopenharmony_ci context.get(), 7211cb0ef41Sopenharmony_ci &ctx, 7221cb0ef41Sopenharmony_ci params.digest, 7231cb0ef41Sopenharmony_ci nullptr, 7241cb0ef41Sopenharmony_ci params.key.get())) { 7251cb0ef41Sopenharmony_ci crypto::CheckThrow(env, SignBase::Error::kSignInit); 7261cb0ef41Sopenharmony_ci return false; 7271cb0ef41Sopenharmony_ci } 7281cb0ef41Sopenharmony_ci break; 7291cb0ef41Sopenharmony_ci } 7301cb0ef41Sopenharmony_ci 7311cb0ef41Sopenharmony_ci int padding = params.flags & SignConfiguration::kHasPadding 7321cb0ef41Sopenharmony_ci ? params.padding 7331cb0ef41Sopenharmony_ci : GetDefaultSignPadding(params.key); 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ci Maybe<int> salt_length = params.flags & SignConfiguration::kHasSaltLength 7361cb0ef41Sopenharmony_ci ? Just<int>(params.salt_length) : Nothing<int>(); 7371cb0ef41Sopenharmony_ci 7381cb0ef41Sopenharmony_ci if (!ApplyRSAOptions( 7391cb0ef41Sopenharmony_ci params.key, 7401cb0ef41Sopenharmony_ci ctx, 7411cb0ef41Sopenharmony_ci padding, 7421cb0ef41Sopenharmony_ci salt_length)) { 7431cb0ef41Sopenharmony_ci crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 7441cb0ef41Sopenharmony_ci return false; 7451cb0ef41Sopenharmony_ci } 7461cb0ef41Sopenharmony_ci 7471cb0ef41Sopenharmony_ci switch (params.mode) { 7481cb0ef41Sopenharmony_ci case SignConfiguration::kSign: { 7491cb0ef41Sopenharmony_ci if (IsOneShot(params.key)) { 7501cb0ef41Sopenharmony_ci size_t len; 7511cb0ef41Sopenharmony_ci if (!EVP_DigestSign( 7521cb0ef41Sopenharmony_ci context.get(), 7531cb0ef41Sopenharmony_ci nullptr, 7541cb0ef41Sopenharmony_ci &len, 7551cb0ef41Sopenharmony_ci params.data.data<unsigned char>(), 7561cb0ef41Sopenharmony_ci params.data.size())) { 7571cb0ef41Sopenharmony_ci crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 7581cb0ef41Sopenharmony_ci return false; 7591cb0ef41Sopenharmony_ci } 7601cb0ef41Sopenharmony_ci ByteSource::Builder buf(len); 7611cb0ef41Sopenharmony_ci if (!EVP_DigestSign(context.get(), 7621cb0ef41Sopenharmony_ci buf.data<unsigned char>(), 7631cb0ef41Sopenharmony_ci &len, 7641cb0ef41Sopenharmony_ci params.data.data<unsigned char>(), 7651cb0ef41Sopenharmony_ci params.data.size())) { 7661cb0ef41Sopenharmony_ci crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 7671cb0ef41Sopenharmony_ci return false; 7681cb0ef41Sopenharmony_ci } 7691cb0ef41Sopenharmony_ci *out = std::move(buf).release(len); 7701cb0ef41Sopenharmony_ci } else { 7711cb0ef41Sopenharmony_ci size_t len; 7721cb0ef41Sopenharmony_ci if (!EVP_DigestSignUpdate( 7731cb0ef41Sopenharmony_ci context.get(), 7741cb0ef41Sopenharmony_ci params.data.data<unsigned char>(), 7751cb0ef41Sopenharmony_ci params.data.size()) || 7761cb0ef41Sopenharmony_ci !EVP_DigestSignFinal(context.get(), nullptr, &len)) { 7771cb0ef41Sopenharmony_ci crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 7781cb0ef41Sopenharmony_ci return false; 7791cb0ef41Sopenharmony_ci } 7801cb0ef41Sopenharmony_ci ByteSource::Builder buf(len); 7811cb0ef41Sopenharmony_ci if (!EVP_DigestSignFinal( 7821cb0ef41Sopenharmony_ci context.get(), buf.data<unsigned char>(), &len)) { 7831cb0ef41Sopenharmony_ci crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 7841cb0ef41Sopenharmony_ci return false; 7851cb0ef41Sopenharmony_ci } 7861cb0ef41Sopenharmony_ci 7871cb0ef41Sopenharmony_ci if (UseP1363Encoding(params.key, params.dsa_encoding)) { 7881cb0ef41Sopenharmony_ci *out = ConvertSignatureToP1363( 7891cb0ef41Sopenharmony_ci env, params.key, std::move(buf).release()); 7901cb0ef41Sopenharmony_ci } else { 7911cb0ef41Sopenharmony_ci *out = std::move(buf).release(len); 7921cb0ef41Sopenharmony_ci } 7931cb0ef41Sopenharmony_ci } 7941cb0ef41Sopenharmony_ci break; 7951cb0ef41Sopenharmony_ci } 7961cb0ef41Sopenharmony_ci case SignConfiguration::kVerify: { 7971cb0ef41Sopenharmony_ci ByteSource::Builder buf(1); 7981cb0ef41Sopenharmony_ci buf.data<char>()[0] = 0; 7991cb0ef41Sopenharmony_ci if (EVP_DigestVerify( 8001cb0ef41Sopenharmony_ci context.get(), 8011cb0ef41Sopenharmony_ci params.signature.data<unsigned char>(), 8021cb0ef41Sopenharmony_ci params.signature.size(), 8031cb0ef41Sopenharmony_ci params.data.data<unsigned char>(), 8041cb0ef41Sopenharmony_ci params.data.size()) == 1) { 8051cb0ef41Sopenharmony_ci buf.data<char>()[0] = 1; 8061cb0ef41Sopenharmony_ci } 8071cb0ef41Sopenharmony_ci *out = std::move(buf).release(); 8081cb0ef41Sopenharmony_ci } 8091cb0ef41Sopenharmony_ci } 8101cb0ef41Sopenharmony_ci 8111cb0ef41Sopenharmony_ci return true; 8121cb0ef41Sopenharmony_ci} 8131cb0ef41Sopenharmony_ci 8141cb0ef41Sopenharmony_ciMaybe<bool> SignTraits::EncodeOutput( 8151cb0ef41Sopenharmony_ci Environment* env, 8161cb0ef41Sopenharmony_ci const SignConfiguration& params, 8171cb0ef41Sopenharmony_ci ByteSource* out, 8181cb0ef41Sopenharmony_ci Local<Value>* result) { 8191cb0ef41Sopenharmony_ci switch (params.mode) { 8201cb0ef41Sopenharmony_ci case SignConfiguration::kSign: 8211cb0ef41Sopenharmony_ci *result = out->ToArrayBuffer(env); 8221cb0ef41Sopenharmony_ci break; 8231cb0ef41Sopenharmony_ci case SignConfiguration::kVerify: 8241cb0ef41Sopenharmony_ci *result = Boolean::New(env->isolate(), out->data<char>()[0] == 1); 8251cb0ef41Sopenharmony_ci break; 8261cb0ef41Sopenharmony_ci default: 8271cb0ef41Sopenharmony_ci UNREACHABLE(); 8281cb0ef41Sopenharmony_ci } 8291cb0ef41Sopenharmony_ci return Just(!result->IsEmpty()); 8301cb0ef41Sopenharmony_ci} 8311cb0ef41Sopenharmony_ci 8321cb0ef41Sopenharmony_ci} // namespace crypto 8331cb0ef41Sopenharmony_ci} // namespace node 834