4343
4444#include < algorithm>
4545#include < memory>
46+ #include < utility>
4647#include < vector>
4748
4849static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
@@ -3530,46 +3531,51 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
35303531 sign->CheckThrow (err);
35313532}
35323533
3533- static int Node_SignFinal (EVPMDPointer&& mdctx, unsigned char * md ,
3534- unsigned int * sig_len ,
3535- const EVPKeyPointer& pkey, int padding,
3536- int pss_salt_len) {
3534+ static MallocedBuffer< unsigned char > Node_SignFinal (EVPMDPointer&& mdctx,
3535+ const EVPKeyPointer& pkey ,
3536+ int padding,
3537+ int pss_salt_len) {
35373538 unsigned char m[EVP_MAX_MD_SIZE];
35383539 unsigned int m_len;
35393540
3540- *sig_len = 0 ;
35413541 if (!EVP_DigestFinal_ex (mdctx.get (), m, &m_len))
3542- return 0 ;
3542+ return MallocedBuffer<unsigned char >();
3543+
3544+ int signed_sig_len = EVP_PKEY_size (pkey.get ());
3545+ CHECK_GE (signed_sig_len, 0 );
3546+ size_t sig_len = static_cast <size_t >(signed_sig_len);
3547+ MallocedBuffer<unsigned char > sig (sig_len);
35433548
3544- size_t sltmp = static_cast <size_t >(EVP_PKEY_size (pkey.get ()));
35453549 EVPKeyCtxPointer pkctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
35463550 if (pkctx &&
35473551 EVP_PKEY_sign_init (pkctx.get ()) > 0 &&
35483552 ApplyRSAOptions (pkey, pkctx.get (), padding, pss_salt_len) &&
35493553 EVP_PKEY_CTX_set_signature_md (pkctx.get (),
35503554 EVP_MD_CTX_md (mdctx.get ())) > 0 &&
3551- EVP_PKEY_sign (pkctx.get (), md , &sltmp , m, m_len) > 0 ) {
3552- * sig_len = sltmp ;
3553- return 1 ;
3555+ EVP_PKEY_sign (pkctx.get (), sig. data , &sig_len , m, m_len) > 0 ) {
3556+ sig. Truncate ( sig_len) ;
3557+ return sig ;
35543558 }
3555- return 0 ;
3559+
3560+ return MallocedBuffer<unsigned char >();
35563561}
35573562
3558- SignBase::Error Sign::SignFinal (const char * key_pem,
3559- int key_pem_len,
3560- const char * passphrase,
3561- unsigned char * sig,
3562- unsigned int * sig_len,
3563- int padding,
3564- int salt_len) {
3563+ std::pair<SignBase::Error, MallocedBuffer<unsigned char >> Sign::SignFinal (
3564+ const char * key_pem,
3565+ int key_pem_len,
3566+ const char * passphrase,
3567+ int padding,
3568+ int salt_len) {
3569+ MallocedBuffer<unsigned char > buffer;
3570+
35653571 if (!mdctx_)
3566- return kSignNotInitialised ;
3572+ return std::make_pair ( kSignNotInitialised , std::move (buffer)) ;
35673573
35683574 EVPMDPointer mdctx = std::move (mdctx_);
35693575
35703576 BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
35713577 if (!bp)
3572- return kSignPrivateKey ;
3578+ return std::make_pair ( kSignPrivateKey , std::move (buffer)) ;
35733579
35743580 EVPKeyPointer pkey (PEM_read_bio_PrivateKey (bp.get (),
35753581 nullptr ,
@@ -3580,7 +3586,7 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
35803586 // without `pkey` being set to nullptr;
35813587 // cf. the test of `test_bad_rsa_privkey.pem` for an example.
35823588 if (!pkey || 0 != ERR_peek_error ())
3583- return kSignPrivateKey ;
3589+ return std::make_pair ( kSignPrivateKey , std::move (buffer)) ;
35843590
35853591#ifdef NODE_FIPS_MODE
35863592 /* Validate DSA2 parameters from FIPS 186-4 */
@@ -3604,10 +3610,9 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
36043610 }
36053611#endif // NODE_FIPS_MODE
36063612
3607- if (Node_SignFinal (std::move (mdctx), sig, sig_len, pkey, padding, salt_len))
3608- return kSignOk ;
3609- else
3610- return kSignPrivateKey ;
3613+ buffer = Node_SignFinal (std::move (mdctx), pkey, padding, salt_len);
3614+ Error error = buffer.is_empty () ? kSignPrivateKey : kSignOk ;
3615+ return std::make_pair (error, std::move (buffer));
36113616}
36123617
36133618
@@ -3631,22 +3636,22 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
36313636 int salt_len = args[3 ].As <Int32>()->Value ();
36323637
36333638 ClearErrorOnReturn clear_error_on_return;
3634- unsigned char md_value[8192 ];
3635- unsigned int md_len = sizeof (md_value);
36363639
3637- Error err = sign->SignFinal (
3640+ std::pair< Error, MallocedBuffer< unsigned char >> ret = sign->SignFinal (
36383641 buf,
36393642 buf_len,
36403643 len >= 2 && !args[1 ]->IsNull () ? *passphrase : nullptr ,
3641- md_value,
3642- &md_len,
36433644 padding,
36443645 salt_len);
3645- if (err != kSignOk )
3646- return sign->CheckThrow (err);
3646+
3647+ if (std::get<Error>(ret) != kSignOk )
3648+ return sign->CheckThrow (std::get<Error>(ret));
3649+
3650+ MallocedBuffer<unsigned char > sig =
3651+ std::move (std::get<MallocedBuffer<unsigned char >>(ret));
36473652
36483653 Local<Object> rc =
3649- Buffer::Copy (env, reinterpret_cast <char *>(md_value), md_len )
3654+ Buffer::New (env, reinterpret_cast <char *>(sig. release ()), sig. size )
36503655 .ToLocalChecked ();
36513656 args.GetReturnValue ().Set (rc);
36523657}
0 commit comments