diff --git a/doc/api/errors.md b/doc/api/errors.md
index 0161853774367d..44ec5548aeab35 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -186,10 +186,6 @@ circumstance of why the error occurred. `Error` objects capture a "stack trace"
detailing the point in the code at which the `Error` was instantiated, and may
provide a text description of the error.
-For crypto only, `Error` objects will include the OpenSSL error stack in a
-separate property called `opensslErrorStack` if it is available when the error
-is thrown.
-
All errors generated by Node.js, including all System and JavaScript errors,
will either be instances of, or inherit from, the `Error` class.
@@ -589,6 +585,30 @@ program. For a comprehensive list, see the [`errno`(3) man page][].
encountered by [`http`][] or [`net`][] — often a sign that a `socket.end()`
was not properly called.
+## OpenSSL Errors
+
+Errors originating in `crypto` or `tls` are of class `Error`, and in addition to
+the standard `.code` and `.message` properties, may have some additional
+OpenSSL-specific properties.
+
+### error.opensslErrorStack
+
+An array of errors that can give context to where in the OpenSSL library an
+error originates from.
+
+### error.function
+
+The OpenSSL function the error originates in.
+
+### error.library
+
+The OpenSSL library the error originates in.
+
+### error.reason
+
+A human-readable string describing the reason for the error.
+
+
## Node.js Error Codes
@@ -1751,11 +1771,6 @@ Valid TLS protocol versions are `'TLSv1'`, `'TLSv1.1'`, or `'TLSv1.2'`.
Attempting to set a TLS protocol `minVersion` or `maxVersion` conflicts with an
attempt to set the `secureProtocol` explicitly. Use one mechanism or the other.
-
-### ERR_TLS_RENEGOTIATE
-
-An attempt to renegotiate the TLS session failed.
-
### ERR_TLS_RENEGOTIATION_DISABLED
diff --git a/doc/api/tls.md b/doc/api/tls.md
index c86d2ac08768cb..ee390e1bdbc846 100644
--- a/doc/api/tls.md
+++ b/doc/api/tls.md
@@ -1046,9 +1046,10 @@ added: v0.11.8
`true`.
* `requestCert`
* `callback` {Function} If `renegotiate()` returned `true`, callback is
- attached once to the `'secure'` event. If it returned `false`, it will be
- called in the next tick with `ERR_TLS_RENEGOTIATE`, unless the `tlsSocket`
- has been destroyed, in which case it will not be called at all.
+ attached once to the `'secure'` event. If `renegotiate()` returned `false`,
+ `callback` will be called in the next tick with an error, unless the
+ `tlsSocket` has been destroyed, in which case `callback` will not be called
+ at all.
* Returns: {boolean} `true` if renegotiation was initiated, `false` otherwise.
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
index 5e0f648797d661..44a5994a8df9d5 100644
--- a/lib/_tls_wrap.js
+++ b/lib/_tls_wrap.js
@@ -48,7 +48,6 @@ const {
ERR_SOCKET_CLOSED,
ERR_TLS_DH_PARAM_SIZE,
ERR_TLS_HANDSHAKE_TIMEOUT,
- ERR_TLS_RENEGOTIATE,
ERR_TLS_RENEGOTIATION_DISABLED,
ERR_TLS_REQUIRED_SERVER_NAME,
ERR_TLS_SESSION_ATTACK,
@@ -661,9 +660,11 @@ TLSSocket.prototype.renegotiate = function(options, callback) {
// Ensure that we'll cycle through internal openssl's state
this.write('');
- if (!this._handle.renegotiate()) {
+ try {
+ this._handle.renegotiate();
+ } catch (err) {
if (callback) {
- process.nextTick(callback, new ERR_TLS_RENEGOTIATE());
+ process.nextTick(callback, err);
}
return false;
}
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index e3347374cc702b..fee313a0f466e9 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -1046,7 +1046,6 @@ E('ERR_TLS_INVALID_PROTOCOL_VERSION',
'%j is not a valid %s TLS protocol version', TypeError);
E('ERR_TLS_PROTOCOL_VERSION_CONFLICT',
'TLS protocol version %j conflicts with secureProtocol %j', TypeError);
-E('ERR_TLS_RENEGOTIATE', 'Attempt to renegotiate TLS session failed', Error);
E('ERR_TLS_RENEGOTIATION_DISABLED',
'TLS session renegotiation disabled for this socket', Error);
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 91d06c8248b523..e963a50c500644 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -212,6 +212,113 @@ static int NoPasswordCallback(char* buf, int size, int rwflag, void* u) {
}
+// namespace node::crypto::error
+namespace error {
+void Decorate(Environment* env, Local