Skip to content

Commit 146e8f8

Browse files
davidbenrvagg
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: nodejs#16130 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
1 parent 706ad8f commit 146e8f8

2 files changed

Lines changed: 39 additions & 44 deletions

File tree

src/node_crypto.cc

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3454,7 +3454,7 @@ void CipherBase::Init(const char* cipher_type,
34543454
}
34553455
#endif // NODE_FIPS_MODE
34563456

3457-
CHECK_EQ(initialised_, false);
3457+
CHECK_EQ(ctx_, nullptr);
34583458
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
34593459
if (cipher == nullptr) {
34603460
return env()->ThrowError("Unknown cipher");
@@ -3472,29 +3472,28 @@ void CipherBase::Init(const char* cipher_type,
34723472
key,
34733473
iv);
34743474

3475-
EVP_CIPHER_CTX_init(&ctx_);
3475+
ctx_ = EVP_CIPHER_CTX_new();
34763476
const bool encrypt = (kind_ == kCipher);
3477-
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
3477+
EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
34783478

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

34863486
if (mode == EVP_CIPH_WRAP_MODE)
3487-
EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3487+
EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
34883488

3489-
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(&ctx_, key_len));
3489+
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(ctx_, key_len));
34903490

3491-
EVP_CipherInit_ex(&ctx_,
3491+
EVP_CipherInit_ex(ctx_,
34923492
nullptr,
34933493
nullptr,
34943494
reinterpret_cast<unsigned char*>(key),
34953495
reinterpret_cast<unsigned char*>(iv),
34963496
kind_ == kCipher);
3497-
initialised_ = true;
34983497
}
34993498

35003499

@@ -3531,32 +3530,33 @@ void CipherBase::InitIv(const char* cipher_type,
35313530
return env()->ThrowError("Invalid IV length");
35323531
}
35333532

3534-
EVP_CIPHER_CTX_init(&ctx_);
3533+
ctx_ = EVP_CIPHER_CTX_new();
35353534

35363535
if (mode == EVP_CIPH_WRAP_MODE)
3537-
EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
3536+
EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
35383537

35393538
const bool encrypt = (kind_ == kCipher);
3540-
EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
3539+
EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
35413540

35423541
if (is_gcm_mode &&
3543-
!EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
3544-
EVP_CIPHER_CTX_cleanup(&ctx_);
3542+
!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
3543+
EVP_CIPHER_CTX_free(ctx_);
3544+
ctx_ = nullptr;
35453545
return env()->ThrowError("Invalid IV length");
35463546
}
35473547

3548-
if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
3549-
EVP_CIPHER_CTX_cleanup(&ctx_);
3548+
if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
3549+
EVP_CIPHER_CTX_free(ctx_);
3550+
ctx_ = nullptr;
35503551
return env()->ThrowError("Invalid key length");
35513552
}
35523553

3553-
EVP_CipherInit_ex(&ctx_,
3554+
EVP_CipherInit_ex(ctx_,
35543555
nullptr,
35553556
nullptr,
35563557
reinterpret_cast<const unsigned char*>(key),
35573558
reinterpret_cast<const unsigned char*>(iv),
35583559
kind_ == kCipher);
3559-
initialised_ = true;
35603560
}
35613561

35623562

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

35793579
bool CipherBase::IsAuthenticatedMode() const {
35803580
// Check if this cipher operates in an AEAD mode that we support.
3581-
CHECK_EQ(initialised_, true);
3582-
const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(&ctx_);
3581+
CHECK_NE(ctx_, nullptr);
3582+
const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(ctx_);
35833583
int mode = EVP_CIPHER_mode(cipher);
35843584
return mode == EVP_CIPH_GCM_MODE;
35853585
}
@@ -3591,7 +3591,7 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
35913591
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
35923592

