lib: deprecate _tls_common and _tls_wrap

runtime deprecate the _tls_common and _tls_wrap
modules, users should use nust node:tls insteal
and internally internal/tls/commond and
internal/tls/wrap should be used instead

PR-URL: https://github.com/nodejs/node/pull/57643
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
Dario Piotrowicz 2025-05-11 00:10:43 +01:00 committed by GitHub
parent 6710c00e56
commit a822a1cbe7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 2000 additions and 1941 deletions

View File

@ -3904,6 +3904,20 @@ of built-in modules. This was incomplete and matched the already deprecated
`repl._builtinLibs` ([DEP0142][]) instead it's better to rely `repl._builtinLibs` ([DEP0142][]) instead it's better to rely
upon `require('node:module').builtinModules`. upon `require('node:module').builtinModules`.
### DEP0192: `require('node:_tls_common')` and `require('node:_tls_wrap')`
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/57643
description: Runtime deprecation.
-->
Type: Runtime
The `node:_tls_common` and `node:_tls_wrap` modules are deprecated as they should be considered
an internal nodejs implementation rather than a public facing API, use `node:tls` instead.
[DEP0142]: #dep0142-repl_builtinlibs [DEP0142]: #dep0142-repl_builtinlibs
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3

View File

@ -1,156 +1,10 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict'; 'use strict';
const { const { SecureContext, createSecureContext, translatePeerCertificate } = require('internal/tls/common');
JSONParse,
} = primordials;
const tls = require('tls');
const {
codes: {
ERR_TLS_INVALID_PROTOCOL_VERSION,
ERR_TLS_PROTOCOL_VERSION_CONFLICT,
},
} = require('internal/errors');
const {
crypto: {
SSL_OP_CIPHER_SERVER_PREFERENCE,
TLS1_VERSION,
TLS1_1_VERSION,
TLS1_2_VERSION,
TLS1_3_VERSION,
},
} = internalBinding('constants');
const {
kEmptyObject,
} = require('internal/util');
const {
validateInteger,
} = require('internal/validators');
const {
configSecureContext,
} = require('internal/tls/secure-context');
function toV(which, v, def) {
v ??= def;
if (v === 'TLSv1') return TLS1_VERSION;
if (v === 'TLSv1.1') return TLS1_1_VERSION;
if (v === 'TLSv1.2') return TLS1_2_VERSION;
if (v === 'TLSv1.3') return TLS1_3_VERSION;
throw new ERR_TLS_INVALID_PROTOCOL_VERSION(v, which);
}
const {
SecureContext: NativeSecureContext,
} = internalBinding('crypto');
function SecureContext(secureProtocol, secureOptions, minVersion, maxVersion) {
if (!(this instanceof SecureContext)) {
return new SecureContext(secureProtocol, secureOptions, minVersion,
maxVersion);
}
if (secureProtocol) {
if (minVersion != null)
throw new ERR_TLS_PROTOCOL_VERSION_CONFLICT(minVersion, secureProtocol);
if (maxVersion != null)
throw new ERR_TLS_PROTOCOL_VERSION_CONFLICT(maxVersion, secureProtocol);
}
this.context = new NativeSecureContext();
this.context.init(secureProtocol,
toV('minimum', minVersion, tls.DEFAULT_MIN_VERSION),
toV('maximum', maxVersion, tls.DEFAULT_MAX_VERSION));
if (secureOptions) {
validateInteger(secureOptions, 'secureOptions');
this.context.setOptions(secureOptions);
}
}
function createSecureContext(options) {
options ||= kEmptyObject;
const {
honorCipherOrder,
minVersion,
maxVersion,
secureProtocol,
} = options;
let { secureOptions } = options;
if (honorCipherOrder)
secureOptions |= SSL_OP_CIPHER_SERVER_PREFERENCE;
const c = new SecureContext(secureProtocol, secureOptions,
minVersion, maxVersion);
configSecureContext(c.context, options);
return c;
}
// Translate some fields from the handle's C-friendly format into more idiomatic
// javascript object representations before passing them back to the user. Can
// be used on any cert object, but changing the name would be semver-major.
function translatePeerCertificate(c) {
if (!c)
return null;
if (c.issuerCertificate != null && c.issuerCertificate !== c) {
c.issuerCertificate = translatePeerCertificate(c.issuerCertificate);
}
if (c.infoAccess != null) {
const info = c.infoAccess;
c.infoAccess = { __proto__: null };
// XXX: More key validation?
info.replace(/([^\n:]*):([^\n]*)(?:\n|$)/g,
(all, key, val) => {
if (val.charCodeAt(0) === 0x22) {
// The translatePeerCertificate function is only
// used on internally created legacy certificate
// objects, and any value that contains a quote
// will always be a valid JSON string literal,
// so this should never throw.
val = JSONParse(val);
}
if (key in c.infoAccess)
c.infoAccess[key].push(val);
else
c.infoAccess[key] = [val];
});
}
return c;
}
module.exports = { module.exports = {
SecureContext, SecureContext,
createSecureContext, createSecureContext,
translatePeerCertificate, translatePeerCertificate,
}; };
process.emitWarning('The _tls_common module is deprecated.',
'DeprecationWarning', 'DEP0192');

