Skip to content

Commit 2419b86

Browse files
davidbengibfahn
authored andcommitted
crypto: make SignBase compatible with OpenSSL 1.1.0
1.1.0 requires EVP_MD_CTX be heap-allocated. In doing so, move the Init and Update hooks to shared code because they are the same between Verify and Sign. PR-URL: #16130 Backport-PR-URL: #18622 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
1 parent 0ef35a1 commit 2419b86

File tree

2 files changed

+53
-78
lines changed

2 files changed

+53
-78
lines changed

src/node_crypto.cc

Lines changed: 47 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4096,6 +4096,38 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
40964096
}
40974097

40984098

4099+
SignBase::~SignBase() {
4100+
EVP_MD_CTX_free(mdctx_);
4101+
}
4102+
4103+
4104+
SignBase::Error SignBase::Init(const char* sign_type) {
4105+
CHECK_EQ(mdctx_, nullptr);
4106+
const EVP_MD* md = EVP_get_digestbyname(sign_type);
4107+
if (md == nullptr)
4108+
return kSignUnknownDigest;
4109+
4110+
mdctx_ = EVP_MD_CTX_new();
4111+
if (mdctx_ == nullptr ||
4112+
!EVP_DigestInit_ex(mdctx_, md, nullptr)) {
4113+
EVP_MD_CTX_free(mdctx_);
4114+
mdctx_ = nullptr;
4115+
return kSignInit;
4116+
}
4117+
4118+
return kSignOk;
4119+
}
4120+
4121+
4122+
SignBase::Error SignBase::Update(const char* data, int len) {
4123+
if (mdctx_ == nullptr)
4124+
return kSignNotInitialised;
4125+
if (!EVP_DigestUpdate(mdctx_, data, len))
4126+
return kSignUpdate;
4127+
return kSignOk;
4128+
}
4129+
4130+
40994131
void SignBase::CheckThrow(SignBase::Error error) {
41004132
HandleScope scope(env()->isolate());
41014133

@@ -4169,21 +4201,6 @@ void Sign::New(const FunctionCallbackInfo<Value>& args) {
41694201
}
41704202

41714203

4172-
SignBase::Error Sign::SignInit(const char* sign_type) {
4173-
CHECK_EQ(initialised_, false);
4174-
const EVP_MD* md = EVP_get_digestbyname(sign_type);
4175-
if (md == nullptr)
4176-
return kSignUnknownDigest;
4177-
4178-
EVP_MD_CTX_init(&mdctx_);
4179-
if (!EVP_DigestInit_ex(&mdctx_, md, nullptr))
4180-
return kSignInit;
4181-
initialised_ = true;
4182-
4183-
return kSignOk;
4184-
}
4185-
4186-
41874204
void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
41884205
Sign* sign;
41894206
ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
@@ -4196,16 +4213,7 @@ void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
41964213
THROW_AND_RETURN_IF_NOT_STRING(args[0], "Sign type");
41974214

41984215
const node::Utf8Value sign_type(args.GetIsolate(), args[0]);
4199-
sign->CheckThrow(sign->SignInit(*sign_type));
4200-
}
4201-
4202-
4203-
SignBase::Error Sign::SignUpdate(const char* data, int len) {
4204-
if (!initialised_)
4205-
return kSignNotInitialised;
4206-
if (!EVP_DigestUpdate(&mdctx_, data, len))
4207-
return kSignUpdate;
4208-
return kSignOk;
4216+
sign->CheckThrow(sign->Init(*sign_type));
42094217
}
42104218

42114219

@@ -4223,11 +4231,11 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
42234231
StringBytes::InlineDecoder decoder;
42244232
if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8))
42254233
return;
4226-
err = sign->SignUpdate(decoder.out(), decoder.size());
4234+
err = sign->Update(decoder.out(), decoder.size());
42274235
} else {
42284236
char* buf = Buffer::Data(args[0]);
42294237
size_t buflen = Buffer::Length(args[0]);
4230-
err = sign->SignUpdate(buf, buflen);
4238+
err = sign->Update(buf, buflen);
42314239
}
42324240

42334241
sign->CheckThrow(err);
@@ -4271,7 +4279,7 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
42714279
unsigned int* sig_len,
42724280
int padding,
42734281
int salt_len) {
4274-
if (!initialised_)
4282+
if (!mdctx_)
42754283
return kSignNotInitialised;
42764284

42774285
BIO* bp = nullptr;
@@ -4316,18 +4324,17 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
43164324
}
43174325
#endif // NODE_FIPS_MODE
43184326

4319-
if (Node_SignFinal(&mdctx_, sig, sig_len, pkey, padding, salt_len))
4327+
if (Node_SignFinal(mdctx_, sig, sig_len, pkey, padding, salt_len))
43204328
fatal = false;
43214329

4322-
initialised_ = false;
4323-
43244330
exit:
43254331
if (pkey != nullptr)
43264332
EVP_PKEY_free(pkey);
43274333
if (bp != nullptr)
43284334
BIO_free_all(bp);
43294335

4330-
EVP_MD_CTX_cleanup(&mdctx_);
4336+
EVP_MD_CTX_free(mdctx_);
4337+
mdctx_ = nullptr;
43314338

