Skip to content

Commit b20409e

Browse files
aduh95danielleadams
authored andcommitted
tls: refactor to use more primordials
PR-URL: #36266 Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 9cb53f6 commit b20409e

4 files changed

Lines changed: 91 additions & 59 deletions

File tree

‎lib/_tls_common.js‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ const {
2525
ArrayIsArray,
2626
ArrayPrototypeFilter,
2727
ArrayPrototypeJoin,
28+
ArrayPrototypePush,
2829
ObjectCreate,
30+
StringPrototypeReplace,
2931
StringPrototypeSplit,
3032
StringPrototypeStartsWith,
3133
}=primordials;
@@ -392,12 +394,13 @@ exports.translatePeerCertificate = function translatePeerCertificate(c) {
392394
c.infoAccess=ObjectCreate(null);
393395

394396
// XXX: More key validation?
395-
info.replace(/([^\n:]*):([^\n]*)(?:\n|$)/g,(all,key,val)=>{
396-
if(keyinc.infoAccess)
397-
c.infoAccess[key].push(val);
398-
else
399-
c.infoAccess[key]=[val];
400-
});
397+
StringPrototypeReplace(info,/([^\n:]*):([^\n]*)(?:\n|$)/g,
398+
(all,key,val)=>{
399+
if(keyinc.infoAccess)
400+
ArrayPrototypePush(c.infoAccess[key],val);
401+
else
402+
c.infoAccess[key]=[val];
403+
});
401404
}
402405
returnc;
403406
};

‎lib/_tls_wrap.js‎

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@
2222
'use strict';
2323

2424
const{
25+
ArrayPrototypeForEach,
26+
ArrayPrototypeJoin,
27+
ArrayPrototypePush,
28+
FunctionPrototype,
2529
ObjectAssign,
2630
ObjectDefineProperty,
2731
ObjectSetPrototypeOf,
32+
ReflectApply,
2833
RegExp,
34+
RegExpPrototypeTest,
35+
StringPrototypeReplace,
36+
StringPrototypeSlice,
2937
Symbol,
3038
SymbolFor,
3139
}=primordials;
@@ -96,7 +104,7 @@ const kPskIdentityHint = Symbol('pskidentityhint');
96104
constkPendingSession=Symbol('pendingSession');
97105
constkIsVerified=Symbol('verified');
98106

99-
constnoop=()=>{};
107+
constnoop=FunctionPrototype;
100108

