Skip to content

Commit 85b0f16

Browse files
committed
crypto: handle OpenSSL error queue in CipherBase
This handles all errors produced by OpenSSL within the CipherBase class. API functions ensure that they do not add any new errors to the error queue. Also adds a couple of CHECKs and throws under certain conditions. PR-URL: #21288 Fixes: #21281 Refs: #21287 Reviewed-By: Ujjwal Sharma <[email protected]>
1 parent 144c1b7 commit 85b0f16

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

src/node_crypto.cc

+39-18
Original file line numberDiff line numberDiff line change
@@ -2591,6 +2591,7 @@ void CipherBase::Init(const char* cipher_type,
25912591
int key_buf_len,
25922592
unsigned int auth_tag_len) {
25932593
HandleScope scope(env()->isolate());
2594+
MarkPopErrorOnReturn mark_pop_error_on_return;
25942595

25952596
#ifdef NODE_FIPS_MODE
25962597
if (FIPS_mode()) {
@@ -2615,6 +2616,7 @@ void CipherBase::Init(const char* cipher_type,
26152616
1,
26162617
key,
26172618
iv);
2619+
CHECK_NE(key_len, 0);
26182620

26192621
ctx_.reset(EVP_CIPHER_CTX_new());
26202622

@@ -2623,7 +2625,11 @@ void CipherBase::Init(const char* cipher_type,
26232625
EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
26242626

26252627
const bool encrypt = (kind_ == kCipher);
2626-
EVP_CipherInit_ex(ctx_.get(), cipher, nullptr, nullptr, nullptr, encrypt);
2628+
if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
2629+
nullptr, nullptr, encrypt)) {
2630+
return ThrowCryptoError(env(), ERR_get_error(),
2631+
"Failed to initialize cipher");
2632+
}
26272633

26282634
if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE ||
26292635
mode == EVP_CIPH_CCM_MODE)) {
@@ -2642,12 +2648,15 @@ void CipherBase::Init(const char* cipher_type,
26422648

26432649
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len));
26442650

2645-
EVP_CipherInit_ex(ctx_.get(),
2646-
nullptr,
2647-
nullptr,
2648-
reinterpret_cast<unsigned char*>(key),
2649-
reinterpret_cast<unsigned char*>(iv),
2650-
encrypt);
2651+
if (1 != EVP_CipherInit_ex(ctx_.get(),
2652+
nullptr,
2653+
nullptr,
2654+
reinterpret_cast<unsigned char*>(key),
2655+
reinterpret_cast<unsigned char*>(iv),
2656+
encrypt)) {
2657+
return ThrowCryptoError(env(), ERR_get_error(),
2658+
"Failed to initialize cipher");
2659+
}
26512660
}
26522661

26532662

@@ -2682,6 +2691,7 @@ void CipherBase::InitIv(const char* cipher_type,
26822691
int iv_len,
26832692
unsigned int auth_tag_len) {
26842693
HandleScope scope(env()->isolate());
2694+
MarkPopErrorOnReturn mark_pop_error_on_return;
26852695

26862696
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
26872697
if (cipher == nullptr) {
@@ -2712,7 +2722,11 @@ void CipherBase::InitIv(const char* cipher_type,
27122722
EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
27132723

27142724
const bool encrypt = (kind_ == kCipher);
2715-
EVP_CipherInit_ex(ctx_.get(), cipher, nullptr, nullptr, nullptr, encrypt);
2725+
if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
2726+
nullptr, nullptr, encrypt)) {
2727+
return ThrowCryptoError(env(), ERR_get_error(),
2728+
"Failed to initialize cipher");
2729+
}
27162730

27172731
if (IsAuthenticatedMode()) {
27182732
CHECK(has_iv);
@@ -2725,12 +2739,15 @@ void CipherBase::InitIv(const char* cipher_type,
27252739
return env()->ThrowError("Invalid key length");
27262740
}
27272741

2728-
EVP_CipherInit_ex(ctx_.get(),
2729-
nullptr,
2730-
nullptr,
2731-
reinterpret_cast<const unsigned char*>(key),
2732-
reinterpret_cast<const unsigned char*>(iv),
2733-
encrypt);
2742+
if (1 != EVP_CipherInit_ex(ctx_.get(),
2743+
nullptr,
2744+
nullptr,
2745+
reinterpret_cast<const unsigned char*>(key),
2746+
reinterpret_cast<const unsigned char*>(iv),
2747+
encrypt)) {
2748+
return ThrowCryptoError(env(), ERR_get_error(),
2749+
"Failed to initialize cipher");
2750+
}
27342751
}
27352752

27362753

@@ -2775,6 +2792,7 @@ static bool IsValidGCMTagLength(unsigned int tag_len) {
27752792
bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
27762793
unsigned int auth_tag_len) {
27772794
CHECK(IsAuthenticatedMode());
2795+
MarkPopErrorOnReturn mark_pop_error_on_return;
27782796

27792797
if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
27802798
EVP_CTRL_AEAD_SET_IVLEN,
@@ -2917,6 +2935,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
29172935
bool CipherBase::SetAAD(const char* data, unsigned int len, int plaintext_len) {
29182936
if (!ctx_ || !IsAuthenticatedMode())
29192937
return false;
2938+
MarkPopErrorOnReturn mark_pop_error_on_return;
29202939

29212940
int outlen;
29222941
const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
@@ -2976,6 +2995,7 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
29762995
int* out_len) {
29772996
if (!ctx_)
29782997
return kErrorState;
2998+
MarkPopErrorOnReturn mark_pop_error_on_return;
29792999

29803000
const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
29813001

@@ -2987,10 +3007,10 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
29873007
// on first update:
29883008
if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_len_ > 0 &&
29893009
auth_tag_len_ != kNoAuthTagLength && !auth_tag_set_) {
2990-
EVP_CIPHER_CTX_ctrl(ctx_.get(),
2991-
EVP_CTRL_GCM_SET_TAG,
2992-
auth_tag_len_,
2993-
reinterpret_cast<unsigned char*>(auth_tag_));
3010+
CHECK(EVP_CIPHER_CTX_ctrl(ctx_.get(),
3011+
EVP_CTRL_GCM_SET_TAG,
3012+
auth_tag_len_,
3013+
reinterpret_cast<unsigned char*>(auth_tag_)));
29943014
auth_tag_set_ = true;
29953015
}
29963016

@@ -3068,6 +3088,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
30683088
bool CipherBase::SetAutoPadding(bool auto_padding) {
30693089
if (!ctx_)
30703090
return false;
3091+
MarkPopErrorOnReturn mark_pop_error_on_return;
30713092
return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
30723093
}
30733094

0 commit comments

Comments
 (0)