Skip to content

Commit e0cbc39

Browse files
davidbengibfahn
authored andcommitted
crypto: make CipherBase 1.1.0-compatible
In OpenSSL 1.1.0, EVP_CIPHER_CTX must be heap-allocated. Once we're heap-allocating them, there's no need in a separate initialised_ bit. The presence of ctx_ is sufficient. PR-URL: #16130 Backport-PR-URL: #18622 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
1 parent e210798 commit e0cbc39

File tree

2 files changed

+39
-44
lines changed

2 files changed

+39
-44
lines changed

src/node_crypto.cc

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3457,7 +3457,7 @@ void CipherBase::Init(const char* cipher_type,
34573457
}
34583458
#endif // NODE_FIPS_MODE
34593459

3460-
CHECK_EQ(initialised_, false);
3460+
CHECK_EQ(ctx_, nullptr);
34613461
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
34623462
if (cipher == nullptr) {
34633463
return env()->ThrowError("Unknown cipher");
@@ -3475,29 +3475,28 @@ void CipherBase::Init(const char* cipher_type,
34753475
key,
34763476
iv);
34773477

3478-
EVP_CIPHER_CTX_init(&ctx_);
3478+
ctx_ = EVP_CIPHER_CTX_new();
34793479
const bool encrypt = (kind_ == kCipher);
3480-
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
3480+
EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
34813481

3482-
int mode = EVP_CIPHER_CTX_mode(&ctx_);
3482+
int mode = EVP_CIPHER_CTX_mode(ctx_);
34833483
if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE ||
34843484
mode == EVP_CIPH_CCM_MODE)) {
34853485
ProcessEmitWarning(env(), "Use Cipheriv for counter mode of %s",
34863486
cipher_type);
34873487
}
34883488

34893489
if (mode == EVP_CIPH_WRAP_MODE)
3490-
EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3490+
EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
34913491

3492-
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(&ctx_, key_len));
3492+
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(ctx_, key_len));
34933493

3494-
EVP_CipherInit_ex(&ctx_,
3494+
EVP_CipherInit_ex(ctx_,
34953495
nullptr,
34963496
nullptr,
34973497
reinterpret_cast<unsigned char*>(key),
34983498
reinterpret_cast<unsigned char*>(iv),
34993499
kind_ == kCipher);
3500-
initialised_ = true;
35013500
}
35023501

35033502

@@ -3540,32 +3539,33 @@ void CipherBase::InitIv(const char* cipher_type,
35403539
return env()->ThrowError("Invalid IV length");
35413540
}
35423541

3543-
EVP_CIPHER_CTX_init(&ctx_);
3542+
ctx_ = EVP_CIPHER_CTX_new();
35443543

35453544
if (mode == EVP_CIPH_WRAP_MODE)
3546-
EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3545+
EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
35473546

35483547
const bool encrypt = (kind_ == kCipher);
3549-
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
3548+
EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
35503549

35513550
if (is_gcm_mode &&
3552-
!EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
3553-
EVP_CIPHER_CTX_cleanup(&ctx_);
3551+
!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
3552+
EVP_CIPHER_CTX_free(ctx_);
3553+
ctx_ = nullptr;
35543554
return env()->ThrowError("Invalid IV length");
35553555
}
35563556

3557-
if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
3558-
EVP_CIPHER_CTX_cleanup(&ctx_);
3557+
if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
3558+
EVP_CIPHER_CTX_free(ctx_);
3559+
ctx_ = nullptr;
35593560
return env()->ThrowError("Invalid key length");
35603561
}
35613562

3562-
EVP_CipherInit_ex(&ctx_,
3563+
EVP_CipherInit_ex(ctx_,
35633564
nullptr,
35643565
nullptr,
35653566
reinterpret_cast<const unsigned char*>(key),
35663567
reinterpret_cast<const unsigned char*>(iv),
35673568
kind_ == kCipher);
3568-
initialised_ = true;
35693569
}
35703570

35713571

@@ -3593,8 +3593,8 @@ void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
35933593

35943594
bool CipherBase::IsAuthenticatedMode() const {
35953595
// Check if this cipher operates in an AEAD mode that we support.
3596-
CHECK_EQ(initialised_, true);
3597-
const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(&ctx_);
3596+
CHECK_NE(ctx_, nullptr);
3597+
const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(ctx_);
35983598
int mode = EVP_CIPHER_mode(cipher);
35993599
return mode == EVP_CIPH_GCM_MODE;
36003600
}
@@ -3606,7 +3606,7 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
36063606
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
36073607

