@@ -35,10 +35,6 @@ using v8::Value;
35
35
36
36
namespace crypto {
37
37
namespace {
38
- bool IsValidGCMTagLength (unsigned int tag_len) {
39
- return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16 );
40
- }
41
-
42
38
// Collects and returns information on the given cipher
43
39
void GetCipherInfo (const FunctionCallbackInfo<Value>& args) {
44
40
Environment* env = Environment::GetCurrent (args);
@@ -50,7 +46,7 @@ void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
50
46
const auto cipher = ([&] {
51
47
if (args[1 ]->IsString ()) {
52
48
Utf8Value name (env->isolate (), args[1 ]);
53
- return Cipher::FromName (* name);
49
+ return Cipher::FromName (name. ToStringView () );
54
50
} else {
55
51
int nid = args[1 ].As <Int32>()->Value ();
56
52
return Cipher::FromNid (nid);
@@ -166,16 +162,19 @@ void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
166
162
} // namespace
167
163
168
164
void CipherBase::GetSSLCiphers (const FunctionCallbackInfo<Value>& args) {
165
+ MarkPopErrorOnReturn mark_pop_error_on_return;
169
166
Environment* env = Environment::GetCurrent (args);
170
167
171
168
auto ctx = SSLCtxPointer::New ();
172
169
if (!ctx) {
173
- return ThrowCryptoError (env, ERR_get_error (), " SSL_CTX_new" );
170
+ return ThrowCryptoError (
171
+ env, mark_pop_error_on_return.peekError (), " SSL_CTX_new" );
174
172
}
175
173
176
174
auto ssl = SSLPointer::New (ctx);
177
175
if (!ssl) {
178
- return ThrowCryptoError (env, ERR_get_error (), " SSL_new" );
176
+ return ThrowCryptoError (
177
+ env, mark_pop_error_on_return.peekError (), " SSL_new" );
179
178
}
180
179
181
180
LocalVector<Value> arr (env->isolate ());
@@ -309,6 +308,7 @@ void CipherBase::CommonInit(const char* cipher_type,
309
308
const unsigned char * iv,
310
309
int iv_len,
311
310
unsigned int auth_tag_len) {
311
+ MarkPopErrorOnReturn mark_pop_error_on_return;
312
312
CHECK (!ctx_);
313
313
ctx_ = CipherCtxPointer::New ();
314
314
CHECK (ctx_);
@@ -319,14 +319,16 @@ void CipherBase::CommonInit(const char* cipher_type,
319
319
320
320
const bool encrypt = (kind_ == kCipher );
321
321
if (!ctx_.init (cipher, encrypt )) {
322
- return ThrowCryptoError (env (), ERR_get_error (),
322
+ return ThrowCryptoError (env (),
323
+ mark_pop_error_on_return.peekError (),
323
324
" Failed to initialize cipher" );
324
325
}
325
326
326
327
if (cipher.isSupportedAuthenticatedMode ()) {
327
328
CHECK_GE (iv_len, 0 );
328
- if (!InitAuthenticated (cipher_type, iv_len, auth_tag_len))
329
+ if (!InitAuthenticated (cipher_type, iv_len, auth_tag_len)) {
329
330
return ;
331
+ }
330
332
}
331
333
332
334
if (!ctx_.setKeyLength (key_len)) {
@@ -335,7 +337,8 @@ void CipherBase::CommonInit(const char* cipher_type,
335
337
}
336
338
337
339
if (!ctx_.init (Cipher (), encrypt , key, iv)) {
338
- return ThrowCryptoError (env (), ERR_get_error (),
340
+ return ThrowCryptoError (env (),
341
+ mark_pop_error_on_return.peekError (),
339
342
" Failed to initialize cipher" );
340
343
}
341
344
}
@@ -422,8 +425,9 @@ void CipherBase::InitIv(const char* cipher_type,
422
425
const bool has_iv = iv_buf.size () > 0 ;
423
426
424
427
// Throw if no IV was passed and the cipher requires an IV
425
- if (!has_iv && expected_iv_len != 0 )
428
+ if (!has_iv && expected_iv_len != 0 ) {
426
429
return THROW_ERR_CRYPTO_INVALID_IV (env ());
430
+ }
427
431
428
432
// Throw if an IV was passed which does not match the cipher's fixed IV length
429
433
// static_cast<int> for the iv_buf.size() is safe because we've verified
@@ -438,8 +442,9 @@ void CipherBase::InitIv(const char* cipher_type,
438
442
// Check for invalid IV lengths, since OpenSSL does not under some
439
443
// conditions:
440
444
// https://www.openssl.org/news/secadv/20190306.txt.
441
- if (iv_buf.size () > 12 )
445
+ if (iv_buf.size () > 12 ) {
442
446
return THROW_ERR_CRYPTO_INVALID_IV (env ());
447
+ }
443
448
}
444
449
445
450
CommonInit (
@@ -504,7 +509,7 @@ bool CipherBase::InitAuthenticated(
504
509
const int mode = ctx_.getMode ();
505
510
if (mode == EVP_CIPH_GCM_MODE) {
506
511
if (auth_tag_len != kNoAuthTagLength ) {
507
- if (!IsValidGCMTagLength (auth_tag_len)) {
512
+ if (!Cipher:: IsValidGCMTagLength (auth_tag_len)) {
508
513
THROW_ERR_CRYPTO_INVALID_AUTH_TAG (
509
514
env (),
510
515
" Invalid authentication tag length: %u" ,
@@ -595,9 +600,11 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
595
600
return ;
596
601
}
597
602
598
- args.GetReturnValue ().Set (
599
- Buffer::Copy (env, cipher->auth_tag_ , cipher->auth_tag_len_ )
600
- .FromMaybe (Local<Value>()));
603
+ Local<Value> ret;
604
+ if (Buffer::Copy (env, cipher->auth_tag_ , cipher->auth_tag_len_ )
605
+ .ToLocal (&ret)) {
606
+ args.GetReturnValue ().Set (ret);
607
+ }
601
608
}
602
609
603
610
void CipherBase::SetAuthTag (const FunctionCallbackInfo<Value>& args) {
@@ -624,7 +631,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
624
631
// Restrict GCM tag lengths according to NIST 800-38d, page 9.
625
632
is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength ||
626
633
cipher->auth_tag_len_ == tag_len) &&
627
- IsValidGCMTagLength (tag_len);
634
+ Cipher:: IsValidGCMTagLength (tag_len);
628
635
} else {
629
636
// At this point, the tag length is already known and must match the
630
637
// length of the given authentication tag.
@@ -693,12 +700,12 @@ bool CipherBase::SetAAD(
693
700
return false ;
694
701
}
695
702
696
- if (!CheckCCMMessageLength (plaintext_len))
703
+ if (!CheckCCMMessageLength (plaintext_len)) {
697
704
return false ;
705
+ }
698
706
699
- if (kind_ == kDecipher ) {
700
- if (!MaybePassAuthTagToOpenSSL ())
701
- return false ;
707
+ if (kind_ == kDecipher && !MaybePassAuthTagToOpenSSL ()) {
708
+ return false ;
702
709
}
703
710
704
711
ncrypto::Buffer<const unsigned char > buffer{
@@ -738,19 +745,20 @@ CipherBase::UpdateResult CipherBase::Update(
738
745
const char * data,
739
746
size_t len,
740
747
std::unique_ptr<BackingStore>* out) {
741
- if (!ctx_ || len > INT_MAX)
742
- return kErrorState ;
748
+ if (!ctx_ || len > INT_MAX) return kErrorState ;
743
749
MarkPopErrorOnReturn mark_pop_error_on_return;
744
750
745
751
const int mode = ctx_.getMode ();
746
752
747
- if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength (len))
753
+ if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength (len)) {
748
754
return kErrorMessageSize ;
755
+ }
749
756
750
757
// Pass the authentication tag to OpenSSL if possible. This will only happen
751
758
// once, usually on the first update.
752
- if (kind_ == kDecipher && IsAuthenticatedMode ())
759
+ if (kind_ == kDecipher && IsAuthenticatedMode ()) {
753
760
CHECK (MaybePassAuthTagToOpenSSL ());
761
+ }
754
762
755
763
const int block_size = ctx_.getBlockSize ();
756
764
CHECK_GT (block_size, 0 );
@@ -800,34 +808,38 @@ CipherBase::UpdateResult CipherBase::Update(
800
808
}
801
809
802
810
void CipherBase::Update (const FunctionCallbackInfo<Value>& args) {
803
- Decode<CipherBase>(args, [](CipherBase* cipher,
804
- const FunctionCallbackInfo<Value>& args,
805
- const char * data, size_t size) {
806
- std::unique_ptr<BackingStore> out;
807
- Environment* env = Environment::GetCurrent (args);
808
-
809
- if (size > INT_MAX) [[unlikely]] {
810
- return THROW_ERR_OUT_OF_RANGE (env, " data is too long" );
811
- }
812
- UpdateResult r = cipher->Update (data, size, &out);
813
-
814
- if (r != kSuccess ) {
815
- if (r == kErrorState ) {
816
- ThrowCryptoError (env, ERR_get_error (),
817
- " Trying to add data in unsupported state" );
818
- }
819
- return ;
820
- }
811
+ Decode<CipherBase>(
812
+ args,
813
+ [](CipherBase* cipher,
814
+ const FunctionCallbackInfo<Value>& args,
815
+ const char * data,
816
+ size_t size) {
817
+ MarkPopErrorOnReturn mark_pop_error_on_return;
818
+ std::unique_ptr<BackingStore> out;
819
+ Environment* env = Environment::GetCurrent (args);
820
+
821
+ if (size > INT_MAX) [[unlikely]] {
822
+ return THROW_ERR_OUT_OF_RANGE (env, " data is too long" );
823
+ }
824
+ UpdateResult r = cipher->Update (data, size, &out);
825
+
826
+ if (r != kSuccess ) {
827
+ if (r == kErrorState ) {
828
+ ThrowCryptoError (env,
829
+ mark_pop_error_on_return.peekError (),
830
+ " Trying to add data in unsupported state" );
831
+ }
832
+ return ;
833
+ }
821
834
822
- Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
823
- args.GetReturnValue ().Set (
824
- Buffer::New (env, ab, 0 , ab-> ByteLength ()) .FromMaybe (Local<Value>()));
825
- });
835
+ auto ab = ArrayBuffer::New (env->isolate (), std::move (out));
836
+ args.GetReturnValue ().Set (Buffer::New (env, ab, 0 , ab-> ByteLength ())
837
+ .FromMaybe (Local<Value>()));
838
+ });
826
839
}
827
840
828
841
bool CipherBase::SetAutoPadding (bool auto_padding) {
829
- if (!ctx_)
830
- return false ;
842
+ if (!ctx_) return false ;
831
843
MarkPopErrorOnReturn mark_pop_error_on_return;
832
844
return ctx_.setPadding (auto_padding);
833
845
}
@@ -841,8 +853,7 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
841
853
}
842
854
843
855
bool CipherBase::Final (std::unique_ptr<BackingStore>* out) {
844
- if (!ctx_)
845
- return false ;
856
+ if (!ctx_) return false ;
846
857
847
858
const int mode = ctx_.getMode ();
848
859
@@ -906,11 +917,13 @@ bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
906
917
907
918
void CipherBase::Final (const FunctionCallbackInfo<Value>& args) {
908
919
Environment* env = Environment::GetCurrent (args);
920
+ MarkPopErrorOnReturn mark_pop_error_on_return;
909
921
910
922
CipherBase* cipher;
911
923
ASSIGN_OR_RETURN_UNWRAP (&cipher, args.This ());
912
- if (cipher->ctx_ == nullptr )
924
+ if (cipher->ctx_ == nullptr ) {
913
925
return THROW_ERR_CRYPTO_INVALID_STATE (env);
926
+ }
914
927
915
928
std::unique_ptr<BackingStore> out;
916
929
@@ -923,10 +936,10 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
923
936
? " Unsupported state or unable to authenticate data"
924
937
: " Unsupported state" ;
925
938
926
- return ThrowCryptoError (env, ERR_get_error (), msg);
939
+ return ThrowCryptoError (env, mark_pop_error_on_return. peekError (), msg);
927
940
}
928
941
929
- Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
942
+ auto ab = ArrayBuffer::New (env->isolate (), std::move (out));
930
943
args.GetReturnValue ().Set (
931
944
Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
932
945
}
@@ -974,8 +987,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
974
987
auto data = KeyObjectData::GetPublicOrPrivateKeyFromJs (args, &offset);
975
988
if (!data) return ;
976
989
const auto & pkey = data.GetAsymmetricKey ();
977
- if (!pkey)
978
- return ;
990
+ if (!pkey) return ;
979
991
980
992
ArrayBufferOrViewContents<unsigned char > buf (args[offset]);
981
993
if (!buf.CheckSizeInt32 ()) [[unlikely]] {
0 commit comments