File diff suppressed because it is too large Load Diff

View File

@ -371,7 +371,7 @@ class X509Certificate {
// TODO(tniessen): do not depend on translatePeerCertificate here, return // TODO(tniessen): do not depend on translatePeerCertificate here, return
// the correct legacy representation from the binding // the correct legacy representation from the binding
lazyTranslatePeerCertificate ??= lazyTranslatePeerCertificate ??=
require('_tls_common').translatePeerCertificate; require('internal/tls/common').translatePeerCertificate;
return lazyTranslatePeerCertificate(this[kHandle].toLegacy()); return lazyTranslatePeerCertificate(this[kHandle].toLegacy());
} }
} }

156
lib/internal/tls/common.js Normal file
View File

@ -0,0 +1,156 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
const {
JSONParse,
} = primordials;
const tls = require('tls');
const {
codes: {
ERR_TLS_INVALID_PROTOCOL_VERSION,
ERR_TLS_PROTOCOL_VERSION_CONFLICT,
},
} = require('internal/errors');
const {
crypto: {
SSL_OP_CIPHER_SERVER_PREFERENCE,
TLS1_VERSION,
TLS1_1_VERSION,
TLS1_2_VERSION,
TLS1_3_VERSION,
},
} = internalBinding('constants');
const {
kEmptyObject,
} = require('internal/util');
const {
validateInteger,
} = require('internal/validators');
const {
configSecureContext,
} = require('internal/tls/secure-context');
function toV(which, v, def) {
v ??= def;
if (v === 'TLSv1') return TLS1_VERSION;
if (v === 'TLSv1.1') return TLS1_1_VERSION;
if (v === 'TLSv1.2') return TLS1_2_VERSION;
if (v === 'TLSv1.3') return TLS1_3_VERSION;
throw new ERR_TLS_INVALID_PROTOCOL_VERSION(v, which);
}
const {
SecureContext: NativeSecureContext,
} = internalBinding('crypto');
function SecureContext(secureProtocol, secureOptions, minVersion, maxVersion) {
if (!(this instanceof SecureContext)) {
return new SecureContext(secureProtocol, secureOptions, minVersion,
maxVersion);
}
if (secureProtocol) {
if (minVersion != null)
throw new ERR_TLS_PROTOCOL_VERSION_CONFLICT(minVersion, secureProtocol);
if (maxVersion != null)
throw new ERR_TLS_PROTOCOL_VERSION_CONFLICT(maxVersion, secureProtocol);
}
this.context = new NativeSecureContext();
this.context.init(secureProtocol,
toV('minimum', minVersion, tls.DEFAULT_MIN_VERSION),
toV('maximum', maxVersion, tls.DEFAULT_MAX_VERSION));
if (secureOptions) {
validateInteger(secureOptions, 'secureOptions');
this.context.setOptions(secureOptions);
}
}
function createSecureContext(options) {
options ||= kEmptyObject;
const {
honorCipherOrder,
minVersion,
maxVersion,
secureProtocol,
} = options;
let { secureOptions } = options;
if (honorCipherOrder)
secureOptions |= SSL_OP_CIPHER_SERVER_PREFERENCE;
const c = new SecureContext(secureProtocol, secureOptions,
minVersion, maxVersion);
configSecureContext(c.context, options);
return c;
}
// Translate some fields from the handle's C-friendly format into more idiomatic
// javascript object representations before passing them back to the user. Can
// be used on any cert object, but changing the name would be semver-major.
function translatePeerCertificate(c) {
if (!c)
return null;
if (c.issuerCertificate != null && c.issuerCertificate !== c) {
c.issuerCertificate = translatePeerCertificate(c.issuerCertificate);
}
if (c.infoAccess != null) {
const info = c.infoAccess;
c.infoAccess = { __proto__: null };
// XXX: More key validation?
info.replace(/([^\n:]*):([^\n]*)(?:\n|$)/g,
(all, key, val) => {
if (val.charCodeAt(0) === 0x22) {
// The translatePeerCertificate function is only
// used on internally created legacy certificate
// objects, and any value that contains a quote
// will always be a valid JSON string literal,
// so this should never throw.
val = JSONParse(val);
}
if (key in c.infoAccess)
c.infoAccess[key].push(val);
else
c.infoAccess[key] = [val];
});
}
return c;
}
module.exports = {
SecureContext,
createSecureContext,
translatePeerCertificate,
};

