@@ -4910,6 +4910,9 @@ void CheckThrow(Environment* env, SignBase::Error error) {
49104910 case SignBase::Error::kSignNotInitialised :
49114911 return env->ThrowError (" Not initialised" );
49124912
4913+ case SignBase::Error::kSignMalformedSignature :
4914+ return env->ThrowError (" Malformed signature" );
4915+
49134916 case SignBase::Error::kSignInit :
49144917 case SignBase::Error::kSignUpdate :
49154918 case SignBase::Error::kSignPrivateKey :
@@ -5007,6 +5010,89 @@ static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
50075010 RSA_PKCS1_PADDING;
50085011}
50095012
5013+ static const unsigned int kNoDsaSignature = static_cast <unsigned int >(-1 );
5014+
5015+ // Returns the maximum size of each of the integers (r, s) of the DSA signature.
5016+ static unsigned int GetBytesOfRS (const ManagedEVPPKey& pkey) {
5017+ int bits, base_id = EVP_PKEY_base_id (pkey.get ());
5018+
5019+ if (base_id == EVP_PKEY_DSA) {
5020+ DSA* dsa_key = EVP_PKEY_get0_DSA (pkey.get ());
5021+ // Both r and s are computed mod q, so their width is limited by that of q.
5022+ bits = BN_num_bits (DSA_get0_q (dsa_key));
5023+ } else if (base_id == EVP_PKEY_EC) {
5024+ EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY (pkey.get ());
5025+ const EC_GROUP* ec_group = EC_KEY_get0_group (ec_key);
5026+ bits = EC_GROUP_order_bits (ec_group);
5027+ } else {
5028+ return kNoDsaSignature ;
5029+ }
5030+
5031+ return (bits + 7 ) / 8 ;
5032+ }
5033+
5034+ static AllocatedBuffer ConvertSignatureToP1363 (Environment* env,
5035+ const ManagedEVPPKey& pkey,
5036+ AllocatedBuffer&& signature) {
5037+ unsigned int n = GetBytesOfRS (pkey);
5038+ if (n == kNoDsaSignature )
5039+ return std::move (signature);
5040+
5041+ const unsigned char * sig_data =
5042+ reinterpret_cast <unsigned char *>(signature.data ());
5043+
5044+ ECDSA_SIG* asn1_sig = d2i_ECDSA_SIG (nullptr , &sig_data, signature.size ());
5045+ if (asn1_sig == nullptr )
5046+ return AllocatedBuffer ();
5047+
5048+ AllocatedBuffer buf = env->AllocateManaged (2 * n);
5049+ unsigned char * data = reinterpret_cast <unsigned char *>(buf.data ());
5050+
5051+ const BIGNUM* r = ECDSA_SIG_get0_r (asn1_sig);
5052+ const BIGNUM* s = ECDSA_SIG_get0_s (asn1_sig);
5053+ CHECK_EQ (n, BN_bn2binpad (r, data, n));
5054+ CHECK_EQ (n, BN_bn2binpad (s, data + n, n));
5055+
5056+ ECDSA_SIG_free (asn1_sig);
5057+
5058+ return buf;
5059+ }
5060+
5061+ static ByteSource ConvertSignatureToDER (
5062+ const ManagedEVPPKey& pkey,
5063+ const ArrayBufferViewContents<char >& signature) {
5064+ unsigned int n = GetBytesOfRS (pkey);
5065+ if (n == kNoDsaSignature )
5066+ return ByteSource::Foreign (signature.data (), signature.length ());
5067+
5068+ const unsigned char * sig_data =
5069+ reinterpret_cast <const unsigned char *>(signature.data ());
5070+
5071+ if (signature.length () != 2 * n)
5072+ return ByteSource ();
5073+
5074+ ECDSA_SIG* asn1_sig = ECDSA_SIG_new ();
5075+ CHECK_NOT_NULL (asn1_sig);
5076+ BIGNUM* r = BN_new ();
5077+ CHECK_NOT_NULL (r);
5078+ BIGNUM* s = BN_new ();
5079+ CHECK_NOT_NULL (s);
5080+ CHECK_EQ (r, BN_bin2bn (sig_data, n, r));
5081+ CHECK_EQ (s, BN_bin2bn (sig_data + n, n, s));
5082+ CHECK_EQ (1 , ECDSA_SIG_set0 (asn1_sig, r, s));
5083+
5084+ unsigned char * data = nullptr ;
5085+ int len = i2d_ECDSA_SIG (asn1_sig, &data);
5086+ ECDSA_SIG_free (asn1_sig);
5087+
5088+ if (len <= 0 )
5089+ return ByteSource ();
5090+
5091+ CHECK_NOT_NULL (data);
5092+
5093+ return ByteSource::Allocated (reinterpret_cast <char *>(data), len);
5094+ }
5095+
50105096static AllocatedBuffer Node_SignFinal (Environment* env,
50115097 EVPMDPointer&& mdctx,
50125098 const ManagedEVPPKey& pkey,
@@ -5066,7 +5152,8 @@ static inline bool ValidateDSAParameters(EVP_PKEY* key) {
50665152Sign::SignResult Sign::SignFinal (
50675153 const ManagedEVPPKey& pkey,
50685154 int padding,
5069- const Maybe<int >& salt_len) {
5155+ const Maybe<int >& salt_len,
5156+ DSASigEnc dsa_sig_enc) {
50705157 if (!mdctx_)
50715158 return SignResult (kSignNotInitialised );
50725159
@@ -5078,6 +5165,10 @@ Sign::SignResult Sign::SignFinal(
50785165 AllocatedBuffer buffer =
50795166 Node_SignFinal (env (), std::move (mdctx), pkey, padding, salt_len);
50805167 Error error = buffer.data () == nullptr ? kSignPrivateKey : kSignOk ;
5168+ if (error == kSignOk && dsa_sig_enc == kSigEncP1363 ) {
5169+ buffer = ConvertSignatureToP1363 (env (), pkey, std::move (buffer));
5170+ CHECK_NOT_NULL (buffer.data ());
5171+ }
50815172 return SignResult (error, std::move (buffer));
50825173}
50835174
@@ -5105,10 +5196,15 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
51055196 salt_len = Just<int >(args[offset + 1 ].As <Int32>()->Value ());
51065197 }
51075198
5199+ CHECK (args[offset + 2 ]->IsInt32 ());
5200+ DSASigEnc dsa_sig_enc =
5201+ static_cast <DSASigEnc>(args[offset + 2 ].As <Int32>()->Value ());
5202+
51085203 SignResult ret = sign->SignFinal (
51095204 key,
51105205 padding,
5111- salt_len);
5206+ salt_len,
5207+ dsa_sig_enc);
51125208
51135209 if (ret.error != kSignOk )
51145210 return sign->CheckThrow (ret.error );
@@ -5152,6 +5248,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
51525248 rsa_salt_len = Just<int >(args[offset + 3 ].As <Int32>()->Value ());
51535249 }
51545250
5251+ CHECK (args[offset + 4 ]->IsInt32 ());
5252+ DSASigEnc dsa_sig_enc =
5253+ static_cast <DSASigEnc>(args[offset + 4 ].As <Int32>()->Value ());
5254+
51555255 EVP_PKEY_CTX* pkctx = nullptr ;
51565256 EVPMDPointer mdctx (EVP_MD_CTX_new ());
51575257 if (!mdctx ||
@@ -5179,6 +5279,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
51795279
51805280 signature.Resize (sig_len);
51815281
5282+ if (dsa_sig_enc == kSigEncP1363 ) {
5283+ signature = ConvertSignatureToP1363 (env, key, std::move (signature));
5284+ }
5285+
51825286 args.GetReturnValue ().Set (signature.ToBuffer ().ToLocalChecked ());
51835287}
51845288
@@ -5284,6 +5388,17 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
52845388 salt_len = Just<int >(args[offset + 2 ].As <Int32>()->Value ());
52855389 }
52865390
5391+ CHECK (args[offset + 3 ]->IsInt32 ());
5392+ DSASigEnc dsa_sig_enc =
5393+ static_cast <DSASigEnc>(args[offset + 3 ].As <Int32>()->Value ());
5394+
5395+ ByteSource signature = ByteSource::Foreign (hbuf.data (), hbuf.length ());
5396+ if (dsa_sig_enc == kSigEncP1363 ) {
5397+ signature = ConvertSignatureToDER (pkey, hbuf);
5398+ if (signature.get () == nullptr )
5399+ return verify->CheckThrow (Error::kSignMalformedSignature );
5400+ }
5401+
52875402 bool verify_result;
52885403 Error err = verify->VerifyFinal (pkey, hbuf.data (), hbuf.length (), padding,
52895404 salt_len, &verify_result);
@@ -5327,6 +5442,10 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
53275442 rsa_salt_len = Just<int >(args[offset + 4 ].As <Int32>()->Value ());
53285443 }
53295444
5445+ CHECK (args[offset + 5 ]->IsInt32 ());
5446+ DSASigEnc dsa_sig_enc =
5447+ static_cast <DSASigEnc>(args[offset + 5 ].As <Int32>()->Value ());
5448+
53305449 EVP_PKEY_CTX* pkctx = nullptr ;
53315450 EVPMDPointer mdctx (EVP_MD_CTX_new ());
53325451 if (!mdctx ||
@@ -5337,11 +5456,18 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
53375456 if (!ApplyRSAOptions (key, pkctx, rsa_padding, rsa_salt_len))
53385457 return CheckThrow (env, SignBase::Error::kSignPublicKey );
53395458
5459+ ByteSource sig_bytes = ByteSource::Foreign (sig.data (), sig.length ());
5460+ if (dsa_sig_enc == kSigEncP1363 ) {
5461+ sig_bytes = ConvertSignatureToDER (key, sig);
5462+ if (!sig_bytes)
5463+ return CheckThrow (env, SignBase::Error::kSignMalformedSignature );
5464+ }
5465+
53405466 bool verify_result;
53415467 const int r = EVP_DigestVerify (
53425468 mdctx.get (),
5343- reinterpret_cast <const unsigned char *>(sig. data ()),
5344- sig. length (),
5469+ reinterpret_cast <const unsigned char *>(sig_bytes. get ()),
5470+ sig_bytes. size (),
53455471 reinterpret_cast <const unsigned char *>(data.data ()),
53465472 data.length ());
53475473 switch (r) {
@@ -7129,6 +7255,8 @@ void Initialize(Local<Object> target,
71297255 NODE_DEFINE_CONSTANT (target, kKeyTypeSecret );
71307256 NODE_DEFINE_CONSTANT (target, kKeyTypePublic );
71317257 NODE_DEFINE_CONSTANT (target, kKeyTypePrivate );
7258+ NODE_DEFINE_CONSTANT (target, kSigEncDER );
7259+ NODE_DEFINE_CONSTANT (target, kSigEncP1363 );
71327260 env->SetMethod (target, " randomBytes" , RandomBytes);
71337261 env->SetMethod (target, " signOneShot" , SignOneShot);
71347262 env->SetMethod (target, " verifyOneShot" , VerifyOneShot);
0 commit comments