Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove tls.createSecurePair usage, closes #515 #689

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -44,6 +44,7 @@
"big-number": "0.3.1",
"bl": "^1.2.0",
"depd": "^1.1.2",
"duplexpair": "1.0.1",
"iconv-lite": "^0.4.11",
"readable-stream": "^2.2.6",
"sprintf-js": "^1.1.1",
Expand Down
66 changes: 51 additions & 15 deletions src/message-io.js
@@ -1,12 +1,15 @@
const tls = require('tls');
const crypto = require('crypto');
const DuplexPair = require('duplexpair');
const EventEmitter = require('events').EventEmitter;
const Transform = require('readable-stream').Transform;

const Packet = require('./packet').Packet;
const TYPE = require('./packet').TYPE;
const packetHeaderLength = require('./packet').HEADER_LENGTH;

const USE_LEGACY_SECUREPAIR = Number(process.versions.node[0]) <= 7;

class ReadablePacketStream extends Transform {
constructor() {
super({ objectMode: true });
Expand Down Expand Up @@ -84,25 +87,14 @@ module.exports = class MessageIO extends EventEmitter {
startTls(credentialsDetails, hostname, trustServerCertificate) {
const credentials = tls.createSecureContext ? tls.createSecureContext(credentialsDetails) : crypto.createCredentials(credentialsDetails);

this.securePair = tls.createSecurePair(credentials);
this.securePair = this.createSecurePair(credentials);
this.tlsNegotiationComplete = false;

this.securePair.on('secure', () => {
this.getSecurePairSecureTarget().on('secure', () => {
const cipher = this.securePair.cleartext.getCipher();

if (!trustServerCertificate) {
let verifyError = this.securePair.ssl.verifyError();

// Verify that server's identity matches it's certificate's names
if (!verifyError) {
verifyError = tls.checkServerIdentity(hostname, this.securePair.cleartext.getPeerCertificate());
}

if (verifyError) {
this.securePair.destroy();
this.socket.destroy(verifyError);
return;
}
if (!trustServerCertificate && !this.checkAuthorizationError(hostname)) {
return;
}

this.debug.log('TLS negotiated (' + cipher.name + ', ' + cipher.version + ')');
Expand Down Expand Up @@ -189,4 +181,48 @@ module.exports = class MessageIO extends EventEmitter {
resume() {
this.packetStream.resume();
}

createSecurePair(credentials) {
if (USE_LEGACY_SECUREPAIR) {
return tls.createSecurePair(credentials);
} else {
const duplexpair = new DuplexPair();
return {
cleartext: new tls.TLSSocket(duplexpair.socket1, {
secureContext: credentials,
rejectUnauthorized: false
}),
encrypted: duplexpair.socket2
};
}
}

checkAuthorizationError(hostname) {
let verifyError = null;
if (USE_LEGACY_SECUREPAIR) {
verifyError = this.securePair.ssl.verifyError();
// Verify that server's identity matches it's certificate's names
if (!verifyError) {
verifyError = tls.checkServerIdentity(hostname, this.securePair.cleartext.getPeerCertificate());
}
if (verifyError) {
this.securePair.destroy();
}
} else if (!this.securePair.cleartext.authorized) {
verifyError = this.securePair.cleartext.authorizationError;
}
if (verifyError) {
this.socket.destroy(verifyError);
return false;
}
return true;
}

getSecurePairSecureTarget() {
if (USE_LEGACY_SECUREPAIR) {
return this.securePair;
} else {
return this.securePair.cleartext;
}
}
};
2 changes: 1 addition & 1 deletion test/integration/connection-retry-test.js
Expand Up @@ -74,7 +74,7 @@ exports['connection retry tests'] = {
const config = getConfig();
config.options.connectTimeout = config.options.connectionRetryInterval / 2;

const clock = this.sinon.useFakeTimers();
const clock = this.sinon.useFakeTimers('setTimeout');

test.expect(1);

Expand Down