@@ -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); |
|