Skip to content

Commit 9ffebea

Browse files
committed
tls: migrate argument type-checking errors
* Throw ERR_INVALID_ARG_TYPE from public APIs * Assert argument types in bindings instead of throwing errors PR-URL: #18125 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent f75bc2c commit 9ffebea

File tree

4 files changed

+60
-19
lines changed

4 files changed

+60
-19
lines changed

lib/_tls_wrap.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ const { Timer } = process.binding('timer_wrap');
3636
const tls_wrap = process.binding('tls_wrap');
3737
const { TCP, constants: TCPConstants } = process.binding('tcp_wrap');
3838
const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap');
39+
const {
40+
SecureContext: NativeSecureContext
41+
} = process.binding('crypto');
3942
const errors = require('internal/errors');
4043
const kConnectOptions = Symbol('connect-options');
4144
const kDisableRenegotiation = Symbol('disable-renegotiation');
@@ -407,7 +410,12 @@ TLSSocket.prototype._wrapHandle = function(wrap) {
407410
const context = options.secureContext ||
408411
options.credentials ||
409412
tls.createSecureContext(options);
410-
const res = tls_wrap.wrap(handle._externalStream,
413+
const externalStream = handle._externalStream;
414+
assert(typeof externalStream === 'object',
415+
'handle must be a LibuvStreamWrap');
416+
assert(context.context instanceof NativeSecureContext,
417+
'context.context must be a NativeSecureContext');
418+
const res = tls_wrap.wrap(externalStream,
411419
context.context,
412420
!!options.isServer);
413421
res._parent = handle;
@@ -548,8 +556,8 @@ TLSSocket.prototype.renegotiate = function(options, callback) {
548556
if (this.destroyed)
549557
return;
550558

551-
let requestCert = this._requestCert;
552-
let rejectUnauthorized = this._rejectUnauthorized;
559+
let requestCert = !!this._requestCert;
560+
let rejectUnauthorized = !!this._rejectUnauthorized;
553561

554562
if (options.requestCert !== undefined)
555563
requestCert = !!options.requestCert;
@@ -649,6 +657,9 @@ TLSSocket.prototype._start = function() {
649657
};
650658

651659
TLSSocket.prototype.setServername = function(name) {
660+
if (typeof name !== 'string') {
661+
throw new errors.Error('ERR_INVALID_ARG_TYPE', 'name', 'string');
662+
}
652663
this._handle.setServername(name);
653664
};
654665

src/tls_wrap.cc

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,10 @@ void TLSWrap::InitSSL() {
181181
void TLSWrap::Wrap(const FunctionCallbackInfo<Value>& args) {
182182
Environment* env = Environment::GetCurrent(args);
183183

184-
if (args.Length() < 1 || !args[0]->IsObject()) {
185-
return env->ThrowTypeError(
186-
"First argument should be a LibuvStreamWrap instance");
187-
}
188-
if (args.Length() < 2 || !args[1]->IsObject()) {
189-
return env->ThrowTypeError(
190-
"Second argument should be a SecureContext instance");
191-
}
192-
if (args.Length() < 3 || !args[2]->IsBoolean())
193-
return env->ThrowTypeError("Third argument should be boolean");
184+
CHECK_EQ(args.Length(), 3);
185+
CHECK(args[0]->IsObject());
186+
CHECK(args[1]->IsObject());
187+
CHECK(args[2]->IsBoolean());
194188

195189
Local<External> stream_obj = args[0].As<External>();
196190
Local<Object> sc = args[1].As<Object>();
@@ -758,8 +752,9 @@ void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
758752
TLSWrap* wrap;
759753
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
760754

761-
if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean())
762-
return env->ThrowTypeError("Bad arguments, expected two booleans");
755+
CHECK_EQ(args.Length(), 2);
756+
CHECK(args[0]->IsBoolean());
757+
CHECK(args[1]->IsBoolean());
763758

764759
if (wrap->ssl_ == nullptr)
765760
return env->ThrowTypeError("SetVerifyMode after destroySSL");
@@ -855,8 +850,8 @@ void TLSWrap::SetServername(const FunctionCallbackInfo<Value>& args) {
855850
TLSWrap* wrap;
856851
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
857852

858-
if (args.Length() < 1 || !args[0]->IsString())
859-
return env->ThrowTypeError("First argument should be a string");
853+
CHECK_EQ(args.Length(), 1);
854+
CHECK(args[0]->IsString());
860855

861856
if (wrap->started_)
862857
return env->ThrowError("Already started.");

test/parallel/test-tls-basic-validations.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,13 @@ assert.throws(() => tls.createServer({ ticketKeys: 'abcd' }),
3939
assert.throws(() => tls.createServer({ ticketKeys: Buffer.alloc(0) }),
4040
/TypeError: Ticket keys length must be 48 bytes/);
4141

42-
assert.throws(() => tls.createSecurePair({}),
43-
/TypeError: Second argument should be a SecureContext instance/);
42+
common.expectsError(
43+
() => tls.createSecurePair({}),
44+
{
45+
code: 'ERR_ASSERTION',
46+
message: 'context.context must be a NativeSecureContext'
47+
}
48+
);
4449

4550
{
4651
const buffer = Buffer.from('abcd');
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict';
2+
3+
// This tests the errors thrown from TLSSocket.prototype.setServername
4+
5+
const common = require('../common');
6+
const fixtures = require('../common/fixtures');
7+
8+
if (!common.hasCrypto)
9+
common.skip('missing crypto');
10+
11+
const { connect } = require('tls');
12+
const makeDuplexPair = require('../common/duplexpair');
13+
const { clientSide } = makeDuplexPair();
14+
15+
const ca = fixtures.readKey('ca1-cert.pem');
16+
17+
const client = connect({
18+
socket: clientSide,
19+
ca,
20+
host: 'agent1' // Hostname from certificate
21+
});
22+
23+
[undefined, null, 1, true, {}].forEach((value) => {
24+
common.expectsError(() => {
25+
client.setServername(value);
26+
}, {
27+
code: 'ERR_INVALID_ARG_TYPE',
28+
message: 'The "name" argument must be of type string'
29+
});
30+
});

0 commit comments

Comments
 (0)