1#include "crypto/crypto_sig.h" 2#include "async_wrap-inl.h" 3#include "base_object-inl.h" 4#include "crypto/crypto_ec.h" 5#include "crypto/crypto_keys.h" 6#include "crypto/crypto_util.h" 7#include "env-inl.h" 8#include "memory_tracker-inl.h" 9#include "threadpoolwork-inl.h" 10#include "v8.h" 11 12namespace node { 13 14using v8::ArrayBuffer; 15using v8::BackingStore; 16using v8::Boolean; 17using v8::FunctionCallbackInfo; 18using v8::FunctionTemplate; 19using v8::HandleScope; 20using v8::Int32; 21using v8::Isolate; 22using v8::Just; 23using v8::Local; 24using v8::Maybe; 25using v8::Nothing; 26using v8::Object; 27using v8::Uint32; 28using v8::Value; 29 30namespace crypto { 31namespace { 32bool ValidateDSAParameters(EVP_PKEY* key) { 33 /* Validate DSA2 parameters from FIPS 186-4 */ 34#if OPENSSL_VERSION_MAJOR >= 3 35 if (EVP_default_properties_is_fips_enabled(nullptr) && 36 EVP_PKEY_DSA == EVP_PKEY_base_id(key)) { 37#else 38 if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key)) { 39#endif 40 const DSA* dsa = EVP_PKEY_get0_DSA(key); 41 const BIGNUM* p; 42 DSA_get0_pqg(dsa, &p, nullptr, nullptr); 43 size_t L = BN_num_bits(p); 44 const BIGNUM* q; 45 DSA_get0_pqg(dsa, nullptr, &q, nullptr); 46 size_t N = BN_num_bits(q); 47 48 return (L == 1024 && N == 160) || 49 (L == 2048 && N == 224) || 50 (L == 2048 && N == 256) || 51 (L == 3072 && N == 256); 52 } 53 54 return true; 55} 56 57bool ApplyRSAOptions(const ManagedEVPPKey& pkey, 58 EVP_PKEY_CTX* pkctx, 59 int padding, 60 const Maybe<int>& salt_len) { 61 if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA || 62 EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 || 63 EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) { 64 if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0) 65 return false; 66 if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) { 67 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len.FromJust()) <= 0) 68 return false; 69 } 70 } 71 72 return true; 73} 74 75std::unique_ptr<BackingStore> Node_SignFinal(Environment* env, 76 EVPMDPointer&& mdctx, 77 const ManagedEVPPKey& pkey, 78 int padding, 79 Maybe<int> pss_salt_len) { 80 unsigned char m[EVP_MAX_MD_SIZE]; 81 unsigned int m_len; 82 83 if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len)) 84 return nullptr; 85 86 int signed_sig_len = EVP_PKEY_size(pkey.get()); 87 CHECK_GE(signed_sig_len, 0); 88 size_t sig_len = static_cast<size_t>(signed_sig_len); 89 std::unique_ptr<BackingStore> sig; 90 { 91 NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); 92 sig = ArrayBuffer::NewBackingStore(env->isolate(), sig_len); 93 } 94 EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); 95 if (pkctx && 96 EVP_PKEY_sign_init(pkctx.get()) && 97 ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) && 98 EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) && 99 EVP_PKEY_sign(pkctx.get(), static_cast<unsigned char*>(sig->Data()), 100 &sig_len, m, m_len)) { 101 CHECK_LE(sig_len, sig->ByteLength()); 102 if (sig_len == 0) 103 sig = ArrayBuffer::NewBackingStore(env->isolate(), 0); 104 else 105 sig = BackingStore::Reallocate(env->isolate(), std::move(sig), sig_len); 106 return sig; 107 } 108 109 return nullptr; 110} 111 112int GetDefaultSignPadding(const ManagedEVPPKey& m_pkey) { 113 return EVP_PKEY_id(m_pkey.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING : 114 RSA_PKCS1_PADDING; 115} 116 117unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) { 118 int bits, base_id = EVP_PKEY_base_id(pkey.get()); 119 120 if (base_id == EVP_PKEY_DSA) { 121 const DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get()); 122 // Both r and s are computed mod q, so their width is limited by that of q. 123 bits = BN_num_bits(DSA_get0_q(dsa_key)); 124 } else if (base_id == EVP_PKEY_EC) { 125 const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get()); 126 const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key); 127 bits = EC_GROUP_order_bits(ec_group); 128 } else { 129 return kNoDsaSignature; 130 } 131 132 return (bits + 7) / 8; 133} 134 135bool ExtractP1363( 136 const unsigned char* sig_data, 137 unsigned char* out, 138 size_t len, 139 size_t n) { 140 ECDSASigPointer asn1_sig(d2i_ECDSA_SIG(nullptr, &sig_data, len)); 141 if (!asn1_sig) 142 return false; 143 144 const BIGNUM* pr = ECDSA_SIG_get0_r(asn1_sig.get()); 145 const BIGNUM* ps = ECDSA_SIG_get0_s(asn1_sig.get()); 146 147 return BN_bn2binpad(pr, out, n) > 0 && BN_bn2binpad(ps, out + n, n) > 0; 148} 149 150// Returns the maximum size of each of the integers (r, s) of the DSA signature. 151std::unique_ptr<BackingStore> ConvertSignatureToP1363(Environment* env, 152 const ManagedEVPPKey& pkey, std::unique_ptr<BackingStore>&& signature) { 153 unsigned int n = GetBytesOfRS(pkey); 154 if (n == kNoDsaSignature) 155 return std::move(signature); 156 157 std::unique_ptr<BackingStore> buf; 158 { 159 NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); 160 buf = ArrayBuffer::NewBackingStore(env->isolate(), 2 * n); 161 } 162 if (!ExtractP1363(static_cast<unsigned char*>(signature->Data()), 163 static_cast<unsigned char*>(buf->Data()), 164 signature->ByteLength(), n)) 165 return std::move(signature); 166 167 return buf; 168} 169 170// Returns the maximum size of each of the integers (r, s) of the DSA signature. 171ByteSource ConvertSignatureToP1363( 172 Environment* env, 173 const ManagedEVPPKey& pkey, 174 const ByteSource& signature) { 175 unsigned int n = GetBytesOfRS(pkey); 176 if (n == kNoDsaSignature) 177 return ByteSource(); 178 179 const unsigned char* sig_data = signature.data<unsigned char>(); 180 181 ByteSource::Builder out(n * 2); 182 memset(out.data<void>(), 0, n * 2); 183 184 if (!ExtractP1363(sig_data, out.data<unsigned char>(), signature.size(), n)) 185 return ByteSource(); 186 187 return std::move(out).release(); 188} 189 190ByteSource ConvertSignatureToDER( 191 const ManagedEVPPKey& pkey, 192 ByteSource&& out) { 193 unsigned int n = GetBytesOfRS(pkey); 194 if (n == kNoDsaSignature) 195 return std::move(out); 196 197 const unsigned char* sig_data = out.data<unsigned char>(); 198 199 if (out.size() != 2 * n) 200 return ByteSource(); 201 202 ECDSASigPointer asn1_sig(ECDSA_SIG_new()); 203 CHECK(asn1_sig); 204 BIGNUM* r = BN_new(); 205 CHECK_NOT_NULL(r); 206 BIGNUM* s = BN_new(); 207 CHECK_NOT_NULL(s); 208 CHECK_EQ(r, BN_bin2bn(sig_data, n, r)); 209 CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s)); 210 CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig.get(), r, s)); 211 212 unsigned char* data = nullptr; 213 int len = i2d_ECDSA_SIG(asn1_sig.get(), &data); 214 215 if (len <= 0) 216 return ByteSource(); 217 218 CHECK_NOT_NULL(data); 219 220 return ByteSource::Allocated(data, len); 221} 222 223void CheckThrow(Environment* env, SignBase::Error error) { 224 HandleScope scope(env->isolate()); 225 226 switch (error) { 227 case SignBase::Error::kSignUnknownDigest: 228 return THROW_ERR_CRYPTO_INVALID_DIGEST(env); 229 230 case SignBase::Error::kSignNotInitialised: 231 return THROW_ERR_CRYPTO_INVALID_STATE(env, "Not initialised"); 232 233 case SignBase::Error::kSignMalformedSignature: 234 return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Malformed signature"); 235 236 case SignBase::Error::kSignInit: 237 case SignBase::Error::kSignUpdate: 238 case SignBase::Error::kSignPrivateKey: 239 case SignBase::Error::kSignPublicKey: 240 { 241 unsigned long err = ERR_get_error(); // NOLINT(runtime/int) 242 if (err) 243 return ThrowCryptoError(env, err); 244 switch (error) { 245 case SignBase::Error::kSignInit: 246 return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 247 "EVP_SignInit_ex failed"); 248 case SignBase::Error::kSignUpdate: 249 return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 250 "EVP_SignUpdate failed"); 251 case SignBase::Error::kSignPrivateKey: 252 return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 253 "PEM_read_bio_PrivateKey failed"); 254 case SignBase::Error::kSignPublicKey: 255 return THROW_ERR_CRYPTO_OPERATION_FAILED(env, 256 "PEM_read_bio_PUBKEY failed"); 257 default: 258 ABORT(); 259 } 260 } 261 262 case SignBase::Error::kSignOk: 263 return; 264 } 265} 266 267bool IsOneShot(const ManagedEVPPKey& key) { 268 switch (EVP_PKEY_id(key.get())) { 269 case EVP_PKEY_ED25519: 270 case EVP_PKEY_ED448: 271 return true; 272 default: 273 return false; 274 } 275} 276 277bool UseP1363Encoding(const ManagedEVPPKey& key, 278 const DSASigEnc& dsa_encoding) { 279 switch (EVP_PKEY_id(key.get())) { 280 case EVP_PKEY_EC: 281 case EVP_PKEY_DSA: 282 return dsa_encoding == kSigEncP1363; 283 default: 284 return false; 285 } 286} 287} // namespace 288 289SignBase::Error SignBase::Init(const char* sign_type) { 290 CHECK_NULL(mdctx_); 291 // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1 292 // exposed through the public API. 293 if (strcmp(sign_type, "dss1") == 0 || 294 strcmp(sign_type, "DSS1") == 0) { 295 sign_type = "SHA1"; 296 } 297 const EVP_MD* md = EVP_get_digestbyname(sign_type); 298 if (md == nullptr) 299 return kSignUnknownDigest; 300 301 mdctx_.reset(EVP_MD_CTX_new()); 302 if (!mdctx_ || !EVP_DigestInit_ex(mdctx_.get(), md, nullptr)) { 303 mdctx_.reset(); 304 return kSignInit; 305 } 306 307 return kSignOk; 308} 309 310SignBase::Error SignBase::Update(const char* data, size_t len) { 311 if (mdctx_ == nullptr) 312 return kSignNotInitialised; 313 if (!EVP_DigestUpdate(mdctx_.get(), data, len)) 314 return kSignUpdate; 315 return kSignOk; 316} 317 318SignBase::SignBase(Environment* env, Local<Object> wrap) 319 : BaseObject(env, wrap) {} 320 321void SignBase::MemoryInfo(MemoryTracker* tracker) const { 322 tracker->TrackFieldWithSize("mdctx", mdctx_ ? kSizeOf_EVP_MD_CTX : 0); 323} 324 325Sign::Sign(Environment* env, Local<Object> wrap) : SignBase(env, wrap) { 326 MakeWeak(); 327} 328 329void Sign::Initialize(Environment* env, Local<Object> target) { 330 Isolate* isolate = env->isolate(); 331 Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New); 332 333 t->InstanceTemplate()->SetInternalFieldCount( 334 SignBase::kInternalFieldCount); 335 t->Inherit(BaseObject::GetConstructorTemplate(env)); 336 337 SetProtoMethod(isolate, t, "init", SignInit); 338 SetProtoMethod(isolate, t, "update", SignUpdate); 339 SetProtoMethod(isolate, t, "sign", SignFinal); 340 341 SetConstructorFunction(env->context(), target, "Sign", t); 342 343 SignJob::Initialize(env, target); 344 345 constexpr int kSignJobModeSign = SignConfiguration::kSign; 346 constexpr int kSignJobModeVerify = SignConfiguration::kVerify; 347 348 NODE_DEFINE_CONSTANT(target, kSignJobModeSign); 349 NODE_DEFINE_CONSTANT(target, kSignJobModeVerify); 350 NODE_DEFINE_CONSTANT(target, kSigEncDER); 351 NODE_DEFINE_CONSTANT(target, kSigEncP1363); 352 NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING); 353} 354 355void Sign::RegisterExternalReferences(ExternalReferenceRegistry* registry) { 356 registry->Register(New); 357 registry->Register(SignInit); 358 registry->Register(SignUpdate); 359 registry->Register(SignFinal); 360 SignJob::RegisterExternalReferences(registry); 361} 362 363void Sign::New(const FunctionCallbackInfo<Value>& args) { 364 Environment* env = Environment::GetCurrent(args); 365 new Sign(env, args.This()); 366} 367 368void Sign::SignInit(const FunctionCallbackInfo<Value>& args) { 369 Environment* env = Environment::GetCurrent(args); 370 Sign* sign; 371 ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); 372 373 const node::Utf8Value sign_type(args.GetIsolate(), args[0]); 374 crypto::CheckThrow(env, sign->Init(*sign_type)); 375} 376 377void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) { 378 Decode<Sign>(args, [](Sign* sign, const FunctionCallbackInfo<Value>& args, 379 const char* data, size_t size) { 380 Environment* env = Environment::GetCurrent(args); 381 if (UNLIKELY(size > INT_MAX)) 382 return THROW_ERR_OUT_OF_RANGE(env, "data is too long"); 383 Error err = sign->Update(data, size); 384 crypto::CheckThrow(sign->env(), err); 385 }); 386} 387 388Sign::SignResult Sign::SignFinal( 389 const ManagedEVPPKey& pkey, 390 int padding, 391 const Maybe<int>& salt_len, 392 DSASigEnc dsa_sig_enc) { 393 if (!mdctx_) 394 return SignResult(kSignNotInitialised); 395 396 EVPMDPointer mdctx = std::move(mdctx_); 397 398 if (!ValidateDSAParameters(pkey.get())) 399 return SignResult(kSignPrivateKey); 400 401 std::unique_ptr<BackingStore> buffer = 402 Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len); 403 Error error = buffer ? kSignOk : kSignPrivateKey; 404 if (error == kSignOk && dsa_sig_enc == kSigEncP1363) { 405 buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer)); 406 CHECK_NOT_NULL(buffer->Data()); 407 } 408 return SignResult(error, std::move(buffer)); 409} 410 411void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) { 412 Environment* env = Environment::GetCurrent(args); 413 Sign* sign; 414 ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); 415 416 ClearErrorOnReturn clear_error_on_return; 417 418 unsigned int offset = 0; 419 ManagedEVPPKey key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &offset, true); 420 if (!key) 421 return; 422 423 int padding = GetDefaultSignPadding(key); 424 if (!args[offset]->IsUndefined()) { 425 CHECK(args[offset]->IsInt32()); 426 padding = args[offset].As<Int32>()->Value(); 427 } 428 429 Maybe<int> salt_len = Nothing<int>(); 430 if (!args[offset + 1]->IsUndefined()) { 431 CHECK(args[offset + 1]->IsInt32()); 432 salt_len = Just<int>(args[offset + 1].As<Int32>()->Value()); 433 } 434 435 CHECK(args[offset + 2]->IsInt32()); 436 DSASigEnc dsa_sig_enc = 437 static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value()); 438 439 SignResult ret = sign->SignFinal( 440 key, 441 padding, 442 salt_len, 443 dsa_sig_enc); 444 445 if (ret.error != kSignOk) 446 return crypto::CheckThrow(env, ret.error); 447 448 Local<ArrayBuffer> ab = 449 ArrayBuffer::New(env->isolate(), std::move(ret.signature)); 450 args.GetReturnValue().Set( 451 Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>())); 452} 453 454Verify::Verify(Environment* env, Local<Object> wrap) 455 : SignBase(env, wrap) { 456 MakeWeak(); 457} 458 459void Verify::Initialize(Environment* env, Local<Object> target) { 460 Isolate* isolate = env->isolate(); 461 Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New); 462 463 t->InstanceTemplate()->SetInternalFieldCount( 464 SignBase::kInternalFieldCount); 465 t->Inherit(BaseObject::GetConstructorTemplate(env)); 466 467 SetProtoMethod(isolate, t, "init", VerifyInit); 468 SetProtoMethod(isolate, t, "update", VerifyUpdate); 469 SetProtoMethod(isolate, t, "verify", VerifyFinal); 470 471 SetConstructorFunction(env->context(), target, "Verify", t); 472} 473 474void Verify::RegisterExternalReferences(ExternalReferenceRegistry* registry) { 475 registry->Register(New); 476 registry->Register(VerifyInit); 477 registry->Register(VerifyUpdate); 478 registry->Register(VerifyFinal); 479} 480 481void Verify::New(const FunctionCallbackInfo<Value>& args) { 482 Environment* env = Environment::GetCurrent(args); 483 new Verify(env, args.This()); 484} 485 486void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) { 487 Environment* env = Environment::GetCurrent(args); 488 Verify* verify; 489 ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder()); 490 491 const node::Utf8Value verify_type(args.GetIsolate(), args[0]); 492 crypto::CheckThrow(env, verify->Init(*verify_type)); 493} 494 495void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) { 496 Decode<Verify>(args, [](Verify* verify, 497 const FunctionCallbackInfo<Value>& args, 498 const char* data, size_t size) { 499 Environment* env = Environment::GetCurrent(args); 500 if (UNLIKELY(size > INT_MAX)) 501 return THROW_ERR_OUT_OF_RANGE(env, "data is too long"); 502 Error err = verify->Update(data, size); 503 crypto::CheckThrow(verify->env(), err); 504 }); 505} 506 507SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey, 508 const ByteSource& sig, 509 int padding, 510 const Maybe<int>& saltlen, 511 bool* verify_result) { 512 if (!mdctx_) 513 return kSignNotInitialised; 514 515 unsigned char m[EVP_MAX_MD_SIZE]; 516 unsigned int m_len; 517 *verify_result = false; 518 EVPMDPointer mdctx = std::move(mdctx_); 519 520 if (!EVP_DigestFinal_ex(mdctx.get(), m, &m_len)) 521 return kSignPublicKey; 522 523 EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); 524 if (pkctx && 525 EVP_PKEY_verify_init(pkctx.get()) > 0 && 526 ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) && 527 EVP_PKEY_CTX_set_signature_md(pkctx.get(), 528 EVP_MD_CTX_md(mdctx.get())) > 0) { 529 const unsigned char* s = sig.data<unsigned char>(); 530 const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len); 531 *verify_result = r == 1; 532 } 533 534 return kSignOk; 535} 536 537void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) { 538 Environment* env = Environment::GetCurrent(args); 539 ClearErrorOnReturn clear_error_on_return; 540 541 Verify* verify; 542 ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder()); 543 544 unsigned int offset = 0; 545 ManagedEVPPKey pkey = 546 ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &offset); 547 if (!pkey) 548 return; 549 550 ArrayBufferOrViewContents<char> hbuf(args[offset]); 551 if (UNLIKELY(!hbuf.CheckSizeInt32())) 552 return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big"); 553 554 int padding = GetDefaultSignPadding(pkey); 555 if (!args[offset + 1]->IsUndefined()) { 556 CHECK(args[offset + 1]->IsInt32()); 557 padding = args[offset + 1].As<Int32>()->Value(); 558 } 559 560 Maybe<int> salt_len = Nothing<int>(); 561 if (!args[offset + 2]->IsUndefined()) { 562 CHECK(args[offset + 2]->IsInt32()); 563 salt_len = Just<int>(args[offset + 2].As<Int32>()->Value()); 564 } 565 566 CHECK(args[offset + 3]->IsInt32()); 567 DSASigEnc dsa_sig_enc = 568 static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value()); 569 570 ByteSource signature = hbuf.ToByteSource(); 571 if (dsa_sig_enc == kSigEncP1363) { 572 signature = ConvertSignatureToDER(pkey, hbuf.ToByteSource()); 573 if (signature.data() == nullptr) 574 return crypto::CheckThrow(env, Error::kSignMalformedSignature); 575 } 576 577 bool verify_result; 578 Error err = verify->VerifyFinal(pkey, signature, padding, 579 salt_len, &verify_result); 580 if (err != kSignOk) 581 return crypto::CheckThrow(env, err); 582 args.GetReturnValue().Set(verify_result); 583} 584 585SignConfiguration::SignConfiguration(SignConfiguration&& other) noexcept 586 : job_mode(other.job_mode), 587 mode(other.mode), 588 key(std::move(other.key)), 589 data(std::move(other.data)), 590 signature(std::move(other.signature)), 591 digest(other.digest), 592 flags(other.flags), 593 padding(other.padding), 594 salt_length(other.salt_length), 595 dsa_encoding(other.dsa_encoding) {} 596 597SignConfiguration& SignConfiguration::operator=( 598 SignConfiguration&& other) noexcept { 599 if (&other == this) return *this; 600 this->~SignConfiguration(); 601 return *new (this) SignConfiguration(std::move(other)); 602} 603 604void SignConfiguration::MemoryInfo(MemoryTracker* tracker) const { 605 tracker->TrackField("key", key); 606 if (job_mode == kCryptoJobAsync) { 607 tracker->TrackFieldWithSize("data", data.size()); 608 tracker->TrackFieldWithSize("signature", signature.size()); 609 } 610} 611 612Maybe<bool> SignTraits::AdditionalConfig( 613 CryptoJobMode mode, 614 const FunctionCallbackInfo<Value>& args, 615 unsigned int offset, 616 SignConfiguration* params) { 617 ClearErrorOnReturn clear_error_on_return; 618 Environment* env = Environment::GetCurrent(args); 619 620 params->job_mode = mode; 621 622 CHECK(args[offset]->IsUint32()); // Sign Mode 623 624 params->mode = 625 static_cast<SignConfiguration::Mode>(args[offset].As<Uint32>()->Value()); 626 627 ManagedEVPPKey key; 628 unsigned int keyParamOffset = offset + 1; 629 if (params->mode == SignConfiguration::kVerify) { 630 key = ManagedEVPPKey::GetPublicOrPrivateKeyFromJs(args, &keyParamOffset); 631 } else { 632 key = ManagedEVPPKey::GetPrivateKeyFromJs(args, &keyParamOffset, true); 633 } 634 if (!key) 635 return Nothing<bool>(); 636 params->key = key; 637 638 ArrayBufferOrViewContents<char> data(args[offset + 5]); 639 if (UNLIKELY(!data.CheckSizeInt32())) { 640 THROW_ERR_OUT_OF_RANGE(env, "data is too big"); 641 return Nothing<bool>(); 642 } 643 params->data = mode == kCryptoJobAsync 644 ? data.ToCopy() 645 : data.ToByteSource(); 646 647 if (args[offset + 6]->IsString()) { 648 Utf8Value digest(env->isolate(), args[offset + 6]); 649 params->digest = EVP_get_digestbyname(*digest); 650 if (params->digest == nullptr) { 651 THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest); 652 return Nothing<bool>(); 653 } 654 } 655 656 if (args[offset + 7]->IsInt32()) { // Salt length 657 params->flags |= SignConfiguration::kHasSaltLength; 658 params->salt_length = args[offset + 7].As<Int32>()->Value(); 659 } 660 if (args[offset + 8]->IsUint32()) { // Padding 661 params->flags |= SignConfiguration::kHasPadding; 662 params->padding = args[offset + 8].As<Uint32>()->Value(); 663 } 664 665 if (args[offset + 9]->IsUint32()) { // DSA Encoding 666 params->dsa_encoding = 667 static_cast<DSASigEnc>(args[offset + 9].As<Uint32>()->Value()); 668 if (params->dsa_encoding != kSigEncDER && 669 params->dsa_encoding != kSigEncP1363) { 670 THROW_ERR_OUT_OF_RANGE(env, "invalid signature encoding"); 671 return Nothing<bool>(); 672 } 673 } 674 675 if (params->mode == SignConfiguration::kVerify) { 676 ArrayBufferOrViewContents<char> signature(args[offset + 10]); 677 if (UNLIKELY(!signature.CheckSizeInt32())) { 678 THROW_ERR_OUT_OF_RANGE(env, "signature is too big"); 679 return Nothing<bool>(); 680 } 681 // If this is an EC key (assuming ECDSA) we need to convert the 682 // the signature from WebCrypto format into DER format... 683 ManagedEVPPKey m_pkey = params->key; 684 Mutex::ScopedLock lock(*m_pkey.mutex()); 685 if (UseP1363Encoding(m_pkey, params->dsa_encoding)) { 686 params->signature = 687 ConvertSignatureToDER(m_pkey, signature.ToByteSource()); 688 } else { 689 params->signature = mode == kCryptoJobAsync 690 ? signature.ToCopy() 691 : signature.ToByteSource(); 692 } 693 } 694 695 return Just(true); 696} 697 698bool SignTraits::DeriveBits( 699 Environment* env, 700 const SignConfiguration& params, 701 ByteSource* out) { 702 ClearErrorOnReturn clear_error_on_return; 703 EVPMDPointer context(EVP_MD_CTX_new()); 704 EVP_PKEY_CTX* ctx = nullptr; 705 706 switch (params.mode) { 707 case SignConfiguration::kSign: 708 if (!EVP_DigestSignInit( 709 context.get(), 710 &ctx, 711 params.digest, 712 nullptr, 713 params.key.get())) { 714 crypto::CheckThrow(env, SignBase::Error::kSignInit); 715 return false; 716 } 717 break; 718 case SignConfiguration::kVerify: 719 if (!EVP_DigestVerifyInit( 720 context.get(), 721 &ctx, 722 params.digest, 723 nullptr, 724 params.key.get())) { 725 crypto::CheckThrow(env, SignBase::Error::kSignInit); 726 return false; 727 } 728 break; 729 } 730 731 int padding = params.flags & SignConfiguration::kHasPadding 732 ? params.padding 733 : GetDefaultSignPadding(params.key); 734 735 Maybe<int> salt_length = params.flags & SignConfiguration::kHasSaltLength 736 ? Just<int>(params.salt_length) : Nothing<int>(); 737 738 if (!ApplyRSAOptions( 739 params.key, 740 ctx, 741 padding, 742 salt_length)) { 743 crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 744 return false; 745 } 746 747 switch (params.mode) { 748 case SignConfiguration::kSign: { 749 if (IsOneShot(params.key)) { 750 size_t len; 751 if (!EVP_DigestSign( 752 context.get(), 753 nullptr, 754 &len, 755 params.data.data<unsigned char>(), 756 params.data.size())) { 757 crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 758 return false; 759 } 760 ByteSource::Builder buf(len); 761 if (!EVP_DigestSign(context.get(), 762 buf.data<unsigned char>(), 763 &len, 764 params.data.data<unsigned char>(), 765 params.data.size())) { 766 crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 767 return false; 768 } 769 *out = std::move(buf).release(len); 770 } else { 771 size_t len; 772 if (!EVP_DigestSignUpdate( 773 context.get(), 774 params.data.data<unsigned char>(), 775 params.data.size()) || 776 !EVP_DigestSignFinal(context.get(), nullptr, &len)) { 777 crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 778 return false; 779 } 780 ByteSource::Builder buf(len); 781 if (!EVP_DigestSignFinal( 782 context.get(), buf.data<unsigned char>(), &len)) { 783 crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); 784 return false; 785 } 786 787 if (UseP1363Encoding(params.key, params.dsa_encoding)) { 788 *out = ConvertSignatureToP1363( 789 env, params.key, std::move(buf).release()); 790 } else { 791 *out = std::move(buf).release(len); 792 } 793 } 794 break; 795 } 796 case SignConfiguration::kVerify: { 797 ByteSource::Builder buf(1); 798 buf.data<char>()[0] = 0; 799 if (EVP_DigestVerify( 800 context.get(), 801 params.signature.data<unsigned char>(), 802 params.signature.size(), 803 params.data.data<unsigned char>(), 804 params.data.size()) == 1) { 805 buf.data<char>()[0] = 1; 806 } 807 *out = std::move(buf).release(); 808 } 809 } 810 811 return true; 812} 813 814Maybe<bool> SignTraits::EncodeOutput( 815 Environment* env, 816 const SignConfiguration& params, 817 ByteSource* out, 818 Local<Value>* result) { 819 switch (params.mode) { 820 case SignConfiguration::kSign: 821 *result = out->ToArrayBuffer(env); 822 break; 823 case SignConfiguration::kVerify: 824 *result = Boolean::New(env->isolate(), out->data<char>()[0] == 1); 825 break; 826 default: 827 UNREACHABLE(); 828 } 829 return Just(!result->IsEmpty()); 830} 831 832} // namespace crypto 833} // namespace node 834