Skip to content

Commit 59acd27

Browse files
davidbenevanlucas
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 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
1 parent 6c3ae36 commit 59acd27

File tree

2 files changed

+39
-44
lines changed

2 files changed

+39
-44
lines changed

src/node_crypto.cc

+36-36
Original file line numberDiff line numberDiff line change
@@ -3461,7 +3461,7 @@ void CipherBase::Init(const char* cipher_type,
34613461
}
34623462
#endif // NODE_FIPS_MODE
34633463

3464-
CHECK_EQ(initialised_, false);
3464+
CHECK_EQ(ctx_, nullptr);
34653465
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
34663466
if (cipher == nullptr) {
34673467
return env()->ThrowError("Unknown cipher");
@@ -3479,29 +3479,28 @@ void CipherBase::Init(const char* cipher_type,
34793479
key,
34803480
iv);
34813481

3482-
EVP_CIPHER_CTX_init(&ctx_);
3482+
ctx_ = EVP_CIPHER_CTX_new();
34833483
const bool encrypt = (kind_ == kCipher);
3484-
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
3484+
EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
34853485

3486-
int mode = EVP_CIPHER_CTX_mode(&ctx_);
3486+
int mode = EVP_CIPHER_CTX_mode(ctx_);
34873487
if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE ||
34883488
mode == EVP_CIPH_CCM_MODE)) {
34893489
ProcessEmitWarning(env(), "Use Cipheriv for counter mode of %s",
34903490
cipher_type);
34913491
}
34923492

34933493
if (mode == EVP_CIPH_WRAP_MODE)
3494-
EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3494+
EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
34953495

3496-
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(&ctx_, key_len));
3496+
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(ctx_, key_len));
34973497

3498-
EVP_CipherInit_ex(&ctx_,
3498+
EVP_CipherInit_ex(ctx_,
34993499
nullptr,
35003500
nullptr,
35013501
reinterpret_cast<unsigned char*>(key),
35023502
reinterpret_cast<unsigned char*>(iv),
35033503
kind_ == kCipher);
3504-
initialised_ = true;
35053504
}
35063505

35073506

@@ -3544,32 +3543,33 @@ void CipherBase::InitIv(const char* cipher_type,
35443543
return env()->ThrowError("Invalid IV length");
35453544
}
35463545

3547-
EVP_CIPHER_CTX_init(&ctx_);
3546+
ctx_ = EVP_CIPHER_CTX_new();
35483547

35493548
if (mode == EVP_CIPH_WRAP_MODE)
3550-
EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3549+
EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
35513550

35523551
const bool encrypt = (kind_ == kCipher);
3553-
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
3552+
EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
35543553

35553554
if (is_gcm_mode &&
3556-
!EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
3557-
EVP_CIPHER_CTX_cleanup(&ctx_);
3555+
!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
3556+
EVP_CIPHER_CTX_free(ctx_);
3557+
ctx_ = nullptr;
35583558
return env()->ThrowError("Invalid IV length");
35593559
}
35603560

3561-
if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
3562-
EVP_CIPHER_CTX_cleanup(&ctx_);
3561+
if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
3562+
EVP_CIPHER_CTX_free(ctx_);
3563+
ctx_ = nullptr;
35633564
return env()->ThrowError("Invalid key length");
35643565
}
35653566

3566-
EVP_CipherInit_ex(&ctx_,
3567+
EVP_CipherInit_ex(ctx_,
35673568
nullptr,
35683569
nullptr,
35693570
reinterpret_cast<const unsigned char*>(key),
35703571
reinterpret_cast<const unsigned char*>(iv),
35713572
kind_ == kCipher);
3572-
initialised_ = true;
35733573
}
35743574

35753575

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

35983598
bool CipherBase::IsAuthenticatedMode() const {
35993599
// Check if this cipher operates in an AEAD mode that we support.
3600-
CHECK_EQ(initialised_, true);
3601-
const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(&ctx_);
3600+
CHECK_NE(ctx_, nullptr);
3601+
const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(ctx_);
36023602
int mode = EVP_CIPHER_mode(cipher);
36033603
return mode == EVP_CIPH_GCM_MODE;
36043604
}
@@ -3610,7 +3610,7 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
36103610
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
36113611