101109
letipServernameWarned=false;
102110
lettlsTracingWarned=false;
@@ -408,7 +416,8 @@ function onerror(err) {
408416
owner.destroy(err);
409417
}elseif(owner._tlsOptions.isServer&&
410418
owner._rejectUnauthorized&&
411-
/peerdidnotreturnacertificate/.test(err.message)){
419+
RegExpPrototypeTest(/peerdidnotreturnacertificate/,
420+
err.message)){
412421
// Ignore server's authorization errors
413422
owner.destroy();
414423
}else{
@@ -496,14 +505,14 @@ function TLSSocket(socket, opts) {
496505
// distinguishable from regular ones.
497506
this.encrypted=true;
498507

499-
net.Socket.call(this,{
508+
ReflectApply(net.Socket,this,[{
500509
handle: this._wrapHandle(wrap),
501510
allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen,
502511
pauseOnCreate: tlsOptions.pauseOnConnect,
503512
manualStart: true,
504513
highWaterMark: tlsOptions.highWaterMark,
505514
onread: !socket ? tlsOptions.onread : null,
506-
});
515+
}]);
507516

508517
// Proxy for API compatibility
509518
this.ssl=this._handle;// C++ TLSWrap object
@@ -535,7 +544,7 @@ const proxiedMethods = [
535544
functionmakeMethodProxy(name){
536545
returnfunctionmethodProxy(...args){
537546
if(this._parent[name])
538-
returnthis._parent[name].apply(this._parent,args);
547+
returnReflectApply(this._parent[name],this._parent,args);
539548
};
540549
}
541550
for(constproxiedMethodofproxiedMethods){
@@ -993,12 +1002,12 @@ TLSSocket.prototype.getCertificate = function() {
9931002
functionmakeSocketMethodProxy(name){
9941003
returnfunctionsocketMethodProxy(...args){
9951004
if(this._handle)
996-
returnthis._handle[name].apply(this._handle,args);
1005+
returnReflectApply(this._handle[name],this._handle,args);
9971006
returnnull;
9981007
};
9991008
}
10001009

1001-
[
1010+
ArrayPrototypeForEach([
10021011
'getCipher',
10031012
'getSharedSigalgs',
10041013
'getEphemeralKeyInfo',
@@ -1009,7 +1018,7 @@ function makeSocketMethodProxy(name) {
10091018
'getTLSTicket',
10101019
'isSessionReused',
10111020
'enableTrace',
1012-
].forEach((method)=>{
1021+
],(method)=>{
10131022
TLSSocket.prototype[method]=makeSocketMethodProxy(method);
10141023
});
10151024

@@ -1209,7 +1218,7 @@ function Server(options, listener) {
12091218
}
12101219

12111220
// constructor call
1212-
net.Server.call(this,options,tlsConnectionListener);
1221+
ReflectApply(net.Server,this,[options,tlsConnectionListener]);
12131222

12141223
if(listener){
12151224
this.on('secureConnection',listener);
@@ -1309,10 +1318,10 @@ Server.prototype.setSecureContext = function(options) {
13091318
if(options.sessionIdContext){
13101319
this.sessionIdContext=options.sessionIdContext;
13111320
}else{
1312-
this.sessionIdContext=crypto.createHash('sha1')
1313-
.update(process.argv.join(' '))
1314-
.digest('hex')
1315-
.slice(0,32);
1321+
this.sessionIdContext=StringPrototypeSlice(
1322+
crypto.createHash('sha1')
1323+
.update(ArrayPrototypeJoin(process.argv,' '))
1324+
.digest('hex'),0,32);
13161325
}
13171326

13181327
if(options.sessionTimeout)
@@ -1399,10 +1408,10 @@ Server.prototype.setOptions = deprecate(function(options) {
13991408
if(options.sessionIdContext){
14001409
this.sessionIdContext=options.sessionIdContext;
14011410
}else{
1402-
this.sessionIdContext=crypto.createHash('sha1')
1403-
.update(process.argv.join(' '))
1404-
.digest('hex')
1405-
.slice(0,32);
1411+
this.sessionIdContext=StringPrototypeSlice(
1412+
crypto.createHash('sha1')
1413+
.update(ArrayPrototypeJoin(process.argv,' '))
1414+
.digest('hex'),0,32);
14061415
}
14071416
if(options.pskCallback)this[kPskCallback]=options.pskCallback;
14081417
if(options.pskIdentityHint)this[kPskIdentityHint]=options.pskIdentityHint;
@@ -1414,11 +1423,12 @@ Server.prototype.addContext = function(servername, context) {
14141423
thrownewERR_TLS_REQUIRED_SERVER_NAME();
14151424
}
14161425

1417-
constre=newRegExp('^'+
1418-
servername.replace(/([.^$+?\-\\[\]{}])/g,'\\$1')
1419-
.replace(/\*/g,'[^.]*')+
1420-
'$');
1421-
this._contexts.push([re,tls.createSecureContext(context).context]);
1426+
constre=newRegExp('^'+StringPrototypeReplace(
1427+
StringPrototypeReplace(servername,/([.^$+?\-\\[\]{}])/g,'\\$1'),
1428+
/\*/g,'[^.]*'
1429+
)+'$');
1430+
ArrayPrototypePush(this._contexts,
1431+
[re,tls.createSecureContext(context).context]);
14221432
};
14231433

14241434
Server.prototype[EE.captureRejectionSymbol]=function(
@@ -1429,16 +1439,16 @@ Server.prototype[EE.captureRejectionSymbol] = function(
14291439
sock.destroy(err);
14301440
break;
14311441
default:
1432-
net.Server.prototype[SymbolFor('nodejs.rejection')]
1433-
.call(this,err,event,sock);
1442+
ReflectApply(net.Server.prototype[SymbolFor('nodejs.rejection')],this,
1443+
[err,event,sock]);
14341444
}
14351445
};
14361446

14371447
functionSNICallback(servername,callback){
14381448
constcontexts=this.server._contexts;
14391449

14401450
for(constelemofcontexts){
1441-
if(elem[0].test(servername)){
1451+
if(RegExpPrototypeTest(elem[0],servername)){
14421452
callback(null,elem[1]);
14431453
return;
14441454
}

‎lib/internal/tls.js‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,27 @@
22

33
const{
44
ArrayIsArray,
5+
ArrayPrototypePush,
6+
StringPrototypeIndexOf,
7+
StringPrototypeSlice,
8+
StringPrototypeSplit,
59
ObjectCreate,
610
}=primordials;
711

812
// Example:
913
// C=US\nST=CA\nL=SF\nO=Joyent\nOU=Node.js\nCN=ca1\nemailAddress=ry@clouds.org
1014
functionparseCertString(s){
1115
constout=ObjectCreate(null);
12-
for(constpartofs.split('\n')){
13-
constsepIndex=part.indexOf('=');
16+
for(constpartofStringPrototypeSplit(s,'\n')){
17+
constsepIndex=StringPrototypeIndexOf(part,'=');
1418
if(sepIndex>0){
15-
constkey=part.slice(0,sepIndex);
16-
constvalue=part.slice(sepIndex+1);
19+
constkey=StringPrototypeSlice(part,0,sepIndex);
20+
constvalue=StringPrototypeSlice(part,sepIndex+1);
1721
if(keyinout){
1822
if(!ArrayIsArray(out[key])){
1923
out[key]=[out[key]];
2024
}
21-
out[key].push(value);
25+
ArrayPrototypePush(out[key],value);
2226
}else{
2327
out[key]=value;
2428
}

‎lib/tls.js‎

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,22 @@
2424
const{
2525
Array,
2626
ArrayIsArray,
27+
ArrayPrototypeIncludes,
28+
ArrayPrototypeJoin,
29+
ArrayPrototypePush,
30+
ArrayPrototypeReduce,
31+
ArrayPrototypeSome,
2732
ObjectDefineProperty,
2833
ObjectFreeze,
34+
RegExpPrototypeTest,
2935
StringFromCharCode,
3036
StringPrototypeCharCodeAt,
37+
StringPrototypeEndsWith,
38+
StringPrototypeIncludes,
3139
StringPrototypeReplace,
40+
StringPrototypeSlice,
3241
StringPrototypeSplit,
42+
StringPrototypeStartsWith,
3343
}=primordials;
3444

3545
const{
@@ -107,7 +117,7 @@ ObjectDefineProperty(exports, 'rootCertificates', {
107117
// ("\x06spdy/2\x08http/1.1\x08http/1.0")
108118
functionconvertProtocols(protocols){
109119
constlens=newArray(protocols.length);
110-
constbuff=Buffer.allocUnsafe(protocols.reduce((p,c,i)=>{
120+
constbuff=Buffer.allocUnsafe(ArrayPrototypeReduce(protocols,(p,c,i)=>{
111121
constlen=Buffer.byteLength(c);
112122
if(len>255){
113123
thrownewERR_OUT_OF_RANGE('The byte length of the protocol at index '+
@@ -138,7 +148,7 @@ exports.convertALPNProtocols = function convertALPNProtocols(protocols, out) {
138148
};
139149

140150
functionunfqdn(host){
141-
returnhost.replace(/[.]$/,'');
151+
returnStringPrototypeReplace(host,/[.]$/,'');
142152
}
143153

144154
// String#toLowerCase() is locale-sensitive so we use
@@ -165,15 +175,15 @@ function check(hostParts, pattern, wildcards) {
165175
returnfalse;
166176

167177
// Pattern has empty components, e.g. "bad..example.com".
168-
if(patternParts.includes(''))
178+
if(ArrayPrototypeIncludes(patternParts,''))
169179
returnfalse;
170180

171181
// RFC 6125 allows IDNA U-labels (Unicode) in names but we have no
172182
// good way to detect their encoding or normalize them so we simply
173183
// reject them. Control characters and blanks are rejected as well
174184
// because nothing good can come from accepting them.
175-
constisBad=(s)=>/[^\u0021-\u007F]/u.test(s);
176-
if(patternParts.some(isBad))
185+
constisBad=(s)=>RegExpPrototypeTest(/[^\u0021-\u007F]/u,s);
186+
if(ArrayPrototypeSome(patternParts,isBad))
177187
returnfalse;
178188

179189
// Check host parts from right to left first.
@@ -184,12 +194,13 @@ function check(hostParts, pattern, wildcards) {
184194

185195
consthostSubdomain=hostParts[0];
186196
constpatternSubdomain=patternParts[0];
187-
constpatternSubdomainParts=patternSubdomain.split('*');
197+
constpatternSubdomainParts=StringPrototypeSplit(patternSubdomain,'*');
188198

189199
// Short-circuit when the subdomain does not contain a wildcard.
190200
// RFC 6125 does not allow wildcard substitution for components
191201
// containing IDNA A-labels (Punycode) so match those verbatim.
192-
if(patternSubdomainParts.length===1||patternSubdomain.includes('xn--'))
202+
if(patternSubdomainParts.length===1||
203+
StringPrototypeIncludes(patternSubdomain,'xn--'))
193204
returnhostSubdomain===patternSubdomain;
194205

195206
if(!wildcards)
@@ -208,10 +219,10 @@ function check(hostParts, pattern, wildcards) {
208219
if(prefix.length+suffix.length>hostSubdomain.length)
209220
returnfalse;
210221

211-
if(!hostSubdomain.startsWith(prefix))
222+
if(!StringPrototypeStartsWith(hostSubdomain,prefix))
212223
returnfalse;
213224

214-
if(!hostSubdomain.endsWith(suffix))
225+
if(!StringPrototypeEndsWith(hostSubdomain,suffix))
215226
returnfalse;
216227

217228
returntrue;
@@ -228,28 +239,30 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
228239
hostname=''+hostname;
229240

230241
if(altNames){
231-
for(constnameofaltNames.split(', ')){
232-
if(name.startsWith('DNS:')){
233-
dnsNames.push(name.slice(4));
234-
}elseif(name.startsWith('URI:')){
242+
for(constnameofStringPrototypeSplit(altNames,', ')){
243+
if(StringPrototypeStartsWith(name,'DNS:')){
244+
ArrayPrototypePush(dnsNames,StringPrototypeSlice(name,4));
245+
}elseif(StringPrototypeStartsWith(name,'URI:')){
235246
leturi;
236247
try{
237-
uri=newURL(name.slice(4));
248+
uri=newURL(StringPrototypeSlice(name,4));
238249
}catch{
239-
uri=url.parse(name.slice(4));
250+
constslicedName=StringPrototypeSlice(name,4);
251+
uri=url.parse(slicedName);
240252
if(!urlWarningEmitted&&!process.noDeprecation){
241253
urlWarningEmitted=true;
242254
process.emitWarning(
243-
`The URI ${name.slice(4)} found in cert.subjectaltname `+
255+
`The URI ${slicedName} found in cert.subjectaltname `+
244256
'is not a valid URI, and is supported in the tls module '+
245257
'solely for compatibility.',
246258
'DeprecationWarning','DEP0109');
247259
}
248260
}
249261

250-
uriNames.push(uri.hostname);// TODO(bnoordhuis) Also use scheme.
251-
}elseif(name.startsWith('IP Address:')){
252-
ips.push(canonicalizeIP(name.slice(11)));
262+
// TODO(bnoordhuis) Also use scheme.
263+
ArrayPrototypePush(uriNames,uri.hostname);
264+
}elseif(StringPrototypeStartsWith(name,'IP Address:')){
265+
ArrayPrototypePush(ips,canonicalizeIP(StringPrototypeSlice(name,11)));
253266
}
254267
}
255268
}
@@ -263,17 +276,19 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
263276
hostname=unfqdn(hostname);// Remove trailing dot for error messages.
264277

265278
if(net.isIP(hostname)){
266-
valid=ips.includes(canonicalizeIP(hostname));
279+
valid=ArrayPrototypeIncludes(ips,canonicalizeIP(hostname));
267280
if(!valid)
268-
reason=`IP: ${hostname} is not in the cert's list: ${ips.join(', ')}`;
281+
reason=`IP: ${hostname} is not in the cert's list: `+
282+
ArrayPrototypeJoin(ips,', ');
269283
// TODO(bnoordhuis) Also check URI SANs that are IP addresses.
270284
}elseif(hasAltNames||subject){
271285
consthostParts=splitHost(hostname);
272286
constwildcard=(pattern)=>check(hostParts,pattern,true);
273287

274288
if(hasAltNames){
275289
constnoWildcard=(pattern)=>check(hostParts,pattern,false);
276-
valid=dnsNames.some(wildcard)||uriNames.some(noWildcard);
290+
valid=ArrayPrototypeSome(dnsNames,wildcard)||
291+
ArrayPrototypeSome(uriNames,noWildcard);
277292
if(!valid)
278293
reason=
279294
`Host: ${hostname}. is not in the cert's altnames: ${altNames}`;
@@ -282,7 +297,7 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
282297
constcn=subject.CN;
283298

284299
if(ArrayIsArray(cn))
285-
valid=cn.some(wildcard);
300+
valid=ArrayPrototypeSome(cn,wildcard);
286301
elseif(cn)
287302
valid=wildcard(cn);
288303

0 commit comments

Comments
 (0)