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: #21288Fixes: #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‎

Lines changed: 39 additions & 18 deletions
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
unsignedint 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
constbool 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+
returnThrowCryptoError(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<unsignedchar*>(key),
2639-
reinterpret_cast<unsignedchar*>(iv),
2640-
encrypt);
2641+
if (1 != EVP_CipherInit_ex(ctx_.get(),
2642+
nullptr,
2643+
nullptr,
2644+
reinterpret_cast<unsignedchar*>(key),
2645+
reinterpret_cast<unsignedchar*>(iv),
2646+
encrypt)){
2647+
returnThrowCryptoError(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
unsignedint 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
constbool 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+
returnThrowCryptoError(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
returnenv()->ThrowError("Invalid key length");
27162730
}
27172731

2718-
EVP_CipherInit_ex(ctx_.get(),
2719-
nullptr,
2720-
nullptr,
2721-
reinterpret_cast<constunsignedchar*>(key),
2722-
reinterpret_cast<constunsignedchar*>(iv),
2723-
encrypt);
2732+
if (1 != EVP_CipherInit_ex(ctx_.get(),
2733+
nullptr,
2734+
nullptr,
2735+
reinterpret_cast<constunsignedchar*>(key),
2736+
reinterpret_cast<constunsignedchar*>(iv),
2737+
encrypt)){
2738+
returnThrowCryptoError(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
boolCipherBase::InitAuthenticated(constchar* cipher_type, int iv_len,
27662783
unsignedint 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
boolCipherBase::SetAAD(constchar* data, unsignedint len, int plaintext_len){
29112929
if (!ctx_ || !IsAuthenticatedMode())
29122930
returnfalse;
2931+
MarkPopErrorOnReturn mark_pop_error_on_return;
29132932

29142933
int outlen;
29152934
constint 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
returnkErrorState;
2991+
MarkPopErrorOnReturn mark_pop_error_on_return;
29722992

29732993
constint 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<unsignedchar*>(auth_tag_));
3003+
CHECK(EVP_CIPHER_CTX_ctrl(ctx_.get(),
3004+
EVP_CTRL_GCM_SET_TAG,
3005+
auth_tag_len_,
3006+
reinterpret_cast<unsignedchar*>(auth_tag_)));
29873007
auth_tag_set_ = true;
29883008
}
29893009

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

0 commit comments

Comments
(0)