Skip to content

Commit 0b10714

Browse files
committed
SNI support for encrypted connections
This commit enables SNI for TLS connections by making them send the target hostname in the first TLS message. It is done by simply adding a new TLS connection option called `servername`.
1 parent c3d2ec9 commit 0b10714

File tree

1 file changed

+22
-25
lines changed

1 file changed

+22
-25
lines changed

src/v1/internal/ch-node.js

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,8 @@ const TrustStrategy = {
123123
return;
124124
}
125125

126-
let tlsOpts = {
127-
ca: config.trustedCertificates.map((f) => fs.readFileSync(f)),
128-
// Because we manually check for this in the connect callback, to give
129-
// a more helpful error to the user
130-
rejectUnauthorized: false
131-
};
132-
133-
let socket = tls.connect(config.url.port, config.url.host, tlsOpts, function () {
126+
const tlsOpts = newTlsOptions(config.url.host, config.trustedCertificates.map((f) => fs.readFileSync(f)));
127+
const socket = tls.connect(config.url.port, config.url.host, tlsOpts, function () {
134128
if (!socket.authorized) {
135129
onFailure(newError("Server certificate is not trusted. If you trust the database you are connecting to, add" +
136130
" the signing certificate, or the server certificate, to the list of certificates trusted by this driver" +
@@ -146,13 +140,8 @@ const TrustStrategy = {
146140
return socket;
147141
},
148142
TRUST_SYSTEM_CA_SIGNED_CERTIFICATES : function( config, onSuccess, onFailure ) {
149-
150-
let tlsOpts = {
151-
// Because we manually check for this in the connect callback, to give
152-
// a more helpful error to the user
153-
rejectUnauthorized: false
154-
};
155-
let socket = tls.connect(config.url.port, config.url.host, tlsOpts, function () {
143+
const tlsOpts = newTlsOptions(config.url.host);
144+
const socket = tls.connect(config.url.port, config.url.host, tlsOpts, function () {
156145
if (!socket.authorized) {
157146
onFailure(newError("Server certificate is not trusted. If you trust the database you are connecting to, use " +
158147
"TRUST_CUSTOM_CA_SIGNED_CERTIFICATES and add" +
@@ -175,13 +164,9 @@ const TrustStrategy = {
175164
console.warn('`TRUST_ON_FIRST_USE` has been deprecated as option and will be removed in a future version of ' +
176165
"the driver. Please use `TRUST_ALL_CERTIFICATES` instead.");
177166

178-
let tlsOpts = {
179-
// Because we manually verify the certificate against known_hosts
180-
rejectUnauthorized: false
181-
};
182-
183-
let socket = tls.connect(config.url.port, config.url.host, tlsOpts, function () {
184-
var serverCert = socket.getPeerCertificate(/*raw=*/true);
167+
const tlsOpts = newTlsOptions(config.url.host);
168+
const socket = tls.connect(config.url.port, config.url.host, tlsOpts, function () {
169+
const serverCert = socket.getPeerCertificate(/*raw=*/true);
185170

186171
if( !serverCert.raw ) {
187172
// If `raw` is not available, we're on an old version of NodeJS, and
@@ -229,9 +214,7 @@ const TrustStrategy = {
229214
},
230215

231216
TRUST_ALL_CERTIFICATES: function (config, onSuccess, onFailure) {
232-
const tlsOpts = {
233-
rejectUnauthorized: false
234-
};
217+
const tlsOpts = newTlsOptions(config.url.host);
235218
const socket = tls.connect(config.url.port, config.url.host, tlsOpts, function () {
236219
const certificate = socket.getPeerCertificate();
237220
if (isEmptyObjectOrNull(certificate)) {
@@ -275,6 +258,20 @@ function connect( config, onSuccess, onFailure=(()=>null) ) {
275258
}
276259
}
277260

261+
/**
262+
* Create a new configuration options object for the {@code tls.connect()} call.
263+
* @param {string} hostname the target hostname.
264+
* @param {string|undefined} ca an optional CA.
265+
* @return {object} a new options object.
266+
*/
267+
function newTlsOptions(hostname, ca = undefined) {
268+
return {
269+
rejectUnauthorized: false, // we manually check for this in the connect callback, to give a more helpful error to the user
270+
servername: hostname, // server name for the SNI (Server Name Indication) TLS extension
271+
ca: ca, // optional CA useful for TRUST_CUSTOM_CA_SIGNED_CERTIFICATES trust mode
272+
};
273+
}
274+
278275
/**
279276
* In a Node.js environment the 'net' module is used
280277
* as transport.

0 commit comments

Comments
 (0)