1782
lib/internal/tls/wrap.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -55,8 +55,8 @@ const {
} = internalBinding('crypto'); } = internalBinding('crypto');
const { Buffer } = require('buffer'); const { Buffer } = require('buffer');
const { canonicalizeIP } = internalBinding('cares_wrap'); const { canonicalizeIP } = internalBinding('cares_wrap');
const _tls_common = require('_tls_common'); const tlsCommon = require('internal/tls/common');
const _tls_wrap = require('_tls_wrap'); const tlsWrap = require('internal/tls/wrap');
const { validateString } = require('internal/validators'); const { validateString } = require('internal/validators');
// Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations // Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations
@ -386,9 +386,9 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
} }
}; };
exports.createSecureContext = _tls_common.createSecureContext; exports.createSecureContext = tlsCommon.createSecureContext;
exports.SecureContext = _tls_common.SecureContext; exports.SecureContext = tlsCommon.SecureContext;
exports.TLSSocket = _tls_wrap.TLSSocket; exports.TLSSocket = tlsWrap.TLSSocket;
exports.Server = _tls_wrap.Server; exports.Server = tlsWrap.Server;
exports.createServer = _tls_wrap.createServer; exports.createServer = tlsWrap.createServer;
exports.connect = _tls_wrap.connect; exports.connect = tlsWrap.connect;

View File

@ -127,9 +127,10 @@ BuiltinLoader::BuiltinCategories BuiltinLoader::GetBuiltinCategories() const {
#if !HAVE_OPENSSL #if !HAVE_OPENSSL
"crypto", "crypto/promises", "https", "http2", "tls", "_tls_common", "crypto", "crypto/promises", "https", "http2", "tls", "_tls_common",
"_tls_wrap", "internal/tls/parse-cert-string", "_tls_wrap", "internal/tls/parse-cert-string", "internal/tls/common",
"internal/tls/secure-context", "internal/http2/core", "internal/tls/wrap", "internal/tls/secure-context",
"internal/http2/compat", "internal/streams/lazy_transform", "internal/http2/core", "internal/http2/compat",
"internal/streams/lazy_transform",
#endif // !HAVE_OPENSSL #endif // !HAVE_OPENSSL
#if !NODE_OPENSSL_HAS_QUIC #if !NODE_OPENSSL_HAS_QUIC
"internal/quic/quic", "internal/quic/symbols", "internal/quic/stats", "internal/quic/quic", "internal/quic/symbols", "internal/quic/stats",

View File

@ -1,3 +1,4 @@
// Flags: --expose-internals --no-warnings
/* eslint-disable no-proto */ /* eslint-disable no-proto */
'use strict'; 'use strict';
const common = require('../common'); const common = require('../common');
@ -6,7 +7,7 @@ if (!common.hasCrypto)
common.skip('missing crypto'); common.skip('missing crypto');
const { strictEqual, deepStrictEqual } = require('assert'); const { strictEqual, deepStrictEqual } = require('assert');
const { translatePeerCertificate } = require('_tls_common'); const { translatePeerCertificate } = require('internal/tls/common');
const certString = '__proto__=42\nA=1\nB=2\nC=3'; const certString = '__proto__=42\nA=1\nB=2\nC=3';

View File

@ -0,0 +1,11 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto) common.skip('missing crypto');
// _tls_common is deprecated.
common.expectWarning('DeprecationWarning',
'The _tls_common module is deprecated.', 'DEP0192');
require('_tls_common');

View File

@ -0,0 +1,11 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto) common.skip('missing crypto');
// _tls_wrap is deprecated.
common.expectWarning('DeprecationWarning',
'The _tls_wrap module is deprecated.', 'DEP0192');
require('_tls_wrap');