Skip to content

Commit 5f58cff

Browse files
committed
tls_wrap: clear errors on return
Adopt `MarkPopErrorOnReturn` from `node_crypto.cc`, and use it to clear errors after `SSL_read`/`SSL_write`/`SSL_shutdown` functions. See: nodejs#4485 PR-URL: nodejs#4515 Reviewed-By: Ben Noordhuis <[email protected]>
1 parent bd8b2f0 commit 5f58cff

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

src/node_crypto.cc

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,6 @@ static X509_NAME *cnnic_ev_name =
116116
d2i_X509_NAME(nullptr, &cnnic_ev_p,
117117
sizeof(CNNIC_EV_ROOT_CA_SUBJECT_DATA)-1);
118118

119-
// Forcibly clear OpenSSL's error stack on return. This stops stale errors
120-
// from popping up later in the lifecycle of crypto operations where they
121-
// would cause spurious failures. It's a rather blunt method, though.
122-
// ERR_clear_error() isn't necessarily cheap either.
123-
struct ClearErrorOnReturn {
124-
~ClearErrorOnReturn() { ERR_clear_error(); }
125-
};
126-
127119
static uv_mutex_t* locks;
128120

129121
const char* const root_certs[] = {

src/node_crypto.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,21 @@
4141
namespace node {
4242
namespace crypto {
4343

44+
// Forcibly clear OpenSSL's error stack on return. This stops stale errors
45+
// from popping up later in the lifecycle of crypto operations where they
46+
// would cause spurious failures. It's a rather blunt method, though.
47+
// ERR_clear_error() isn't necessarily cheap either.
48+
struct ClearErrorOnReturn {
49+
~ClearErrorOnReturn() { ERR_clear_error(); }
50+
};
51+
52+
// Pop errors from OpenSSL's error stack that were added
53+
// between when this was constructed and destructed.
54+
struct MarkPopErrorOnReturn {
55+
MarkPopErrorOnReturn() { ERR_set_mark(); }
56+
~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }
57+
};
58+
4459
enum CheckResult {
4560
CHECK_CERT_REVOKED = 0,
4661
CHECK_OK = 1

src/tls_wrap.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ using v8::Object;
3131
using v8::String;
3232
using v8::Value;
3333

34-
3534
TLSWrap::TLSWrap(Environment* env,
3635
Kind kind,
3736
StreamBase* stream,
@@ -401,6 +400,8 @@ void TLSWrap::ClearOut() {
401400
if (ssl_ == nullptr)
402401
return;
403402

403+
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
404+
404405
char out[kClearOutChunkSize];
405406
int read;
406407
for (;;) {
@@ -460,6 +461,8 @@ bool TLSWrap::ClearIn() {
460461
if (ssl_ == nullptr)
461462
return false;
462463

464+
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
465+
463466
int written = 0;
464467
while (clear_in_->Length() > 0) {
465468
size_t avail = 0;
@@ -587,6 +590,8 @@ int TLSWrap::DoWrite(WriteWrap* w,
587590
if (ssl_ == nullptr)
588591
return UV_EPROTO;
589592

593+
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
594+
590595
int written = 0;
591596
for (i = 0; i < count; i++) {
592597
written = SSL_write(ssl_, bufs[i].base, bufs[i].len);
@@ -702,8 +707,11 @@ void TLSWrap::DoRead(ssize_t nread,
702707

703708

704709
int TLSWrap::DoShutdown(ShutdownWrap* req_wrap) {
710+
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
711+
705712
if (ssl_ != nullptr && SSL_shutdown(ssl_) == 0)
706713
SSL_shutdown(ssl_);
714+
707715
shutdown_ = true;
708716
EncOut();
709717
return stream_->DoShutdown(req_wrap);

0 commit comments

Comments
 (0)