Skip to content

Commit 07cce88

Browse files
tniessentargos
authored andcommitted
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 48b16aa commit 07cce88

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
@@ -2581,6 +2581,7 @@ void CipherBase::Init(const char* cipher_type,
25812581
int key_buf_len,
25822582
unsigned int auth_tag_len) {
25832583
HandleScope scope(env()->isolate());
2584+
MarkPopErrorOnReturn mark_pop_error_on_return;
25842585

25852586
#ifdef NODE_FIPS_MODE
25862587
if (FIPS_mode()) {
@@ -2605,6 +2606,7 @@ void CipherBase::Init(const char* cipher_type,
26052606
1,
26062607
key,
26072608
iv);
2609+
CHECK_NE(key_len, 0);
26082610

26092611
ctx_.reset(EVP_CIPHER_CTX_new());
26102612

@@ -2613,7 +2615,11 @@ void CipherBase::Init(const char* cipher_type,
26132615
EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
26142616

26152617
const bool encrypt = (kind_ == kCipher);
2616-
EVP_CipherInit_ex(ctx_.get(), cipher, nullptr, nullptr, nullptr, encrypt);
2618+
if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
2619+
nullptr, nullptr, encrypt)) {
2620+
return ThrowCryptoError(env(), ERR_get_error(),
2621+
"Failed to initialize cipher");
2622+
}
26172623

26182624
if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE ||
26192625
mode == EVP_CIPH_CCM_MODE)) {
@@ -2632,12 +2638,15 @@ void CipherBase::Init(const char* cipher_type,
26322638

26332639
CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(ctx_.get(), key_len));
26342640

2635-
EVP_CipherInit_ex(ctx_.get(),
2636-
nullptr,
2637-
nullptr,
2638-
reinterpret_cast<unsigned char*>(key),
2639-
reinterpret_cast<unsigned char*>(iv),
2640-
encrypt);
2641+
if (1 != EVP_CipherInit_ex(ctx_.get(),
2642+
nullptr,
2643+
nullptr,
2644+
reinterpret_cast<unsigned char*>(key),
2645+
reinterpret_cast<unsigned char*>(iv),
2646+
encrypt)) {
2647+
return ThrowCryptoError(env(), ERR_get_error(),
2648+
"Failed to initialize cipher");
2649+
}
26412650
}
26422651

26432652

@@ -2672,6 +2681,7 @@ void CipherBase::InitIv(const char* cipher_type,
26722681
int iv_len,
26732682
unsigned int auth_tag_len) {
26742683
HandleScope scope(env()->isolate());
2684+
MarkPopErrorOnReturn mark_pop_error_on_return;
26752685

26762686
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
26772687
if (cipher == nullptr) {
@@ -2702,7 +2712,11 @@ void CipherBase::InitIv(const char* cipher_type,
27022712
EVP_CIPHER_CTX_set_flags(ctx_.get(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
27032713

27042714
const bool encrypt = (kind_ == kCipher);
2705-
EVP_CipherInit_ex(ctx_.get(), cipher, nullptr, nullptr, nullptr, encrypt);
2715+
if (1 != EVP_CipherInit_ex(ctx_.get(), cipher, nullptr,
2716+
nullptr, nullptr, encrypt)) {
2717+
return ThrowCryptoError(env(), ERR_get_error(),
2718+
"Failed to initialize cipher");
2719+
}
27062720

27072721
if (IsAuthenticatedMode()) {
27082722
CHECK(has_iv);
@@ -2715,12 +2729,15 @@ void CipherBase::InitIv(const char* cipher_type,
27152729
return env()->ThrowError("Invalid key length");
27162730
}
27172731

2718-
EVP_CipherInit_ex(ctx_.get(),
2719-
nullptr,
2720-
nullptr,
2721-
reinterpret_cast<const unsigned char*>(key),
2722-
reinterpret_cast<const unsigned char*>(iv),
2723-
encrypt);
2732+
if (1 != EVP_CipherInit_ex(ctx_.get(),
2733+
nullptr,
2734+
nullptr,
2735+
reinterpret_cast<const unsigned char*>(key),
2736+
reinterpret_cast<const unsigned char*>(iv),
2737+
encrypt)) {
2738+
return ThrowCryptoError(env(), ERR_get_error(),
2739+
"Failed to initialize cipher");
2740+
}
27242741
}
27252742

27262743

@@ -2765,6 +2782,7 @@ static bool IsValidGCMTagLength(unsigned int tag_len) {
27652782
bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
27662783
unsigned int auth_tag_len) {
27672784
CHECK(IsAuthenticatedMode());
2785+
MarkPopErrorOnReturn mark_pop_error_on_return;
27682786

27692787
if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
27702788
EVP_CTRL_AEAD_SET_IVLEN,
@@ -2910,6 +2928,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
29102928
bool CipherBase::SetAAD(const char* data, unsigned int len, int plaintext_len) {
29112929
if (!ctx_ || !IsAuthenticatedMode())
29122930
return false;
2931+
MarkPopErrorOnReturn mark_pop_error_on_return;
29132932

29142933
int outlen;
29152934
const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
@@ -2969,6 +2988,7 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
29692988
int* out_len) {
29702989
if (!ctx_)
29712990
return kErrorState;
2991+
MarkPopErrorOnReturn mark_pop_error_on_return;
29722992

29732993
const int mode = EVP_CIPHER_CTX_mode(ctx_.get());
29742994

@@ -2980,10 +3000,10 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
29803000
// on first update:
29813001
if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_len_ > 0 &&
29823002
auth_tag_len_ != kNoAuthTagLength && !auth_tag_set_) {
2983-
EVP_CIPHER_CTX_ctrl(ctx_.get(),
2984-
EVP_CTRL_GCM_SET_TAG,
2985-
auth_tag_len_,
2986-
reinterpret_cast<unsigned char*>(auth_tag_));
3003+
CHECK(EVP_CIPHER_CTX_ctrl(ctx_.get(),
3004+
EVP_CTRL_GCM_SET_TAG,
3005+
auth_tag_len_,
3006+
reinterpret_cast<unsigned char*>(auth_tag_)));
29873007
auth_tag_set_ = true;
29883008
}
29893009

@@ -3061,6 +3081,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
30613081
bool CipherBase::SetAutoPadding(bool auto_padding) {
30623082
if (!ctx_)
30633083
return false;
3084+
MarkPopErrorOnReturn mark_pop_error_on_return;
30643085
return EVP_CIPHER_CTX_set_padding(ctx_.get(), auto_padding);
30653086
}
30663087

0 commit comments

Comments
 (0)