4343
4444#include < algorithm>
4545#include < memory>
46+ #include < utility>
4647#include < vector>
4748
4849static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
@@ -3523,46 +3524,51 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
35233524 sign->CheckThrow (err);
35243525}
35253526
3526- static int Node_SignFinal (EVPMDPointer&& mdctx, unsigned char * md ,
3527- unsigned int * sig_len ,
3528- const EVPKeyPointer& pkey, int padding,
3529- int pss_salt_len) {
3527+ static MallocedBuffer< unsigned char > Node_SignFinal (EVPMDPointer&& mdctx,
3528+ const EVPKeyPointer& pkey ,
3529+ int padding,
3530+ int pss_salt_len) {
35303531 unsigned char m[EVP_MAX_MD_SIZE];
35313532 unsigned int m_len;
35323533
3533- *sig_len = 0 ;
35343534 if (!EVP_DigestFinal_ex (mdctx.get (), m, &m_len))
3535- return 0 ;
3535+ return MallocedBuffer<unsigned char >();
3536+
3537+ int signed_sig_len = EVP_PKEY_size (pkey.get ());
3538+ CHECK_GE (signed_sig_len, 0 );
3539+ size_t sig_len = static_cast <size_t >(signed_sig_len);
3540+ MallocedBuffer<unsigned char > sig (sig_len);
35363541
3537- size_t sltmp = static_cast <size_t >(EVP_PKEY_size (pkey.get ()));
35383542 EVPKeyCtxPointer pkctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
35393543 if (pkctx &&
35403544 EVP_PKEY_sign_init (pkctx.get ()) > 0 &&
35413545 ApplyRSAOptions (pkey, pkctx.get (), padding, pss_salt_len) &&
35423546 EVP_PKEY_CTX_set_signature_md (pkctx.get (),
35433547 EVP_MD_CTX_md (mdctx.get ())) > 0 &&
3544- EVP_PKEY_sign (pkctx.get (), md , &sltmp , m, m_len) > 0 ) {
3545- * sig_len = sltmp ;
3546- return 1 ;
3548+ EVP_PKEY_sign (pkctx.get (), sig. data , &sig_len , m, m_len) > 0 ) {
3549+ sig. Truncate ( sig_len) ;
3550+ return sig ;
35473551 }
3548- return 0 ;
3552+
3553+ return MallocedBuffer<unsigned char >();
35493554}
35503555
3551- SignBase::Error Sign::SignFinal (const char * key_pem,
3552- int key_pem_len,
3553- const char * passphrase,
3554- unsigned char * sig,
3555- unsigned int * sig_len,
3556- int padding,
3557- int salt_len) {
3556+ std::pair<SignBase::Error, MallocedBuffer<unsigned char >> Sign::SignFinal (
3557+ const char * key_pem,
3558+ int key_pem_len,
3559+ const char * passphrase,
3560+ int padding,
3561+ int salt_len) {
3562+ MallocedBuffer<unsigned char > buffer;
3563+
35583564 if (!mdctx_)
3559- return kSignNotInitialised ;
3565+ return std::make_pair ( kSignNotInitialised , std::move (buffer)) ;
35603566
35613567 EVPMDPointer mdctx = std::move (mdctx_);
35623568
35633569 BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
35643570 if (!bp)
3565- return kSignPrivateKey ;
3571+ return std::make_pair ( kSignPrivateKey , std::move (buffer)) ;
35663572
35673573 EVPKeyPointer pkey (PEM_read_bio_PrivateKey (bp.get (),
35683574 nullptr ,
@@ -3573,7 +3579,7 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
35733579 // without `pkey` being set to nullptr;
35743580 // cf. the test of `test_bad_rsa_privkey.pem` for an example.
35753581 if (!pkey || 0 != ERR_peek_error ())
3576- return kSignPrivateKey ;
3582+ return std::make_pair ( kSignPrivateKey , std::move (buffer)) ;
35773583
35783584#ifdef NODE_FIPS_MODE
35793585 /* Validate DSA2 parameters from FIPS 186-4 */
@@ -3597,10 +3603,9 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
35973603 }
35983604#endif // NODE_FIPS_MODE
35993605
3600- if (Node_SignFinal (std::move (mdctx), sig, sig_len, pkey, padding, salt_len))
3601- return kSignOk ;
3602- else
3603- return kSignPrivateKey ;
3606+ buffer = Node_SignFinal (std::move (mdctx), pkey, padding, salt_len);
3607+ Error error = buffer.is_empty () ? kSignPrivateKey : kSignOk ;
3608+ return std::make_pair (error, std::move (buffer));
36043609}
36053610
36063611
@@ -3624,22 +3629,22 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
36243629 int salt_len = args[3 ].As <Int32>()->Value ();
36253630
36263631 ClearErrorOnReturn clear_error_on_return;
3627- unsigned char md_value[8192 ];
3628- unsigned int md_len = sizeof (md_value);
36293632
3630- Error err = sign->SignFinal (
3633+ std::pair< Error, MallocedBuffer< unsigned char >> ret = sign->SignFinal (
36313634 buf,
36323635 buf_len,
36333636 len >= 2 && !args[1 ]->IsNull () ? *passphrase : nullptr ,
3634- md_value,
3635- &md_len,
36363637 padding,
36373638 salt_len);
3638- if (err != kSignOk )
3639- return sign->CheckThrow (err);
3639+
3640+ if (std::get<Error>(ret) != kSignOk )
3641+ return sign->CheckThrow (std::get<Error>(ret));
3642+
3643+ MallocedBuffer<unsigned char > sig =
3644+ std::move (std::get<MallocedBuffer<unsigned char >>(ret));
36403645
36413646 Local<Object> rc =
3642- Buffer::Copy (env, reinterpret_cast <char *>(md_value), md_len )
3647+ Buffer::New (env, reinterpret_cast <char *>(sig. release ()), sig. size )
36433648 .ToLocalChecked ();
36443649 args.GetReturnValue ().Set (rc);
36453650}
0 commit comments