@@ -4907,6 +4907,9 @@ void CheckThrow(Environment* env, SignBase::Error error) {
4907
4907
case SignBase::Error::kSignNotInitialised :
4908
4908
return env->ThrowError (" Not initialised" );
4909
4909
4910
+ case SignBase::Error::kSignMalformedSignature :
4911
+ return env->ThrowError (" Malformed signature" );
4912
+
4910
4913
case SignBase::Error::kSignInit :
4911
4914
case SignBase::Error::kSignUpdate :
4912
4915
case SignBase::Error::kSignPrivateKey :
@@ -5004,6 +5007,89 @@ static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
5004
5007
RSA_PKCS1_PADDING;
5005
5008
}
5006
5009
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
+
5007
5093
static AllocatedBuffer Node_SignFinal (Environment* env,
5008
5094
EVPMDPointer&& mdctx,
5009
5095
const ManagedEVPPKey& pkey,
@@ -5063,7 +5149,8 @@ static inline bool ValidateDSAParameters(EVP_PKEY* key) {
5063
5149
Sign::SignResult Sign::SignFinal (
5064
5150
const ManagedEVPPKey& pkey,
5065
5151
int padding,
5066
- const Maybe<int >& salt_len) {
5152
+ const Maybe<int >& salt_len,
5153
+ DSASigEnc dsa_sig_enc) {
5067
5154
if (!mdctx_)
5068
5155
return SignResult (kSignNotInitialised );
5069
5156
@@ -5075,6 +5162,10 @@ Sign::SignResult Sign::SignFinal(
5075
5162
AllocatedBuffer buffer =
5076
5163
Node_SignFinal (env (), std::move (mdctx), pkey, padding, salt_len);
5077
5164
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
+ }
5078
5169
return SignResult (error, std::move (buffer));
5079
5170
}
5080
5171
@@ -5102,10 +5193,15 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
5102
5193
salt_len = Just<int >(args[offset + 1 ].As <Int32>()->Value ());
5103
5194
}
5104
5195
5196
+ CHECK (args[offset + 2 ]->IsInt32 ());
5197
+ DSASigEnc dsa_sig_enc =
5198
+ static_cast <DSASigEnc>(args[offset + 2 ].As <Int32>()->Value ());
5199
+
5105
5200
SignResult ret = sign->SignFinal (
5106
5201
key,
5107
5202
padding,
5108
- salt_len);
5203
+ salt_len,
5204
+ dsa_sig_enc);
5109
5205
5110
5206
if (ret.error != kSignOk )
5111
5207
return sign->CheckThrow (ret.error );
@@ -5149,6 +5245,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
5149
5245
rsa_salt_len = Just<int >(args[offset + 3 ].As <Int32>()->Value ());
5150
5246
}
5151
5247
5248
+ CHECK (args[offset + 4 ]->IsInt32 ());
5249
+ DSASigEnc dsa_sig_enc =
5250
+ static_cast <DSASigEnc>(args[offset + 4 ].As <Int32>()->Value ());
5251
+
5152
5252
EVP_PKEY_CTX* pkctx = nullptr ;
5153
5253
EVPMDPointer mdctx (EVP_MD_CTX_new ());
5154
5254
if (!mdctx ||
@@ -5176,6 +5276,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
5176
5276
5177
5277
signature.Resize (sig_len);
5178
5278
5279
+ if (dsa_sig_enc == kSigEncP1363 ) {
5280
+ signature = ConvertSignatureToP1363 (env, key, std::move (signature));
5281
+ }
5282
+
5179
5283
args.GetReturnValue ().Set (signature.ToBuffer ().ToLocalChecked ());
5180
5284
}
5181
5285
@@ -5281,6 +5385,17 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
5281
5385
salt_len = Just<int >(args[offset + 2 ].As <Int32>()->Value ());
5282
5386
}
5283
5387
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
+
5284
5399
bool verify_result;
5285
5400
Error err = verify->VerifyFinal (pkey, hbuf.data (), hbuf.length (), padding,
5286
5401
salt_len, &verify_result);
@@ -5324,6 +5439,10 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
5324
5439
rsa_salt_len = Just<int >(args[offset + 4 ].As <Int32>()->Value ());
5325
5440
}
5326
5441
5442
+ CHECK (args[offset + 5 ]->IsInt32 ());
5443
+ DSASigEnc dsa_sig_enc =
5444
+ static_cast <DSASigEnc>(args[offset + 5 ].As <Int32>()->Value ());
5445
+
5327
5446
EVP_PKEY_CTX* pkctx = nullptr ;
5328
5447
EVPMDPointer mdctx (EVP_MD_CTX_new ());
5329
5448
if (!mdctx ||
@@ -5334,11 +5453,18 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
5334
5453
if (!ApplyRSAOptions (key, pkctx, rsa_padding, rsa_salt_len))
5335
5454
return CheckThrow (env, SignBase::Error::kSignPublicKey );
5336
5455
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
+
5337
5463
bool verify_result;
5338
5464
const int r = EVP_DigestVerify (
5339
5465
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 (),
5342
5468
reinterpret_cast <const unsigned char *>(data.data ()),
5343
5469
data.length ());
5344
5470
switch (r) {
@@ -7126,6 +7252,8 @@ void Initialize(Local<Object> target,
7126
7252
NODE_DEFINE_CONSTANT (target, kKeyTypeSecret );
7127
7253
NODE_DEFINE_CONSTANT (target, kKeyTypePublic );
7128
7254
NODE_DEFINE_CONSTANT (target, kKeyTypePrivate );
7255
+ NODE_DEFINE_CONSTANT (target, kSigEncDER );
7256
+ NODE_DEFINE_CONSTANT (target, kSigEncP1363 );
7129
7257
env->SetMethod (target, " randomBytes" , RandomBytes);
7130
7258
env->SetMethod (target, " signOneShot" , SignOneShot);
7131
7259
env->SetMethod (target, " verifyOneShot" , VerifyOneShot);
0 commit comments