35933593
// Only callable after Final and if encrypting.
3594-
if (cipher->initialised_ ||
3594+
if (cipher->ctx_ != nullptr ||
35953595
cipher->kind_ != kCipher ||
35963596
cipher->auth_tag_len_ == 0) {
35973597
return args.GetReturnValue().SetUndefined();
@@ -3608,7 +3608,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
36083608
CipherBase* cipher;
36093609
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
36103610

3611-
if (!cipher->initialised_ ||
3611+
if (cipher->ctx_ == nullptr ||
36123612
!cipher->IsAuthenticatedMode() ||
36133613
cipher->kind_ != kDecipher) {
36143614
return args.GetReturnValue().Set(false);
@@ -3626,10 +3626,10 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
36263626

36273627

36283628
bool CipherBase::SetAAD(const char* data, unsigned int len) {
3629-
if (!initialised_ || !IsAuthenticatedMode())
3629+
if (ctx_ == nullptr || !IsAuthenticatedMode())
36303630
return false;
36313631
int outlen;
3632-
if (!EVP_CipherUpdate(&ctx_,
3632+
if (!EVP_CipherUpdate(ctx_,
36333633
nullptr,
36343634
&outlen,
36353635
reinterpret_cast<const unsigned char*>(data),
@@ -3653,21 +3653,21 @@ bool CipherBase::Update(const char* data,
36533653
int len,
36543654
unsigned char** out,
36553655
int* out_len) {
3656-
if (!initialised_)
3656+
if (ctx_ == nullptr)
36573657
return 0;
36583658

36593659
// on first update:
36603660
if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_len_ > 0) {
3661-
EVP_CIPHER_CTX_ctrl(&ctx_,
3661+
EVP_CIPHER_CTX_ctrl(ctx_,
36623662
EVP_CTRL_GCM_SET_TAG,
36633663
auth_tag_len_,
36643664
reinterpret_cast<unsigned char*>(auth_tag_));
36653665
auth_tag_len_ = 0;
36663666
}
36673667

3668-
*out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
3668+
*out_len = len + EVP_CIPHER_CTX_block_size(ctx_);
36693669
*out = Malloc<unsigned char>(static_cast<size_t>(*out_len));
3670-
return EVP_CipherUpdate(&ctx_,
3670+
return EVP_CipherUpdate(ctx_,
36713671
*out,
36723672
out_len,
36733673
reinterpret_cast<const unsigned char*>(data),
@@ -3713,9 +3713,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
37133713

37143714

37153715
bool CipherBase::SetAutoPadding(bool auto_padding) {
3716-
if (!initialised_)
3716+
if (ctx_ == nullptr)
37173717
return false;
3718-
return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
3718+
return EVP_CIPHER_CTX_set_padding(ctx_, auto_padding);
37193719
}
37203720

37213721

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

37303730

37313731
bool CipherBase::Final(unsigned char** out, int *out_len) {
3732-
if (!initialised_)
3732+
if (ctx_ == nullptr)
37333733
return false;
37343734

37353735
*out = Malloc<unsigned char>(
3736-
static_cast<size_t>(EVP_CIPHER_CTX_block_size(&ctx_)));
3737-
int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
3736+
static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_)));
3737+
int r = EVP_CipherFinal_ex(ctx_, *out, out_len);
37383738

37393739
if (r == 1 && kind_ == kCipher && IsAuthenticatedMode()) {
37403740
auth_tag_len_ = sizeof(auth_tag_);
3741-
r = EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
3741+
r = EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
37423742
reinterpret_cast<unsigned char*>(auth_tag_));
37433743
CHECK_EQ(r, 1);
37443744
}
37453745

3746-
EVP_CIPHER_CTX_cleanup(&ctx_);
3747-
initialised_ = false;
3746+
EVP_CIPHER_CTX_free(ctx_);
3747+
ctx_ = nullptr;
37483748

37493749
return r == 1;
37503750
}
@@ -3755,7 +3755,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
37553755

37563756
CipherBase* cipher;
37573757
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3758-
if (!cipher->initialised_) return env->ThrowError("Unsupported state");
3758+
if (cipher->ctx_ == nullptr) return env->ThrowError("Unsupported state");
37593759

37603760
unsigned char* out_value = nullptr;
37613761
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)