Skip to content

Commit

Permalink
tls: move legacy code into own file
Browse files Browse the repository at this point in the history
PR-URL: #39333
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
  • Loading branch information
ronag committed Jul 11, 2021
1 parent bb275ef commit 5960f16
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 129 deletions.
5 changes: 4 additions & 1 deletion lib/_tls_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ const {

const {
configSecureContext,
} = require('internal/tls/secure-context');

const {
parseCertString,
} = require('internal/tls');
} = require('internal/tls/parse-cert-string');

function toV(which, v, def) {
if (v == null) v = def;
Expand Down
51 changes: 0 additions & 51 deletions lib/internal/streams/duplexpair.js

This file was deleted.

35 changes: 35 additions & 0 deletions lib/internal/tls/parse-cert-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

const {
ArrayIsArray,
ArrayPrototypeForEach,
ArrayPrototypePush,
StringPrototypeIndexOf,
StringPrototypeSlice,
StringPrototypeSplit,
ObjectCreate,
} = primordials;

// Example:
// C=US\nST=CA\nL=SF\nO=Joyent\nOU=Node.js\nCN=ca1\nemailAddress=ry@clouds.org
function parseCertString(s) {
const out = ObjectCreate(null);
ArrayPrototypeForEach(StringPrototypeSplit(s, '\n'), (part) => {
const sepIndex = StringPrototypeIndexOf(part, '=');
if (sepIndex > 0) {
const key = StringPrototypeSlice(part, 0, sepIndex);
const value = StringPrototypeSlice(part, sepIndex + 1);
if (key in out) {
if (!ArrayIsArray(out[key])) {
out[key] = [out[key]];
}
ArrayPrototypePush(out[key], value);
} else {
out[key] = value;
}
}
});
return out;
}

exports.parseCertString = parseCertString;
27 changes: 0 additions & 27 deletions lib/internal/tls.js → lib/internal/tls/secure-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@ const {
ArrayPrototypeFilter,
ArrayPrototypeForEach,
ArrayPrototypeJoin,
ArrayPrototypePush,
StringPrototypeIndexOf,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeStartsWith,
ObjectCreate,
} = primordials;

const {
Expand Down Expand Up @@ -42,28 +38,6 @@ const {
},
} = internalBinding('constants');

// Example:
// C=US\nST=CA\nL=SF\nO=Joyent\nOU=Node.js\nCN=ca1\nemailAddress=ry@clouds.org
function parseCertString(s) {
const out = ObjectCreate(null);
ArrayPrototypeForEach(StringPrototypeSplit(s, '\n'), (part) => {
const sepIndex = StringPrototypeIndexOf(part, '=');
if (sepIndex > 0) {
const key = StringPrototypeSlice(part, 0, sepIndex);
const value = StringPrototypeSlice(part, sepIndex + 1);
if (key in out) {
if (!ArrayIsArray(out[key])) {
out[key] = [out[key]];
}
ArrayPrototypePush(out[key], value);
} else {
out[key] = value;
}
}
});
return out;
}

function getDefaultEcdhCurve() {
// We do it this way because DEFAULT_ECDH_CURVE can be
// changed by users, so we need to grab the current
Expand Down Expand Up @@ -340,5 +314,4 @@ function configSecureContext(context, options = {}, name = 'options') {

module.exports = {
configSecureContext,
parseCertString,
};
86 changes: 86 additions & 0 deletions lib/internal/tls/secure-pair.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
'use strict';

const EventEmitter = require('events');
const { Duplex } = require('stream');
const _tls_wrap = require('_tls_wrap');
const _tls_common = require('_tls_common');

const {
Symbol,
ReflectConstruct,
} = primordials;

const kCallback = Symbol('Callback');
const kOtherSide = Symbol('Other');

class DuplexSocket extends Duplex {
constructor() {
super();
this[kCallback] = null;
this[kOtherSide] = null;
}

_read() {
const callback = this[kCallback];
if (callback) {
this[kCallback] = null;
callback();
}
}

_write(chunk, encoding, callback) {
if (chunk.length === 0) {
process.nextTick(callback);
} else {
this[kOtherSide].push(chunk);
this[kOtherSide][kCallback] = callback;
}
}

_final(callback) {
this[kOtherSide].on('end', callback);
this[kOtherSide].push(null);
}
}

class DuplexPair {
constructor() {
this.socket1 = new DuplexSocket();
this.socket2 = new DuplexSocket();
this.socket1[kOtherSide] = this.socket2;
this.socket2[kOtherSide] = this.socket1;
}
}

class SecurePair extends EventEmitter {
constructor(secureContext = _tls_common.createSecureContext(),
isServer = false,
requestCert = !isServer,
rejectUnauthorized = false,
options = {}) {
super();
const { socket1, socket2 } = new DuplexPair();

this.server = options.server;
this.credentials = secureContext;

this.encrypted = socket1;
this.cleartext = new _tls_wrap.TLSSocket(socket2, {
secureContext,
isServer,
requestCert,
rejectUnauthorized,
...options
});
this.cleartext.once('secure', () => this.emit('secure'));
}

destroy() {
this.cleartext.destroy();
this.encrypted.destroy();
}
}

exports.createSecurePair = function createSecurePair(...args) {
return ReflectConstruct(SecurePair, args);
};
53 changes: 9 additions & 44 deletions lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const {
ArrayPrototypeSome,
ObjectDefineProperty,
ObjectFreeze,
ReflectConstruct,
RegExpPrototypeTest,
StringFromCharCode,
StringPrototypeCharCodeAt,
Expand All @@ -50,19 +49,18 @@ const {
} = require('internal/errors').codes;
const internalUtil = require('internal/util');
internalUtil.assertCrypto();
const internalTLS = require('internal/tls');
const { isArrayBufferView } = require('internal/util/types');

const net = require('net');
const { getOptionValue } = require('internal/options');
const { getRootCertificates, getSSLCiphers } = internalBinding('crypto');
const { Buffer } = require('buffer');
const EventEmitter = require('events');
const { URL } = require('internal/url');
const DuplexPair = require('internal/streams/duplexpair');
const { canonicalizeIP } = internalBinding('cares_wrap');
const _tls_common = require('_tls_common');
const _tls_wrap = require('_tls_wrap');
const { createSecurePair } = require('internal/tls/secure-pair');
const { parseCertString } = require('internal/tls/parse-cert-string');

// Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations
// every {CLIENT_RENEG_WINDOW} seconds. An error event is emitted if more
Expand Down Expand Up @@ -300,53 +298,20 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
}
};


class SecurePair extends EventEmitter {
constructor(secureContext = exports.createSecureContext(),
isServer = false,
requestCert = !isServer,
rejectUnauthorized = false,
options = {}) {
super();
const { socket1, socket2 } = new DuplexPair();

this.server = options.server;
this.credentials = secureContext;

this.encrypted = socket1;
this.cleartext = new exports.TLSSocket(socket2, {
secureContext,
isServer,
requestCert,
rejectUnauthorized,
...options
});
this.cleartext.once('secure', () => this.emit('secure'));
}

destroy() {
this.cleartext.destroy();
this.encrypted.destroy();
}
}


exports.parseCertString = internalUtil.deprecate(
internalTLS.parseCertString,
'tls.parseCertString() is deprecated. ' +
'Please use querystring.parse() instead.',
'DEP0076');

exports.createSecureContext = _tls_common.createSecureContext;
exports.SecureContext = _tls_common.SecureContext;
exports.TLSSocket = _tls_wrap.TLSSocket;
exports.Server = _tls_wrap.Server;
exports.createServer = _tls_wrap.createServer;
exports.connect = _tls_wrap.connect;

exports.parseCertString = internalUtil.deprecate(
parseCertString,
'tls.parseCertString() is deprecated. ' +
'Please use querystring.parse() instead.',
'DEP0076');

exports.createSecurePair = internalUtil.deprecate(
function createSecurePair(...args) {
return ReflectConstruct(SecurePair, args);
},
createSecurePair,
'tls.createSecurePair() is deprecated. Please use ' +
'tls.TLSSocket instead.', 'DEP0064');
4 changes: 3 additions & 1 deletion src/node_native_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ void NativeModuleLoader::InitializeModuleCategories() {
"tls",
"_tls_common",
"_tls_wrap",
"internal/tls",
"internal/tls/secure-pair",
"internal/tls/parse-cert-string",
"internal/tls/secure-context",
"internal/http2/core",
"internal/http2/compat",
"internal/policy/manifest",
Expand Down
10 changes: 5 additions & 5 deletions test/parallel/test-tls-parse-cert-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const {
} = require('../common/hijackstdio');
const assert = require('assert');
// Flags: --expose-internals
const internalTLS = require('internal/tls');
const { parseCertString } = require('internal/tls/parse-cert-string');
const tls = require('tls');

const noOutput = common.mustNotCall();
Expand All @@ -20,7 +20,7 @@ hijackStderr(noOutput);
{
const singles = 'C=US\nST=CA\nL=SF\nO=Node.js Foundation\nOU=Node.js\n' +
'CN=ca1\nemailAddress=ry@clouds.org';
const singlesOut = internalTLS.parseCertString(singles);
const singlesOut = parseCertString(singles);
assert.deepStrictEqual(singlesOut, {
__proto__: null,
C: 'US',
Expand All @@ -36,7 +36,7 @@ hijackStderr(noOutput);
{
const doubles = 'OU=Domain Control Validated\nOU=PositiveSSL Wildcard\n' +
'CN=*.nodejs.org';
const doublesOut = internalTLS.parseCertString(doubles);
const doublesOut = parseCertString(doubles);
assert.deepStrictEqual(doublesOut, {
__proto__: null,
OU: [ 'Domain Control Validated', 'PositiveSSL Wildcard' ],
Expand All @@ -46,7 +46,7 @@ hijackStderr(noOutput);

{
const invalid = 'fhqwhgads';
const invalidOut = internalTLS.parseCertString(invalid);
const invalidOut = parseCertString(invalid);
assert.deepStrictEqual(invalidOut, { __proto__: null });
}

Expand All @@ -55,7 +55,7 @@ hijackStderr(noOutput);
const expected = Object.create(null);
expected.__proto__ = 'mostly harmless';
expected.hasOwnProperty = 'not a function';
assert.deepStrictEqual(internalTLS.parseCertString(input), expected);
assert.deepStrictEqual(parseCertString(input), expected);
}

restoreStderr();
Expand Down

0 comments on commit 5960f16

Please sign in to comment.