Skip to content

Commit 8b5d350

Browse files
sam-githubBethGriggs
authored andcommittedApr 15, 2019
src: add .code and SSL specific error properties
SSL errors have a long structured message, but lacked the standard .code property which can be used for stable comparisons. Add a `code` property, as well as the 3 string components of an SSL error: `reason`, `library`, and `function`. Backport-PR-URL: #26951 PR-URL: #25093 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
1 parent 8e14859 commit 8b5d350

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed
 

‎src/env.h

+2
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
185185
V(fingerprint_string, "fingerprint") \
186186
V(flags_string, "flags") \
187187
V(fragment_string, "fragment") \
188+
V(function_string, "function") \
188189
V(get_data_clone_error_string, "_getDataCloneError") \
189190
V(get_shared_array_buffer_id_string, "_getSharedArrayBufferId") \
190191
V(gid_string, "gid") \
@@ -208,6 +209,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
208209
V(issuercert_string, "issuerCertificate") \
209210
V(kill_signal_string, "killSignal") \
210211
V(kind_string, "kind") \
212+
V(library_string, "library") \
211213
V(mac_string, "mac") \
212214
V(main_string, "main") \
213215
V(max_buffer_string, "maxBuffer") \

‎src/tls_wrap.cc

+36-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ using v8::Exception;
4040
using v8::Function;
4141
using v8::FunctionCallbackInfo;
4242
using v8::FunctionTemplate;
43+
using v8::Isolate;
4344
using v8::Local;
4445
using v8::Object;
4546
using v8::ReadOnly;
@@ -367,9 +368,43 @@ Local<Value> TLSWrap::GetSSLError(int status, int* err, std::string* msg) {
367368
BUF_MEM* mem;
368369
BIO_get_mem_ptr(bio, &mem);
369370

371+
Isolate* isolate = env()->isolate();
372+
Local<Context> context = isolate->GetCurrentContext();
373+
370374
Local<String> message =
371-
OneByteString(env()->isolate(), mem->data, mem->length);
375+
OneByteString(isolate, mem->data, mem->length);
372376
Local<Value> exception = Exception::Error(message);
377+
Local<Object> obj = exception->ToObject(context).ToLocalChecked();
378+
379+
const char* ls = ERR_lib_error_string(ssl_err);
380+
const char* fs = ERR_func_error_string(ssl_err);
381+
const char* rs = ERR_reason_error_string(ssl_err);
382+
383+
if (ls != nullptr)
384+
obj->Set(context, env()->library_string(),
385+
OneByteString(isolate, ls)).FromJust();
386+
if (fs != nullptr)
387+
obj->Set(context, env()->function_string(),
388+
OneByteString(isolate, fs)).FromJust();
389+
if (rs != nullptr) {
390+
obj->Set(context, env()->reason_string(),
391+
OneByteString(isolate, rs)).FromJust();
392+
393+
// SSL has no API to recover the error name from the number, so we
394+
// transform reason strings like "this error" to "ERR_SSL_THIS_ERROR",
395+
// which ends up being close to the original error macro name.
396+
std::string code(rs);
397+
398+
for (auto& c : code) {
399+
if (c == ' ')
400+
c = '_';
401+
else
402+
c = ::toupper(c);
403+
}
404+
obj->Set(context, env()->code_string(),
405+
OneByteString(isolate, ("ERR_SSL_" + code).c_str()))
406+
.FromJust();
407+
}
373408

374409
if (msg != nullptr)
375410
msg->assign(mem->data, mem->data + mem->length);

‎test/parallel/test-tls-alert-handling.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ if (!common.hasCrypto)
77
if (!common.opensslCli)
88
common.skip('node compiled without OpenSSL CLI');
99

10+
const assert = require('assert');
1011
const net = require('net');
1112
const tls = require('tls');
1213
const fixtures = require('../common/fixtures');
@@ -29,7 +30,11 @@ const opts = {
2930
const max_iter = 20;
3031
let iter = 0;
3132

32-
const errorHandler = common.mustCall(() => {
33+
const errorHandler = common.mustCall((err) => {
34+
assert.strictEqual(err.code, 'ERR_SSL_WRONG_VERSION_NUMBER');
35+
assert.strictEqual(err.library, 'SSL routines');
36+
assert.strictEqual(err.function, 'ssl3_get_record');
37+
assert.strictEqual(err.reason, 'wrong version number');
3338
errorReceived = true;
3439
if (canCloseServer())
3540
server.close();
@@ -81,5 +86,10 @@ function sendBADTLSRecord() {
8186
socket.end(BAD_RECORD);
8287
});
8388
}));
84-
client.on('error', common.mustCall());
89+
client.on('error', common.mustCall((err) => {
90+
assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION');
91+
assert.strictEqual(err.library, 'SSL routines');
92+
assert.strictEqual(err.function, 'ssl3_read_bytes');
93+
assert.strictEqual(err.reason, 'tlsv1 alert protocol version');
94+
}));
8595
}

0 commit comments

Comments
 (0)
Please sign in to comment.