Skip to content

Commit db65422

Browse files
bnoordhuisaddaleax
authored andcommitted
src: remove superfluous cipher_ data member
The EVP_CIPHER can be reconstructed from the EVP_CIPHER_CTX instance, no need to store it separately. This brought to light the somewhat dubious practice of accessing the EVP_CIPHER after the EVP_CIPHER_CTX instance had been destroyed. It's mostly harmless due to the static nature of built-in EVP_CIPHER instances but it segfaults when the cipher is provided by an ENGINE and the ENGINE is unloaded because its reference count drops to zero. PR-URL: #14122 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 1af064b commit db65422

File tree

2 files changed

+18
-17
lines changed

2 files changed

+18
-17
lines changed

src/node_crypto.cc

+18-15
Original file line numberDiff line numberDiff line change
@@ -3332,16 +3332,16 @@ void CipherBase::Init(const char* cipher_type,
33323332
}
33333333
#endif // NODE_FIPS_MODE
33343334

3335-
CHECK_EQ(cipher_, nullptr);
3336-
cipher_ = EVP_get_cipherbyname(cipher_type);
3337-
if (cipher_ == nullptr) {
3335+
CHECK_EQ(initialised_, false);
3336+
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
3337+
if (cipher == nullptr) {
33383338
return env()->ThrowError("Unknown cipher");
33393339
}
33403340

33413341
unsigned char key[EVP_MAX_KEY_LENGTH];
33423342
unsigned char iv[EVP_MAX_IV_LENGTH];
33433343

3344-
int key_len = EVP_BytesToKey(cipher_,
3344+
int key_len = EVP_BytesToKey(cipher,
33453345
EVP_md5(),
33463346
nullptr,
33473347
reinterpret_cast<const unsigned char*>(key_buf),
@@ -3352,7 +3352,7 @@ void CipherBase::Init(const char* cipher_type,
33523352

33533353
EVP_CIPHER_CTX_init(&ctx_);
33543354
const bool encrypt = (kind_ == kCipher);
3355-
EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
3355+
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
33563356
if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
33573357
EVP_CIPHER_CTX_cleanup(&ctx_);
33583358
return env()->ThrowError("Invalid key length");
@@ -3394,21 +3394,21 @@ void CipherBase::InitIv(const char* cipher_type,
33943394
int iv_len) {
33953395
HandleScope scope(env()->isolate());
33963396

3397-
cipher_ = EVP_get_cipherbyname(cipher_type);
3398-
if (cipher_ == nullptr) {
3397+
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
3398+
if (cipher == nullptr) {
33993399
return env()->ThrowError("Unknown cipher");
34003400
}
34013401

3402-
const int expected_iv_len = EVP_CIPHER_iv_length(cipher_);
3403-
const bool is_gcm_mode = (EVP_CIPH_GCM_MODE == EVP_CIPHER_mode(cipher_));
3402+
const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
3403+
const bool is_gcm_mode = (EVP_CIPH_GCM_MODE == EVP_CIPHER_mode(cipher));
34043404

34053405
if (is_gcm_mode == false && iv_len != expected_iv_len) {
34063406
return env()->ThrowError("Invalid IV length");
34073407
}
34083408

34093409
EVP_CIPHER_CTX_init(&ctx_);
34103410
const bool encrypt = (kind_ == kCipher);
3411-
EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt);
3411+
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
34123412

34133413
if (is_gcm_mode &&
34143414
!EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
@@ -3454,10 +3454,10 @@ void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
34543454

34553455

34563456
bool CipherBase::IsAuthenticatedMode() const {
3457-
// check if this cipher operates in an AEAD mode that we support.
3458-
if (!cipher_)
3459-
return false;
3460-
int mode = EVP_CIPHER_mode(cipher_);
3457+
// Check if this cipher operates in an AEAD mode that we support.
3458+
CHECK_EQ(initialised_, true);
3459+
const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(&ctx_);
3460+
int mode = EVP_CIPHER_mode(cipher);
34613461
return mode == EVP_CIPH_GCM_MODE;
34623462
}
34633463

@@ -3644,19 +3644,22 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
36443644

36453645
CipherBase* cipher;
36463646
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3647+
if (!cipher->initialised_) return env->ThrowError("Unsupported state");
36473648

36483649
unsigned char* out_value = nullptr;
36493650
int out_len = -1;
36503651
Local<Value> outString;
36513652

3653+
// Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
3654+
const bool is_auth_mode = cipher->IsAuthenticatedMode();
36523655
bool r = cipher->Final(&out_value, &out_len);
36533656

36543657
if (out_len <= 0 || !r) {
36553658
free(out_value);
36563659
out_value = nullptr;
36573660
out_len = 0;
36583661
if (!r) {
3659-
const char* msg = cipher->IsAuthenticatedMode() ?
3662+
const char* msg = is_auth_mode ?
36603663
"Unsupported state or unable to authenticate data" :
36613664
"Unsupported state";
36623665

src/node_crypto.h

-2
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,6 @@ class CipherBase : public BaseObject {
467467
v8::Local<v8::Object> wrap,
468468
CipherKind kind)
469469
: BaseObject(env, wrap),
470-
cipher_(nullptr),
471470
initialised_(false),
472471
kind_(kind),
473472
auth_tag_len_(0) {
@@ -476,7 +475,6 @@ class CipherBase : public BaseObject {
476475

477476
private:
478477
EVP_CIPHER_CTX ctx_; /* coverity[member_decl] */
479-
const EVP_CIPHER* cipher_; /* coverity[member_decl] */
480478
bool initialised_;
481479
CipherKind kind_;
482480
unsigned int auth_tag_len_;

0 commit comments

Comments
 (0)