36083608
// Only callable after Final and if encrypting.
3609-
if (cipher->initialised_ ||
3609+
if (cipher->ctx_ != nullptr ||
36103610
cipher->kind_ != kCipher ||
36113611
cipher->auth_tag_len_ == 0) {
36123612
return env->ThrowError("Attempting to get auth tag in unsupported state");
@@ -3627,7 +3627,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
36273627
CipherBase* cipher;
36283628
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
36293629

3630-
if (!cipher->initialised_ ||
3630+
if (cipher->ctx_ == nullptr ||
36313631
!cipher->IsAuthenticatedMode() ||
36323632
cipher->kind_ != kDecipher) {
36333633
return env->ThrowError("Attempting to set auth tag in unsupported state");
@@ -3653,10 +3653,10 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
36533653

36543654

36553655
bool CipherBase::SetAAD(const char* data, unsigned int len) {
3656-
if (!initialised_ || !IsAuthenticatedMode())
3656+
if (ctx_ == nullptr || !IsAuthenticatedMode())
36573657
return false;
36583658
int outlen;
3659-
if (!EVP_CipherUpdate(&ctx_,
3659+
if (!EVP_CipherUpdate(ctx_,
36603660
nullptr,
36613661
&outlen,
36623662
reinterpret_cast<const unsigned char*>(data),
@@ -3684,21 +3684,21 @@ bool CipherBase::Update(const char* data,
36843684
int len,
36853685
unsigned char** out,
36863686
int* out_len) {
3687-
if (!initialised_)
3687+
if (ctx_ == nullptr)
36883688
return 0;
36893689

36903690
// on first update:
36913691
if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_len_ > 0) {
3692-
EVP_CIPHER_CTX_ctrl(&ctx_,
3692+
EVP_CIPHER_CTX_ctrl(ctx_,
36933693
EVP_CTRL_GCM_SET_TAG,
36943694
auth_tag_len_,
36953695
reinterpret_cast<unsigned char*>(auth_tag_));
36963696
auth_tag_len_ = 0;
36973697
}
36983698

3699-
*out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
3699+
*out_len = len + EVP_CIPHER_CTX_block_size(ctx_);
37003700
*out = Malloc<unsigned char>(static_cast<size_t>(*out_len));
3701-
return EVP_CipherUpdate(&ctx_,
3701+
return EVP_CipherUpdate(ctx_,
37023702
*out,
37033703
out_len,
37043704
reinterpret_cast<const unsigned char*>(data),
@@ -3746,9 +3746,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
37463746

37473747

37483748
bool CipherBase::SetAutoPadding(bool auto_padding) {
3749-
if (!initialised_)
3749+
if (ctx_ == nullptr)
37503750
return false;
3751-
return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
3751+
return EVP_CIPHER_CTX_set_padding(ctx_, auto_padding);
37523752
}
37533753

37543754

@@ -3764,22 +3764,22 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
37643764

37653765

37663766
bool CipherBase::Final(unsigned char** out, int *out_len) {
3767-
if (!initialised_)
3767+
if (ctx_ == nullptr)
37683768
return false;
37693769

37703770
*out = Malloc<unsigned char>(
3771-
static_cast<size_t>(EVP_CIPHER_CTX_block_size(&ctx_)));
3772-
int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
3771+
static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_)));
3772+
int r = EVP_CipherFinal_ex(ctx_, *out, out_len);
37733773

37743774
if (r == 1 && kind_ == kCipher && IsAuthenticatedMode()) {
37753775
auth_tag_len_ = sizeof(auth_tag_);
3776-
r = EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
3776+
r = EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
37773777
reinterpret_cast<unsigned char*>(auth_tag_));
37783778
CHECK_EQ(r, 1);
37793779
}
37803780

3781-
EVP_CIPHER_CTX_cleanup(&ctx_);
3782-
initialised_ = false;
3781+
EVP_CIPHER_CTX_free(ctx_);
3782+
ctx_ = nullptr;
37833783

37843784
return r == 1;
37853785
}
@@ -3790,7 +3790,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
37903790

37913791
CipherBase* cipher;
37923792
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3793-
if (!cipher->initialised_) return env->ThrowError("Unsupported state");
3793+
if (cipher->ctx_ == nullptr) return env->ThrowError("Unsupported state");
37943794

37953795
unsigned char* out_value = nullptr;
37963796
int out_len = -1;

src/node_crypto.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@
5151
#include <openssl/rand.h>
5252
#include <openssl/pkcs12.h>
5353

54-
#define EVP_F_EVP_DECRYPTFINAL 101
55-
5654
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
5755
# define NODE__HAVE_TLSEXT_STATUS_CB
5856
#endif // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
@@ -442,9 +440,7 @@ class Connection : public AsyncWrap, public SSLWrap<Connection> {
442440
class CipherBase : public BaseObject {
443441
public:
444442
~CipherBase() override {
445-
if (!initialised_)
446-
return;
447-
EVP_CIPHER_CTX_cleanup(&ctx_);
443+
EVP_CIPHER_CTX_free(ctx_);
448444
}
449445

450446
static void Initialize(Environment* env, v8::Local<v8::Object> target);
@@ -483,15 +479,14 @@ class CipherBase : public BaseObject {
483479
v8::Local<v8::Object> wrap,
484480
CipherKind kind)
485481
: BaseObject(env, wrap),
486-
initialised_(false),
482+
ctx_(nullptr),
487483
kind_(kind),
488484
auth_tag_len_(0) {
489485
MakeWeak<CipherBase>(this);
490486
}
491487

492488
private:
493-
EVP_CIPHER_CTX ctx_; /* coverity[member_decl] */
494-
bool initialised_;
489+
EVP_CIPHER_CTX* ctx_;
495490
const CipherKind kind_;
496491
unsigned int auth_tag_len_;
497492
char auth_tag_[EVP_GCM_TLS_TAG_LEN];

0 commit comments

Comments
 (0)