tls: migrate C++ errors to internal/errors.js
* Throw ERR_TLS_SNI_FROM_SERVER when setting server names on a server-side socket instead of returning silently * Assert on wrap_->started and wrap_->ssl instead of throwing errors since these errors indicate that the user either uses private APIs, or monkey-patches internals, or hits a bug. PR-URL: https://github.com/nodejs/node/pull/18125 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
9ffebeab48
commit
1c29da8236
@ -1530,6 +1530,12 @@ a hostname in the first parameter.
|
|||||||
An excessive amount of TLS renegotiations is detected, which is a potential
|
An excessive amount of TLS renegotiations is detected, which is a potential
|
||||||
vector for denial-of-service attacks.
|
vector for denial-of-service attacks.
|
||||||
|
|
||||||
|
<a id="ERR_TLS_SNI_FROM_SERVER"></a>
|
||||||
|
### ERR_TLS_SNI_FROM_SERVER
|
||||||
|
|
||||||
|
An attempt was made to issue Server Name Indication from a TLS server-side
|
||||||
|
socket, which is only valid from a client.
|
||||||
|
|
||||||
<a id="ERR_TLS_RENEGOTIATION_DISABLED"></a>
|
<a id="ERR_TLS_RENEGOTIATION_DISABLED"></a>
|
||||||
### ERR_TLS_RENEGOTIATION_DISABLED
|
### ERR_TLS_RENEGOTIATION_DISABLED
|
||||||
|
|
||||||
|
@ -660,6 +660,11 @@ TLSSocket.prototype.setServername = function(name) {
|
|||||||
if (typeof name !== 'string') {
|
if (typeof name !== 'string') {
|
||||||
throw new errors.Error('ERR_INVALID_ARG_TYPE', 'name', 'string');
|
throw new errors.Error('ERR_INVALID_ARG_TYPE', 'name', 'string');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._tlsOptions.isServer) {
|
||||||
|
throw new errors.Error('ERR_TLS_SNI_FROM_SERVER');
|
||||||
|
}
|
||||||
|
|
||||||
this._handle.setServername(name);
|
this._handle.setServername(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -480,6 +480,8 @@ E('ERR_TLS_RENEGOTIATION_FAILED', 'Failed to renegotiate');
|
|||||||
E('ERR_TLS_REQUIRED_SERVER_NAME',
|
E('ERR_TLS_REQUIRED_SERVER_NAME',
|
||||||
'"servername" is required parameter for Server.addContext');
|
'"servername" is required parameter for Server.addContext');
|
||||||
E('ERR_TLS_SESSION_ATTACK', 'TLS session renegotiation attack detected');
|
E('ERR_TLS_SESSION_ATTACK', 'TLS session renegotiation attack detected');
|
||||||
|
E('ERR_TLS_SNI_FROM_SERVER',
|
||||||
|
'Cannot issue SNI from a TLS server-side socket');
|
||||||
E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
|
E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
|
||||||
'Calling transform done when still transforming');
|
'Calling transform done when still transforming');
|
||||||
E('ERR_TRANSFORM_WITH_LENGTH_0',
|
E('ERR_TRANSFORM_WITH_LENGTH_0',
|
||||||
|
@ -225,13 +225,11 @@ void TLSWrap::Receive(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
|
|
||||||
void TLSWrap::Start(const FunctionCallbackInfo<Value>& args) {
|
void TLSWrap::Start(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
|
||||||
|
|
||||||
TLSWrap* wrap;
|
TLSWrap* wrap;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
||||||
|
|
||||||
if (wrap->started_)
|
CHECK(!wrap->started_);
|
||||||
return env->ThrowError("Already started.");
|
|
||||||
wrap->started_ = true;
|
wrap->started_ = true;
|
||||||
|
|
||||||
// Send ClientHello handshake
|
// Send ClientHello handshake
|
||||||
@ -747,17 +745,13 @@ int TLSWrap::DoShutdown(ShutdownWrap* req_wrap) {
|
|||||||
|
|
||||||
|
|
||||||
void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
|
void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
|
||||||
|
|
||||||
TLSWrap* wrap;
|
TLSWrap* wrap;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
||||||
|
|
||||||
CHECK_EQ(args.Length(), 2);
|
CHECK_EQ(args.Length(), 2);
|
||||||
CHECK(args[0]->IsBoolean());
|
CHECK(args[0]->IsBoolean());
|
||||||
CHECK(args[1]->IsBoolean());
|
CHECK(args[1]->IsBoolean());
|
||||||
|
CHECK_NE(wrap->ssl_, nullptr);
|
||||||
if (wrap->ssl_ == nullptr)
|
|
||||||
return env->ThrowTypeError("SetVerifyMode after destroySSL");
|
|
||||||
|
|
||||||
int verify_mode;
|
int verify_mode;
|
||||||
if (wrap->is_server()) {
|
if (wrap->is_server()) {
|
||||||
@ -785,10 +779,7 @@ void TLSWrap::EnableSessionCallbacks(
|
|||||||
const FunctionCallbackInfo<Value>& args) {
|
const FunctionCallbackInfo<Value>& args) {
|
||||||
TLSWrap* wrap;
|
TLSWrap* wrap;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
||||||
if (wrap->ssl_ == nullptr) {
|
CHECK_NE(wrap->ssl_, nullptr);
|
||||||
return wrap->env()->ThrowTypeError(
|
|
||||||
"EnableSessionCallbacks after destroySSL");
|
|
||||||
}
|
|
||||||
wrap->enable_session_callbacks();
|
wrap->enable_session_callbacks();
|
||||||
crypto::NodeBIO::FromBIO(wrap->enc_in_)->set_initial(kMaxHelloLength);
|
crypto::NodeBIO::FromBIO(wrap->enc_in_)->set_initial(kMaxHelloLength);
|
||||||
wrap->hello_parser_.Start(SSLWrap<TLSWrap>::OnClientHello,
|
wrap->hello_parser_.Start(SSLWrap<TLSWrap>::OnClientHello,
|
||||||
@ -852,12 +843,8 @@ void TLSWrap::SetServername(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
CHECK_EQ(args.Length(), 1);
|
CHECK_EQ(args.Length(), 1);
|
||||||
CHECK(args[0]->IsString());
|
CHECK(args[0]->IsString());
|
||||||
|
CHECK(!wrap->started_);
|
||||||
if (wrap->started_)
|
CHECK(wrap->is_client());
|
||||||
return env->ThrowError("Already started.");
|
|
||||||
|
|
||||||
if (!wrap->is_client())
|
|
||||||
return;
|
|
||||||
|
|
||||||
CHECK_NE(wrap->ssl_, nullptr);
|
CHECK_NE(wrap->ssl_, nullptr);
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ const fixtures = require('../common/fixtures');
|
|||||||
if (!common.hasCrypto)
|
if (!common.hasCrypto)
|
||||||
common.skip('missing crypto');
|
common.skip('missing crypto');
|
||||||
|
|
||||||
const { connect } = require('tls');
|
const { connect, TLSSocket } = require('tls');
|
||||||
const makeDuplexPair = require('../common/duplexpair');
|
const makeDuplexPair = require('../common/duplexpair');
|
||||||
const { clientSide } = makeDuplexPair();
|
const { clientSide, serverSide } = makeDuplexPair();
|
||||||
|
|
||||||
|
const key = fixtures.readKey('agent1-key.pem');
|
||||||
|
const cert = fixtures.readKey('agent1-cert.pem');
|
||||||
const ca = fixtures.readKey('ca1-cert.pem');
|
const ca = fixtures.readKey('ca1-cert.pem');
|
||||||
|
|
||||||
const client = connect({
|
const client = connect({
|
||||||
@ -28,3 +30,17 @@ const client = connect({
|
|||||||
message: 'The "name" argument must be of type string'
|
message: 'The "name" argument must be of type string'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const server = new TLSSocket(serverSide, {
|
||||||
|
isServer: true,
|
||||||
|
key,
|
||||||
|
cert,
|
||||||
|
ca
|
||||||
|
});
|
||||||
|
|
||||||
|
common.expectsError(() => {
|
||||||
|
server.setServername('localhost');
|
||||||
|
}, {
|
||||||
|
code: 'ERR_TLS_SNI_FROM_SERVER',
|
||||||
|
message: 'Cannot issue SNI from a TLS server-side socket'
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user