@@ -4907,6 +4907,9 @@ void CheckThrow(Environment* env, SignBase::Error error) {
49074907 case SignBase::Error::kSignNotInitialised :
49084908 return env->ThrowError (" Not initialised" );
49094909
4910+ case SignBase::Error::kSignMalformedSignature :
4911+ return env->ThrowError (" Malformed signature" );
4912+
49104913 case SignBase::Error::kSignInit :
49114914 case SignBase::Error::kSignUpdate :
49124915 case SignBase::Error::kSignPrivateKey :
@@ -5004,6 +5007,89 @@ static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
50045007 RSA_PKCS1_PADDING;
50055008}
50065009
5010+ static const unsigned int kNoDsaSignature = static_cast <unsigned int >(-1 );
5011+
5012+ // Returns the maximum size of each of the integers (r, s) of the DSA signature.
5013+ static unsigned int GetBytesOfRS (const ManagedEVPPKey& pkey) {
5014+ int bits, base_id = EVP_PKEY_base_id (pkey.get ());
5015+
5016+ if (base_id == EVP_PKEY_DSA) {
5017+ DSA* dsa_key = EVP_PKEY_get0_DSA (pkey.get ());
5018+ // Both r and s are computed mod q, so their width is limited by that of q.
5019+ bits = BN_num_bits (DSA_get0_q (dsa_key));
5020+ } else if (base_id == EVP_PKEY_EC) {
5021+ EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY (pkey.get ());
5022+ const EC_GROUP* ec_group = EC_KEY_get0_group (ec_key);
5023+ bits = EC_GROUP_order_bits (ec_group);
5024+ } else {
5025+ return kNoDsaSignature ;
5026+ }
5027+
5028+ return (bits + 7 ) / 8 ;
5029+ }
5030+
5031+ static AllocatedBuffer ConvertSignatureToP1363 (Environment* env,
5032+ const ManagedEVPPKey& pkey,
5033+ AllocatedBuffer&& signature) {
5034+ unsigned int n = GetBytesOfRS (pkey);
5035+ if (n == kNoDsaSignature )
5036+ return std::move (signature);
5037+
5038+ const unsigned char * sig_data =
5039+ reinterpret_cast <unsigned char *>(signature.data ());
5040+
5041+ ECDSA_SIG* asn1_sig = d2i_ECDSA_SIG (nullptr , &sig_data, signature.size ());
5042+ if (asn1_sig == nullptr )
5043+ return AllocatedBuffer ();
5044+
5045+ AllocatedBuffer buf = env->AllocateManaged (2 * n);
5046+ unsigned char * data = reinterpret_cast <unsigned char *>(buf.data ());
5047+
5048+ const BIGNUM* r = ECDSA_SIG_get0_r (asn1_sig);
5049+ const BIGNUM* s = ECDSA_SIG_get0_s (asn1_sig);
5050+ CHECK_EQ (n, BN_bn2binpad (r, data, n));
5051+ CHECK_EQ (n, BN_bn2binpad (s, data + n, n));
5052+
5053+ ECDSA_SIG_free (asn1_sig);
5054+
5055+ return buf;
5056+ }
5057+
5058+ static ByteSource ConvertSignatureToDER (
5059+ const ManagedEVPPKey& pkey,
5060+ const ArrayBufferViewContents<char >& signature) {
5061+ unsigned int n = GetBytesOfRS (pkey);
5062+ if (n == kNoDsaSignature )
5063+ return ByteSource::Foreign (signature.data (), signature.length ());
5064+
5065+ const unsigned char * sig_data =
5066+ reinterpret_cast <const unsigned char *>(signature.data ());
5067+
5068+ if (signature.length () != 2 * n)
5069+ return ByteSource ();
5070+
5071+ ECDSA_SIG* asn1_sig = ECDSA_SIG_new ();
5072+ CHECK_NOT_NULL (asn1_sig);
5073+ BIGNUM* r = BN_new ();
5074+ CHECK_NOT_NULL (r);
5075+ BIGNUM* s = BN_new ();
5076+ CHECK_NOT_NULL (s);
5077+ CHECK_EQ (r, BN_bin2bn (sig_data, n, r));
5078+ CHECK_EQ (s, BN_bin2bn (sig_data + n, n, s));
5079+ CHECK_EQ (1 , ECDSA_SIG_set0 (asn1_sig, r, s));
5080+
5081+ unsigned char * data = nullptr ;
5082+ int len = i2d_ECDSA_SIG (asn1_sig, &data);
5083+ ECDSA_SIG_free (asn1_sig);
5084+
5085+ if (len <= 0 )
5086+ return ByteSource ();
5087+
5088+ CHECK_NOT_NULL (data);
5089+
5090+ return ByteSource::Allocated (reinterpret_cast <char *>(data), len);
5091+ }
5092+
50075093static AllocatedBuffer Node_SignFinal (Environment* env,
50085094 EVPMDPointer&& mdctx,
50095095 const ManagedEVPPKey& pkey,
@@ -5063,7 +5149,8 @@ static inline bool ValidateDSAParameters(EVP_PKEY* key) {
50635149Sign::SignResult Sign::SignFinal (
50645150 const ManagedEVPPKey& pkey,
50655151 int padding,
5066- const Maybe<int >& salt_len) {
5152+ const Maybe<int >& salt_len,
5153+ DSASigEnc dsa_sig_enc) {
50675154 if (!mdctx_)
50685155 return SignResult (kSignNotInitialised );
50695156
@@ -5075,6 +5162,10 @@ Sign::SignResult Sign::SignFinal(
50755162 AllocatedBuffer buffer =
50765163 Node_SignFinal (env (), std::move (mdctx), pkey, padding, salt_len);
50775164 Error error = buffer.data () == nullptr ? kSignPrivateKey : kSignOk ;
5165+ if (error == kSignOk && dsa_sig_enc == kSigEncP1363 ) {
5166+ buffer = ConvertSignatureToP1363 (env (), pkey, std::move (buffer));
5167+ CHECK_NOT_NULL (buffer.data ());
5168+ }
50785169 return SignResult (error, std::move (buffer));
50795170}
50805171
@@ -5102,10 +5193,15 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
51025193 salt_len = Just<int >(args[offset + 1 ].As <Int32>()->Value ());
51035194 }
51045195
5196+ CHECK (args[offset + 2 ]->IsInt32 ());
5197+ DSASigEnc dsa_sig_enc =
5198+ static_cast <DSASigEnc>(args[offset + 2 ].As <Int32>()->Value ());
5199+
51055200 SignResult ret = sign->SignFinal (
51065201 key,
51075202 padding,
5108- salt_len);
5203+ salt_len,
5204+ dsa_sig_enc);
51095205
51105206 if (ret.error != kSignOk )
51115207 return sign->CheckThrow (ret.error );
@@ -5149,6 +5245,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
51495245 rsa_salt_len = Just<int >(args[offset + 3 ].As <Int32>()->Value ());
51505246 }
51515247
5248+ CHECK (args[offset + 4 ]->IsInt32 ());
5249+ DSASigEnc dsa_sig_enc =
5250+ static_cast <DSASigEnc>(args[offset + 4 ].As <Int32>()->Value ());
5251+
51525252 EVP_PKEY_CTX* pkctx = nullptr ;
51535253 EVPMDPointer mdctx (EVP_MD_CTX_new ());
51545254 if (!mdctx ||
@@ -5176,6 +5276,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
51765276
51775277 signature.Resize (sig_len);
51785278
5279+ if (dsa_sig_enc == kSigEncP1363 ) {
5280+ signature = ConvertSignatureToP1363 (env, key, std::move (signature));
5281+ }
5282+
51795283 args.GetReturnValue ().Set (signature.ToBuffer ().ToLocalChecked ());
51805284}
51815285
@@ -5281,6 +5385,17 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
52815385 salt_len = Just<int >(args[offset + 2 ].As <Int32>()->Value ());
52825386 }
52835387
5388+ CHECK (args[offset + 3 ]->IsInt32 ());
5389+ DSASigEnc dsa_sig_enc =
5390+ static_cast <DSASigEnc>(args[offset + 3 ].As <Int32>()->Value ());
5391+
5392+ ByteSource signature = ByteSource::Foreign (hbuf.data (), hbuf.length ());
5393+ if (dsa_sig_enc == kSigEncP1363 ) {
5394+ signature = ConvertSignatureToDER (pkey, hbuf);
5395+ if (signature.get () == nullptr )
5396+ return verify->CheckThrow (Error::kSignMalformedSignature );
5397+ }
5398+
52845399 bool verify_result;
52855400 Error err = verify->VerifyFinal (pkey, hbuf.data (), hbuf.length (), padding,
52865401 salt_len, &verify_result);
@@ -5324,6 +5439,10 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
53245439 rsa_salt_len = Just<int >(args[offset + 4 ].As <Int32>()->Value ());
53255440 }
53265441
5442+ CHECK (args[offset + 5 ]->IsInt32 ());
5443+ DSASigEnc dsa_sig_enc =
5444+ static_cast <DSASigEnc>(args[offset + 5 ].As <Int32>()->Value ());
5445+
53275446 EVP_PKEY_CTX* pkctx = nullptr ;
53285447 EVPMDPointer mdctx (EVP_MD_CTX_new ());
53295448 if (!mdctx ||
@@ -5334,11 +5453,18 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
53345453 if (!ApplyRSAOptions (key, pkctx, rsa_padding, rsa_salt_len))
53355454 return CheckThrow (env, SignBase::Error::kSignPublicKey );
53365455
5456+ ByteSource sig_bytes = ByteSource::Foreign (sig.data (), sig.length ());
5457+ if (dsa_sig_enc == kSigEncP1363 ) {
5458+ sig_bytes = ConvertSignatureToDER (key, sig);
5459+ if (!sig_bytes)
5460+ return CheckThrow (env, SignBase::Error::kSignMalformedSignature );
5461+ }
5462+
53375463 bool verify_result;
53385464 const int r = EVP_DigestVerify (
53395465 mdctx.get (),
5340- reinterpret_cast <const unsigned char *>(sig. data ()),
5341- sig. length (),
5466+ reinterpret_cast <const unsigned char *>(sig_bytes. get ()),
5467+ sig_bytes. size (),
53425468 reinterpret_cast <const unsigned char *>(data.data ()),
53435469 data.length ());
53445470 switch (r) {
@@ -7126,6 +7252,8 @@ void Initialize(Local<Object> target,
71267252 NODE_DEFINE_CONSTANT (target, kKeyTypeSecret );
71277253 NODE_DEFINE_CONSTANT (target, kKeyTypePublic );
71287254 NODE_DEFINE_CONSTANT (target, kKeyTypePrivate );
7255+ NODE_DEFINE_CONSTANT (target, kSigEncDER );
7256+ NODE_DEFINE_CONSTANT (target, kSigEncP1363 );
71297257 env->SetMethod (target, " randomBytes" , RandomBytes);
71307258 env->SetMethod (target, " signOneShot" , SignOneShot);
71317259 env->SetMethod (target, " verifyOneShot" , VerifyOneShot);
0 commit comments