43324339
if (fatal)
43334340
return kSignPrivateKey;
@@ -4402,21 +4409,6 @@ void Verify::New(const FunctionCallbackInfo<Value>& args) {
44024409
}
44034410

44044411

4405-
SignBase::Error Verify::VerifyInit(const char* verify_type) {
4406-
CHECK_EQ(initialised_, false);
4407-
const EVP_MD* md = EVP_get_digestbyname(verify_type);
4408-
if (md == nullptr)
4409-
return kSignUnknownDigest;
4410-
4411-
EVP_MD_CTX_init(&mdctx_);
4412-
if (!EVP_DigestInit_ex(&mdctx_, md, nullptr))
4413-
return kSignInit;
4414-
initialised_ = true;
4415-
4416-
return kSignOk;
4417-
}
4418-
4419-
44204412
void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
44214413
Verify* verify;
44224414
ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
@@ -4429,18 +4421,7 @@ void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
44294421
THROW_AND_RETURN_IF_NOT_STRING(args[0], "Verify type");
44304422

44314423
const node::Utf8Value verify_type(args.GetIsolate(), args[0]);
4432-
verify->CheckThrow(verify->VerifyInit(*verify_type));
4433-
}
4434-
4435-
4436-
SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
4437-
if (!initialised_)
4438-
return kSignNotInitialised;
4439-
4440-
if (!EVP_DigestUpdate(&mdctx_, data, len))
4441-
return kSignUpdate;
4442-
4443-
return kSignOk;
4424+
verify->CheckThrow(verify->Init(*verify_type));
44444425
}
44454426

44464427

@@ -4458,11 +4439,11 @@ void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
44584439
StringBytes::InlineDecoder decoder;
44594440
if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8))
44604441
return;
4461-
err = verify->VerifyUpdate(decoder.out(), decoder.size());
4442+
err = verify->Update(decoder.out(), decoder.size());
44624443
} else {
44634444
char* buf = Buffer::Data(args[0]);
44644445
size_t buflen = Buffer::Length(args[0]);
4465-
err = verify->VerifyUpdate(buf, buflen);
4446+
err = verify->Update(buf, buflen);
44664447
}
44674448

44684449
verify->CheckThrow(err);
@@ -4476,7 +4457,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
44764457
int padding,
44774458
int saltlen,
44784459
bool* verify_result) {
4479-
if (!initialised_)
4460+
if (!mdctx_)
44804461
return kSignNotInitialised;
44814462

44824463
EVP_PKEY* pkey = nullptr;
@@ -4521,7 +4502,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
45214502
goto exit;
45224503
}
45234504

4524-
if (!EVP_DigestFinal_ex(&mdctx_, m, &m_len)) {
4505+
if (!EVP_DigestFinal_ex(mdctx_, m, &m_len)) {
45254506
goto exit;
45264507
}
45274508

@@ -4534,7 +4515,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
45344515
goto err;
45354516
if (!ApplyRSAOptions(pkey, pkctx, padding, saltlen))
45364517
goto err;
4537-
if (EVP_PKEY_CTX_set_signature_md(pkctx, mdctx_.digest) <= 0)
4518+
if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(mdctx_)) <= 0)
45384519
goto err;
45394520
r = EVP_PKEY_verify(pkctx,
45404521
reinterpret_cast<const unsigned char*>(sig),
@@ -4553,8 +4534,8 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
45534534
if (x509 != nullptr)
45544535
X509_free(x509);
45554536

4556-
EVP_MD_CTX_cleanup(&mdctx_);
4557-
initialised_ = false;
4537+
EVP_MD_CTX_free(mdctx_);
4538+
mdctx_ = nullptr;
45584539

45594540
if (fatal)
45604541
return kSignPublicKey;

src/node_crypto.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -562,28 +562,24 @@ class SignBase : public BaseObject {
562562

563563
SignBase(Environment* env, v8::Local<v8::Object> wrap)
564564
: BaseObject(env, wrap),
565-
initialised_(false) {
565+
mdctx_(nullptr) {
566566
}
567567

568-
~SignBase() override {
569-
if (!initialised_)
570-
return;
571-
EVP_MD_CTX_cleanup(&mdctx_);
572-
}
568+
~SignBase() override;
569+
570+
Error Init(const char* sign_type);
571+
Error Update(const char* data, int len);
573572

574573
protected:
575574
void CheckThrow(Error error);
576575

577-
EVP_MD_CTX mdctx_; /* coverity[member_decl] */
578-
bool initialised_;
576+
EVP_MD_CTX* mdctx_;
579577
};
580578

581579
class Sign : public SignBase {
582580
public:
583581
static void Initialize(Environment* env, v8::Local<v8::Object> target);
584582

585-
Error SignInit(const char* sign_type);
586-
Error SignUpdate(const char* data, int len);
587583
Error SignFinal(const char* key_pem,
588584
int key_pem_len,
589585
const char* passphrase,
@@ -607,8 +603,6 @@ class Verify : public SignBase {
607603
public:
608604
static void Initialize(Environment* env, v8::Local<v8::Object> target);
609605

610-
Error VerifyInit(const char* verify_type);
611-
Error VerifyUpdate(const char* data, int len);
612606
Error VerifyFinal(const char* key_pem,
613607
int key_pem_len,
614608
const char* sig,

0 commit comments

Comments
 (0)