@@ -4910,6 +4910,9 @@ void CheckThrow(Environment* env, SignBase::Error error) {
4910
4910
case SignBase::Error::kSignNotInitialised :
4911
4911
return env->ThrowError (" Not initialised" );
4912
4912
4913
+ case SignBase::Error::kSignMalformedSignature :
4914
+ return env->ThrowError (" Malformed signature" );
4915
+
4913
4916
case SignBase::Error::kSignInit :
4914
4917
case SignBase::Error::kSignUpdate :
4915
4918
case SignBase::Error::kSignPrivateKey :
@@ -5007,6 +5010,89 @@ static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
5007
5010
RSA_PKCS1_PADDING;
5008
5011
}
5009
5012
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
+
5010
5096
static AllocatedBuffer Node_SignFinal (Environment* env,
5011
5097
EVPMDPointer&& mdctx,
5012
5098
const ManagedEVPPKey& pkey,
@@ -5066,7 +5152,8 @@ static inline bool ValidateDSAParameters(EVP_PKEY* key) {
5066
5152
Sign::SignResult Sign::SignFinal (
5067
5153
const ManagedEVPPKey& pkey,
5068
5154
int padding,
5069
- const Maybe<int >& salt_len) {
5155
+ const Maybe<int >& salt_len,
5156
+ DSASigEnc dsa_sig_enc) {
5070
5157
if (!mdctx_)
5071
5158
return SignResult (kSignNotInitialised );
5072
5159
@@ -5078,6 +5165,10 @@ Sign::SignResult Sign::SignFinal(
5078
5165
AllocatedBuffer buffer =
5079
5166
Node_SignFinal (env (), std::move (mdctx), pkey, padding, salt_len);
5080
5167
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
+ }
5081
5172
return SignResult (error, std::move (buffer));
5082
5173
}
5083
5174
@@ -5105,10 +5196,15 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
5105
5196
salt_len = Just<int >(args[offset + 1 ].As <Int32>()->Value ());
5106
5197
}
5107
5198
5199
+ CHECK (args[offset + 2 ]->IsInt32 ());
5200
+ DSASigEnc dsa_sig_enc =
5201
+ static_cast <DSASigEnc>(args[offset + 2 ].As <Int32>()->Value ());
5202
+
5108
5203
SignResult ret = sign->SignFinal (
5109
5204
key,
5110
5205
padding,
5111
- salt_len);
5206
+ salt_len,
5207
+ dsa_sig_enc);
5112
5208
5113
5209
if (ret.error != kSignOk )
5114
5210
return sign->CheckThrow (ret.error );
@@ -5152,6 +5248,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
5152
5248
rsa_salt_len = Just<int >(args[offset + 3 ].As <Int32>()->Value ());
5153
5249
}
5154
5250
5251
+ CHECK (args[offset + 4 ]->IsInt32 ());
5252
+ DSASigEnc dsa_sig_enc =
5253
+ static_cast <DSASigEnc>(args[offset + 4 ].As <Int32>()->Value ());
5254
+
5155
5255
EVP_PKEY_CTX* pkctx = nullptr ;
5156
5256
EVPMDPointer mdctx (EVP_MD_CTX_new ());
5157
5257
if (!mdctx ||
@@ -5179,6 +5279,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) {
5179
5279
5180
5280
signature.Resize (sig_len);
5181
5281
5282
+ if (dsa_sig_enc == kSigEncP1363 ) {
5283
+ signature = ConvertSignatureToP1363 (env, key, std::move (signature));
5284
+ }
5285
+
5182
5286
args.GetReturnValue ().Set (signature.ToBuffer ().ToLocalChecked ());
5183
5287
}
5184
5288
@@ -5284,6 +5388,17 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
5284
5388
salt_len = Just<int >(args[offset + 2 ].As <Int32>()->Value ());
5285
5389
}
5286
5390
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
+
5287
5402
bool verify_result;
5288
5403
Error err = verify->VerifyFinal (pkey, hbuf.data (), hbuf.length (), padding,
5289
5404
salt_len, &verify_result);
@@ -5327,6 +5442,10 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
5327
5442
rsa_salt_len = Just<int >(args[offset + 4 ].As <Int32>()->Value ());
5328
5443
}
5329
5444
5445
+ CHECK (args[offset + 5 ]->IsInt32 ());
5446
+ DSASigEnc dsa_sig_enc =
5447
+ static_cast <DSASigEnc>(args[offset + 5 ].As <Int32>()->Value ());
5448
+
5330
5449
EVP_PKEY_CTX* pkctx = nullptr ;
5331
5450
EVPMDPointer mdctx (EVP_MD_CTX_new ());
5332
5451
if (!mdctx ||
@@ -5337,11 +5456,18 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) {
5337
5456
if (!ApplyRSAOptions (key, pkctx, rsa_padding, rsa_salt_len))
5338
5457
return CheckThrow (env, SignBase::Error::kSignPublicKey );
5339
5458
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
+
5340
5466
bool verify_result;
5341
5467
const int r = EVP_DigestVerify (
5342
5468
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 (),
5345
5471
reinterpret_cast <const unsigned char *>(data.data ()),
5346
5472
data.length ());
5347
5473
switch (r) {
@@ -7129,6 +7255,8 @@ void Initialize(Local<Object> target,
7129
7255
NODE_DEFINE_CONSTANT (target, kKeyTypeSecret );
7130
7256
NODE_DEFINE_CONSTANT (target, kKeyTypePublic );
7131
7257
NODE_DEFINE_CONSTANT (target, kKeyTypePrivate );
7258
+ NODE_DEFINE_CONSTANT (target, kSigEncDER );
7259
+ NODE_DEFINE_CONSTANT (target, kSigEncP1363 );
7132
7260
env->SetMethod (target, " randomBytes" , RandomBytes);
7133
7261
env->SetMethod (target, " signOneShot" , SignOneShot);
7134
7262
env->SetMethod (target, " verifyOneShot" , VerifyOneShot);
0 commit comments