From f066ae4dd86b60ea2938fb5c21928bdf59f1340f Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 17 Nov 2020 23:09:52 +0100 Subject: tls: refactor to use more primordials PR-URL: https://github.com/nodejs/node/pull/36266 Reviewed-By: Rich Trott --- lib/tls.js | 61 ++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 23 deletions(-) (limited to 'lib/tls.js') diff --git a/lib/tls.js b/lib/tls.js index a46031ad7da..7ee9ae49f03 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -24,12 +24,22 @@ const { Array, ArrayIsArray, + ArrayPrototypeIncludes, + ArrayPrototypeJoin, + ArrayPrototypePush, + ArrayPrototypeReduce, + ArrayPrototypeSome, ObjectDefineProperty, ObjectFreeze, + RegExpPrototypeTest, StringFromCharCode, StringPrototypeCharCodeAt, + StringPrototypeEndsWith, + StringPrototypeIncludes, StringPrototypeReplace, + StringPrototypeSlice, StringPrototypeSplit, + StringPrototypeStartsWith, } = primordials; const { @@ -107,7 +117,7 @@ ObjectDefineProperty(exports, 'rootCertificates', { // ("\x06spdy/2\x08http/1.1\x08http/1.0") function convertProtocols(protocols) { const lens = new Array(protocols.length); - const buff = Buffer.allocUnsafe(protocols.reduce((p, c, i) => { + const buff = Buffer.allocUnsafe(ArrayPrototypeReduce(protocols, (p, c, i) => { const len = Buffer.byteLength(c); if (len > 255) { throw new ERR_OUT_OF_RANGE('The byte length of the protocol at index ' + @@ -138,7 +148,7 @@ exports.convertALPNProtocols = function convertALPNProtocols(protocols, out) { }; function unfqdn(host) { - return host.replace(/[.]$/, ''); + return StringPrototypeReplace(host, /[.]$/, ''); } // String#toLowerCase() is locale-sensitive so we use @@ -165,15 +175,15 @@ function check(hostParts, pattern, wildcards) { return false; // Pattern has empty components, e.g. "bad..example.com". - if (patternParts.includes('')) + if (ArrayPrototypeIncludes(patternParts, '')) return false; // RFC 6125 allows IDNA U-labels (Unicode) in names but we have no // good way to detect their encoding or normalize them so we simply // reject them. Control characters and blanks are rejected as well // because nothing good can come from accepting them. - const isBad = (s) => /[^\u0021-\u007F]/u.test(s); - if (patternParts.some(isBad)) + const isBad = (s) => RegExpPrototypeTest(/[^\u0021-\u007F]/u, s); + if (ArrayPrototypeSome(patternParts, isBad)) return false; // Check host parts from right to left first. @@ -184,12 +194,13 @@ function check(hostParts, pattern, wildcards) { const hostSubdomain = hostParts[0]; const patternSubdomain = patternParts[0]; - const patternSubdomainParts = patternSubdomain.split('*'); + const patternSubdomainParts = StringPrototypeSplit(patternSubdomain, '*'); // Short-circuit when the subdomain does not contain a wildcard. // RFC 6125 does not allow wildcard substitution for components // containing IDNA A-labels (Punycode) so match those verbatim. - if (patternSubdomainParts.length === 1 || patternSubdomain.includes('xn--')) + if (patternSubdomainParts.length === 1 || + StringPrototypeIncludes(patternSubdomain, 'xn--')) return hostSubdomain === patternSubdomain; if (!wildcards) @@ -208,10 +219,10 @@ function check(hostParts, pattern, wildcards) { if (prefix.length + suffix.length > hostSubdomain.length) return false; - if (!hostSubdomain.startsWith(prefix)) + if (!StringPrototypeStartsWith(hostSubdomain, prefix)) return false; - if (!hostSubdomain.endsWith(suffix)) + if (!StringPrototypeEndsWith(hostSubdomain, suffix)) return false; return true; @@ -228,28 +239,30 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { hostname = '' + hostname; if (altNames) { - for (const name of altNames.split(', ')) { - if (name.startsWith('DNS:')) { - dnsNames.push(name.slice(4)); - } else if (name.startsWith('URI:')) { + for (const name of StringPrototypeSplit(altNames, ', ')) { + if (StringPrototypeStartsWith(name, 'DNS:')) { + ArrayPrototypePush(dnsNames, StringPrototypeSlice(name, 4)); + } else if (StringPrototypeStartsWith(name, 'URI:')) { let uri; try { - uri = new URL(name.slice(4)); + uri = new URL(StringPrototypeSlice(name, 4)); } catch { - uri = url.parse(name.slice(4)); + const slicedName = StringPrototypeSlice(name, 4); + uri = url.parse(slicedName); if (!urlWarningEmitted && !process.noDeprecation) { urlWarningEmitted = true; process.emitWarning( - `The URI ${name.slice(4)} found in cert.subjectaltname ` + + `The URI ${slicedName} found in cert.subjectaltname ` + 'is not a valid URI, and is supported in the tls module ' + 'solely for compatibility.', 'DeprecationWarning', 'DEP0109'); } } - uriNames.push(uri.hostname); // TODO(bnoordhuis) Also use scheme. - } else if (name.startsWith('IP Address:')) { - ips.push(canonicalizeIP(name.slice(11))); + // TODO(bnoordhuis) Also use scheme. + ArrayPrototypePush(uriNames, uri.hostname); + } else if (StringPrototypeStartsWith(name, 'IP Address:')) { + ArrayPrototypePush(ips, canonicalizeIP(StringPrototypeSlice(name, 11))); } } } @@ -263,9 +276,10 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { hostname = unfqdn(hostname); // Remove trailing dot for error messages. if (net.isIP(hostname)) { - valid = ips.includes(canonicalizeIP(hostname)); + valid = ArrayPrototypeIncludes(ips, canonicalizeIP(hostname)); if (!valid) - reason = `IP: ${hostname} is not in the cert's list: ${ips.join(', ')}`; + reason = `IP: ${hostname} is not in the cert's list: ` + + ArrayPrototypeJoin(ips, ', '); // TODO(bnoordhuis) Also check URI SANs that are IP addresses. } else if (hasAltNames || subject) { const hostParts = splitHost(hostname); @@ -273,7 +287,8 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { if (hasAltNames) { const noWildcard = (pattern) => check(hostParts, pattern, false); - valid = dnsNames.some(wildcard) || uriNames.some(noWildcard); + valid = ArrayPrototypeSome(dnsNames, wildcard) || + ArrayPrototypeSome(uriNames, noWildcard); if (!valid) reason = `Host: ${hostname}. is not in the cert's altnames: ${altNames}`; @@ -282,7 +297,7 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { const cn = subject.CN; if (ArrayIsArray(cn)) - valid = cn.some(wildcard); + valid = ArrayPrototypeSome(cn, wildcard); else if (cn) valid = wildcard(cn); -- cgit v1.2.3