36123612
// Only callable after Final and if encrypting.
3613-
if (cipher->initialised_ ||
3613+
if (cipher->ctx_ != nullptr ||
36143614
cipher->kind_ != kCipher ||
36153615
cipher->auth_tag_len_ == 0) {
36163616
return env->ThrowError("Attempting to get auth tag in unsupported state");
@@ -3631,7 +3631,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
36313631
CipherBase* cipher;
36323632
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
36333633

3634-
if (!cipher->initialised_ ||
3634+
if (cipher->ctx_ == nullptr ||
36353635
!cipher->IsAuthenticatedMode() ||
36363636
cipher->kind_ != kDecipher) {
36373637
return env->ThrowError("Attempting to set auth tag in unsupported state");
@@ -3649,10 +3649,10 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
36493649

36503650

36513651
bool CipherBase::SetAAD(const char* data, unsigned int len) {
3652-
if (!initialised_ || !IsAuthenticatedMode())
3652+
if (ctx_ == nullptr || !IsAuthenticatedMode())
36533653
return false;
36543654
int outlen;
3655-
if (!EVP_CipherUpdate(&ctx_,
3655+
if (!EVP_CipherUpdate(ctx_,
36563656
nullptr,
36573657
&outlen,
36583658
reinterpret_cast<const unsigned char*>(data),
@@ -3680,21 +3680,21 @@ bool CipherBase::Update(const char* data,
36803680
int len,
36813681
unsigned char** out,
36823682
int* out_len) {
3683-
if (!initialised_)
3683+
if (ctx_ == nullptr)
36843684
return 0;
36853685

36863686
// on first update:
36873687
if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_len_ > 0) {
3688-
EVP_CIPHER_CTX_ctrl(&ctx_,
3688+
EVP_CIPHER_CTX_ctrl(ctx_,
36893689
EVP_CTRL_GCM_SET_TAG,
36903690
auth_tag_len_,
36913691
reinterpret_cast<unsigned char*>(auth_tag_));
36923692
auth_tag_len_ = 0;
36933693
}
36943694

3695-
*out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
3695+
*out_len = len + EVP_CIPHER_CTX_block_size(ctx_);
36963696
*out = Malloc<unsigned char>(static_cast<size_t>(*out_len));
3697-
return EVP_CipherUpdate(&ctx_,
3697+
return EVP_CipherUpdate(ctx_,
36983698
*out,
36993699
out_len,
37003700
reinterpret_cast<const unsigned char*>(data),
@@ -3742,9 +3742,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
37423742

37433743

37443744
bool CipherBase::SetAutoPadding(bool auto_padding) {
3745-
if (!initialised_)
3745+
if (ctx_ == nullptr)
37463746
return false;
3747-
return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
3747+
return EVP_CIPHER_CTX_set_padding(ctx_, auto_padding);
37483748
}
37493749

37503750

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

37613761

37623762
bool CipherBase::Final(unsigned char** out, int *out_len) {
3763-
if (!initialised_)
3763+
if (ctx_ == nullptr)
37643764
return false;
37653765

37663766
*out = Malloc<unsigned char>(
3767-
static_cast<size_t>(EVP_CIPHER_CTX_block_size(&ctx_)));
3768-
int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
3767+
static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_)));
3768+
int r = EVP_CipherFinal_ex(ctx_, *out, out_len);
37693769

37703770
if (r == 1 && kind_ == kCipher && IsAuthenticatedMode()) {
37713771
auth_tag_len_ = sizeof(auth_tag_);
3772-
r = EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
3772+
r = EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
37733773
reinterpret_cast<unsigned char*>(auth_tag_));
37743774
CHECK_EQ(r, 1);
37753775
}
37763776

3777-
EVP_CIPHER_CTX_cleanup(&ctx_);
3778-
initialised_ = false;
3777+
EVP_CIPHER_CTX_free(ctx_);
3778+
ctx_ = nullptr;
37793779

37803780
return r == 1;
37813781
}
@@ -3786,7 +3786,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
37863786

37873787
CipherBase* cipher;
37883788
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3789-
if (!cipher->initialised_) return env->ThrowError("Unsupported state");
3789+
if (cipher->ctx_ == nullptr) return env->ThrowError("Unsupported state");
37903790

37913791
unsigned char* out_value = nullptr;
37923792
int out_len = -1;

src/node_crypto.h

+3-8
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)