37
37
namespace node {
38
38
39
39
using v8::Array;
40
+ using v8::ArrayBuffer;
40
41
using v8::ArrayBufferView;
42
+ using v8::BackingStore;
41
43
using v8::Context;
42
44
using v8::DontDelete;
43
- using v8::EscapableHandleScope;
44
45
using v8::Exception;
45
46
using v8::False;
46
47
using v8::Function;
@@ -313,6 +314,17 @@ inline bool Set(
313
314
OneByteString (env->isolate (), value))
314
315
.IsNothing ();
315
316
}
317
+
318
+ std::string GetBIOError () {
319
+ std::string ret;
320
+ ERR_print_errors_cb (
321
+ [](const char * str, size_t len, void * opaque) {
322
+ static_cast <std::string*>(opaque)->assign (str, len);
323
+ return 0 ;
324
+ },
325
+ static_cast <void *>(&ret));
326
+ return ret;
327
+ }
316
328
} // namespace
317
329
318
330
TLSWrap::TLSWrap (Environment* env,
@@ -572,7 +584,8 @@ void TLSWrap::EncOut() {
572
584
// No encrypted output ready to write to the underlying stream.
573
585
if (BIO_pending (enc_out_) == 0 ) {
574
586
Debug (this , " No pending encrypted output" );
575
- if (pending_cleartext_input_.size () == 0 ) {
587
+ if (!pending_cleartext_input_ ||
588
+ pending_cleartext_input_->ByteLength () == 0 ) {
576
589
if (!in_dowrite_) {
577
590
Debug (this , " No pending cleartext input, not inside DoWrite()" );
578
591
InvokeQueued (0 );
@@ -665,84 +678,9 @@ void TLSWrap::OnStreamAfterWrite(WriteWrap* req_wrap, int status) {
665
678
EncOut ();
666
679
}
667
680
668
- MaybeLocal<Value> TLSWrap::GetSSLError (int status, int * err, std::string* msg) {
669
- EscapableHandleScope scope (env ()->isolate ());
670
-
671
- // ssl_ is already destroyed in reading EOF by close notify alert.
672
- if (ssl_ == nullptr )
673
- return MaybeLocal<Value>();
674
-
675
- *err = SSL_get_error (ssl_.get (), status);
676
- switch (*err) {
677
- case SSL_ERROR_NONE:
678
- case SSL_ERROR_WANT_READ:
679
- case SSL_ERROR_WANT_WRITE:
680
- case SSL_ERROR_WANT_X509_LOOKUP:
681
- return MaybeLocal<Value>();
682
-
683
- case SSL_ERROR_ZERO_RETURN:
684
- return scope.Escape (env ()->zero_return_string ());
685
-
686
- case SSL_ERROR_SSL:
687
- case SSL_ERROR_SYSCALL:
688
- {
689
- unsigned long ssl_err = ERR_peek_error (); // NOLINT(runtime/int)
690
- BIO* bio = BIO_new (BIO_s_mem ());
691
- ERR_print_errors (bio);
692
-
693
- BUF_MEM* mem;
694
- BIO_get_mem_ptr (bio, &mem);
695
-
696
- Isolate* isolate = env ()->isolate ();
697
- Local<Context> context = isolate->GetCurrentContext ();
698
-
699
- Local<String> message = OneByteString (isolate, mem->data , mem->length );
700
- Local<Value> exception = Exception::Error (message);
701
- Local<Object> obj =
702
- exception ->ToObject (context).FromMaybe (Local<Object>());
703
- if (UNLIKELY (obj.IsEmpty ()))
704
- return MaybeLocal<Value>();
705
-
706
- const char * ls = ERR_lib_error_string (ssl_err);
707
- const char * fs = ERR_func_error_string (ssl_err);
708
- const char * rs = ERR_reason_error_string (ssl_err);
709
-
710
- if (!Set (env (), obj, env ()->library_string (), ls) ||
711
- !Set (env (), obj, env ()->function_string (), fs)) {
712
- return MaybeLocal<Value>();
713
- }
714
-
715
- if (rs != nullptr ) {
716
- if (!Set (env (), obj, env ()->reason_string (), rs))
717
- return MaybeLocal<Value>();
718
-
719
- // SSL has no API to recover the error name from the number, so we
720
- // transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
721
- // which ends up being close to the original error macro name.
722
- std::string code (rs);
723
-
724
- for (auto & c : code)
725
- c = (c == ' ' ) ? ' _' : ToUpper (c);
726
-
727
- if (!Set (env (), obj,
728
- env ()->code_string (),
729
- (" ERR_SSL_" + code).c_str ())) {
730
- return MaybeLocal<Value>();
731
- }
732
- }
733
-
734
- if (msg != nullptr )
735
- msg->assign (mem->data , mem->data + mem->length );
736
-
737
- BIO_free_all (bio);
738
-
739
- return scope.Escape (exception );
740
- }
741
-
742
- default :
743
- UNREACHABLE ();
744
- }
745
- UNREACHABLE ();
681
+ int TLSWrap::GetSSLError (int status) const {
682
+ // ssl_ might already be destroyed for reading EOF from a close notify alert.
683
+ return ssl_ != nullptr ? SSL_get_error (ssl_.get (), status) : 0 ;
746
684
}
747
685
748
686
void TLSWrap::ClearOut () {
@@ -809,24 +747,61 @@ void TLSWrap::ClearOut() {
809
747
// See node#1642 and SSL_read(3SSL) for details.
810
748
if (read <= 0 ) {
811
749
HandleScope handle_scope (env ()->isolate ());
812
- int err;
750
+ Local<Value> error;
751
+ int err = GetSSLError (read );
752
+ switch (err) {
753
+ case SSL_ERROR_ZERO_RETURN:
754
+ // Ignore ZERO_RETURN after EOF, it is basically not an error.
755
+ if (eof_) return ;
756
+ error = env ()->zero_return_string ();
757
+ break ;
813
758
814
- Local<Value> arg = GetSSLError (read , &err, nullptr )
815
- .FromMaybe (Local<Value>());
759
+ case SSL_ERROR_SSL:
760
+ case SSL_ERROR_SYSCALL:
761
+ {
762
+ unsigned long ssl_err = ERR_peek_error (); // NOLINT(runtime/int)
763
+
764
+ Local<Context> context = env ()->isolate ()->GetCurrentContext ();
765
+ if (UNLIKELY (context.IsEmpty ())) return ;
766
+ const std::string error_str = GetBIOError ();
767
+ Local<String> message = OneByteString (
768
+ env ()->isolate (), error_str.c_str (), error_str.size ());
769
+ if (UNLIKELY (message.IsEmpty ())) return ;
770
+ error = Exception::Error (message);
771
+ if (UNLIKELY (error.IsEmpty ())) return ;
772
+ Local<Object> obj;
773
+ if (UNLIKELY (!error->ToObject (context).ToLocal (&obj))) return ;
774
+
775
+ const char * ls = ERR_lib_error_string (ssl_err);
776
+ const char * fs = ERR_func_error_string (ssl_err);
777
+ const char * rs = ERR_reason_error_string (ssl_err);
778
+ if (!Set (env (), obj, env ()->library_string (), ls) ||
779
+ !Set (env (), obj, env ()->function_string (), fs) ||
780
+ !Set (env (), obj, env ()->reason_string (), rs, false )) return ;
781
+ // SSL has no API to recover the error name from the number, so we
782
+ // transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
783
+ // which ends up being close to the original error macro name.
784
+ std::string code (rs);
785
+ // TODO(RaisinTen): Pass an appropriate execution policy when it is
786
+ // implemented in our supported compilers.
787
+ std::transform (code.begin (), code.end (), code.begin (),
788
+ [](char c) { return c == ' ' ? ' _' : ToUpper (c); });
789
+ if (!Set (env (), obj,
790
+ env ()->code_string (), (" ERR_SSL_" + code).c_str ())) return ;
791
+ }
792
+ break ;
816
793
817
- // Ignore ZERO_RETURN after EOF, it is basically not a error
818
- if (err == SSL_ERROR_ZERO_RETURN && eof_)
819
- return ;
794
+ default :
795
+ return ;
796
+ }
820
797
821
- if (LIKELY (!arg.IsEmpty ())) {
822
- Debug (this , " Got SSL error (%d), calling onerror" , err);
823
- // When TLS Alert are stored in wbio,
824
- // it should be flushed to socket before destroyed.
825
- if (BIO_pending (enc_out_) != 0 )
826
- EncOut ();
798
+ Debug (this , " Got SSL error (%d), calling onerror" , err);
799
+ // When TLS Alert are stored in wbio,
800
+ // it should be flushed to socket before destroyed.
801
+ if (BIO_pending (enc_out_) != 0 )
802
+ EncOut ();
827
803
828
- MakeCallback (env ()->onerror_string (), 1 , &arg);
829
- }
804
+ MakeCallback (env ()->onerror_string (), 1 , &error);
830
805
}
831
806
}
832
807
@@ -843,18 +818,19 @@ void TLSWrap::ClearIn() {
843
818
return ;
844
819
}
845
820
846
- if (pending_cleartext_input_.size () == 0 ) {
821
+ if (!pending_cleartext_input_ ||
822
+ pending_cleartext_input_->ByteLength () == 0 ) {
847
823
Debug (this , " Returning from ClearIn(), no pending data" );
848
824
return ;
849
825
}
850
826
851
- AllocatedBuffer data = std::move (pending_cleartext_input_);
827
+ std::unique_ptr<BackingStore> bs = std::move (pending_cleartext_input_);
852
828
MarkPopErrorOnReturn mark_pop_error_on_return;
853
829
854
- NodeBIO::FromBIO (enc_out_)->set_allocate_tls_hint (data. size ());
855
- int written = SSL_write (ssl_.get (), data. data (), data. size ());
856
- Debug (this , " Writing %zu bytes, written = %d" , data. size (), written);
857
- CHECK (written == -1 || written == static_cast <int >(data. size ()));
830
+ NodeBIO::FromBIO (enc_out_)->set_allocate_tls_hint (bs-> ByteLength ());
831
+ int written = SSL_write (ssl_.get (), bs-> Data (), bs-> ByteLength ());
832
+ Debug (this , " Writing %zu bytes, written = %d" , bs-> ByteLength (), written);
833
+ CHECK (written == -1 || written == static_cast <int >(bs-> ByteLength ()));
858
834
859
835
// All written
860
836
if (written != -1 ) {
@@ -863,24 +839,20 @@ void TLSWrap::ClearIn() {
863
839
}
864
840
865
841
// Error or partial write
866
- HandleScope handle_scope (env ()->isolate ());
867
- Context::Scope context_scope (env ()->context ());
868
-
869
- int err;
870
- std::string error_str;
871
- MaybeLocal<Value> arg = GetSSLError (written, &err, &error_str);
872
- if (!arg.IsEmpty ()) {
842
+ int err = GetSSLError (written);
843
+ if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL) {
873
844
Debug (this , " Got SSL error (%d)" , err);
874
845
write_callback_scheduled_ = true ;
875
846
// TODO(@sam-github) Should forward an error object with
876
847
// .code/.function/.etc, if possible.
877
- return InvokeQueued (UV_EPROTO, error_str.c_str ());
848
+ InvokeQueued (UV_EPROTO, GetBIOError ().c_str ());
849
+ return ;
878
850
}
879
851
880
852
Debug (this , " Pushing data back" );
881
853
// Push back the not-yet-written data. This can be skipped in the error
882
854
// case because no further writes would succeed anyway.
883
- pending_cleartext_input_ = std::move (data );
855
+ pending_cleartext_input_ = std::move (bs );
884
856
}
885
857
886
858
std::string TLSWrap::diagnostic_name () const {
@@ -998,7 +970,7 @@ int TLSWrap::DoWrite(WriteWrap* w,
998
970
return 0 ;
999
971
}
1000
972
1001
- AllocatedBuffer data ;
973
+ std::unique_ptr<BackingStore> bs ;
1002
974
MarkPopErrorOnReturn mark_pop_error_on_return;
1003
975
1004
976
int written = 0 ;
@@ -1012,36 +984,39 @@ int TLSWrap::DoWrite(WriteWrap* w,
1012
984
// and copying it when it could just be used.
1013
985
1014
986
if (nonempty_count != 1 ) {
1015
- data = AllocatedBuffer::AllocateManaged (env (), length);
987
+ {
988
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
989
+ bs = ArrayBuffer::NewBackingStore (env ()->isolate (), length);
990
+ }
1016
991
size_t offset = 0 ;
1017
992
for (i = 0 ; i < count; i++) {
1018
- memcpy (data.data () + offset, bufs[i].base , bufs[i].len );
993
+ memcpy (static_cast <char *>(bs->Data ()) + offset,
994
+ bufs[i].base , bufs[i].len );
1019
995
offset += bufs[i].len ;
1020
996
}
1021
997
1022
998
NodeBIO::FromBIO (enc_out_)->set_allocate_tls_hint (length);
1023
- written = SSL_write (ssl_.get (), data. data (), length);
999
+ written = SSL_write (ssl_.get (), bs-> Data (), length);
1024
1000
} else {
1025
1001
// Only one buffer: try to write directly, only store if it fails
1026
1002
uv_buf_t * buf = &bufs[nonempty_i];
1027
1003
NodeBIO::FromBIO (enc_out_)->set_allocate_tls_hint (buf->len );
1028
1004
written = SSL_write (ssl_.get (), buf->base , buf->len );
1029
1005
1030
1006
if (written == -1 ) {
1031
- data = AllocatedBuffer::AllocateManaged (env (), length);
1032
- memcpy (data.data (), buf->base , buf->len );
1007
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
1008
+ bs = ArrayBuffer::NewBackingStore (env ()->isolate (), length);
1009
+ memcpy (bs->Data (), buf->base , buf->len );
1033
1010
}
1034
1011
}
1035
1012
1036
1013
CHECK (written == -1 || written == static_cast <int >(length));
1037
1014
Debug (this , " Writing %zu bytes, written = %d" , length, written);
1038
1015
1039
1016
if (written == -1 ) {
1040
- int err;
1041
- MaybeLocal<Value> arg = GetSSLError (written, &err, &error_);
1042
-
1043
1017
// If we stopped writing because of an error, it's fatal, discard the data.
1044
- if (!arg.IsEmpty ()) {
1018
+ int err = GetSSLError (written);
1019
+ if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL) {
1045
1020
// TODO(@jasnell): What are we doing with the error?
1046
1021
Debug (this , " Got SSL error (%d), returning UV_EPROTO" , err);
1047
1022
current_write_.reset ();
@@ -1050,8 +1025,9 @@ int TLSWrap::DoWrite(WriteWrap* w,
1050
1025
1051
1026
Debug (this , " Saving data for later write" );
1052
1027
// Otherwise, save unwritten data so it can be written later by ClearIn().
1053
- CHECK_EQ (pending_cleartext_input_.size (), 0 );
1054
- pending_cleartext_input_ = std::move (data);
1028
+ CHECK (!pending_cleartext_input_ ||
1029
+ pending_cleartext_input_->ByteLength () == 0 );
1030
+ pending_cleartext_input_ = std::move (bs);
1055
1031
}
1056
1032
1057
1033
// Write any encrypted/handshake output that may be ready.
@@ -1491,9 +1467,8 @@ void TLSWrap::MemoryInfo(MemoryTracker* tracker) const {
1491
1467
tracker->TrackField (" ocsp_response" , ocsp_response_);
1492
1468
tracker->TrackField (" sni_context" , sni_context_);
1493
1469
tracker->TrackField (" error" , error_);
1494
- tracker->TrackFieldWithSize (" pending_cleartext_input" ,
1495
- pending_cleartext_input_.size (),
1496
- " AllocatedBuffer" );
1470
+ if (pending_cleartext_input_)
1471
+ tracker->TrackField (" pending_cleartext_input" , pending_cleartext_input_);
1497
1472
if (enc_in_ != nullptr )
1498
1473
tracker->TrackField (" enc_in" , NodeBIO::FromBIO (enc_in_));
1499
1474
if (enc_out_ != nullptr )
@@ -1724,13 +1699,13 @@ void TLSWrap::VerifyError(const FunctionCallbackInfo<Value>& args) {
1724
1699
const char * reason = X509_verify_cert_error_string (x509_verify_error);
1725
1700
const char * code = X509ErrorCode (x509_verify_error);
1726
1701
1727
- Local<Object> exception =
1702
+ Local<Object> error =
1728
1703
Exception::Error (OneByteString (env->isolate (), reason))
1729
1704
->ToObject (env->isolate ()->GetCurrentContext ())
1730
1705
.FromMaybe (Local<Object>());
1731
1706
1732
- if (Set (env, exception , env->code_string (), code))
1733
- args.GetReturnValue ().Set (exception );
1707
+ if (Set (env, error , env->code_string (), code))
1708
+ args.GetReturnValue ().Set (error );
1734
1709
}
1735
1710
1736
1711
void TLSWrap::GetCipher (const FunctionCallbackInfo<Value>& args) {
0 commit comments