From e7bf89623e6a402a41b2adcae1079fef7ce46585 Mon Sep 17 00:00:00 2001 From: Julian Soreavis Date: Tue, 18 Aug 2026 21:44:14 +0200 Subject: [PATCH] doc: fix broken TLS security level example The example under "Setting security levels" does not run. The client sets `maxVersion: 'TLSv1'` while its `minVersion` stays at the `tls.DEFAULT_MIN_VERSION` default of `'TLSv1.2'`, so no version overlaps and the connection fails with ERR_SSL_NO_PROTOCOLS_AVAILABLE. Setting the client's `minVersion` is not enough on its own: the handshake then fails with an alert 40, because `createServer` is given no key or certificate and the server has no shared cipher. Set `minVersion` on the client, add the key and certificate placeholders and the openssl recipe that the other sections using them already carry, pass the server certificate as the client's `ca`, and use port 8000 like the rest of the file. The section now runs from an empty directory and prints "Client connected with protocol: TLSv1". Signed-off-by: Julian Soreavis --- doc/api/tls.md | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/doc/api/tls.md b/doc/api/tls.md index f98bb2976721..34f8c3b99e93 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -468,35 +468,64 @@ to set the security level to 0 while using the default OpenSSL cipher list, you ```mjs import { createServer, connect } from 'node:tls'; -const port = 443; +import { readFileSync } from 'node:fs'; +const port = 8000; -createServer({ ciphers: 'DEFAULT@SECLEVEL=0', minVersion: 'TLSv1' }, function(socket) { +createServer({ + key: readFileSync('server-key.pem'), + cert: readFileSync('server-cert.pem'), + ciphers: 'DEFAULT@SECLEVEL=0', + minVersion: 'TLSv1', +}, function(socket) { console.log('Client connected with protocol:', socket.getProtocol()); socket.end(); this.close(); }) .listen(port, () => { - connect(port, { ciphers: 'DEFAULT@SECLEVEL=0', maxVersion: 'TLSv1' }); + connect(port, { + ciphers: 'DEFAULT@SECLEVEL=0', + minVersion: 'TLSv1', + maxVersion: 'TLSv1', + ca: [ readFileSync('server-cert.pem') ], + }); }); ``` ```cjs const { createServer, connect } = require('node:tls'); -const port = 443; +const { readFileSync } = require('node:fs'); +const port = 8000; -createServer({ ciphers: 'DEFAULT@SECLEVEL=0', minVersion: 'TLSv1' }, function(socket) { +createServer({ + key: readFileSync('server-key.pem'), + cert: readFileSync('server-cert.pem'), + ciphers: 'DEFAULT@SECLEVEL=0', + minVersion: 'TLSv1', +}, function(socket) { console.log('Client connected with protocol:', socket.getProtocol()); socket.end(); this.close(); }) .listen(port, () => { - connect(port, { ciphers: 'DEFAULT@SECLEVEL=0', maxVersion: 'TLSv1' }); + connect(port, { + ciphers: 'DEFAULT@SECLEVEL=0', + minVersion: 'TLSv1', + maxVersion: 'TLSv1', + ca: [ readFileSync('server-cert.pem') ], + }); }); ``` This approach sets the security level to 0, allowing the use of legacy features while still leveraging the default OpenSSL ciphers. +To generate the certificate and key for this example, run: + +```bash +openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \ + -keyout server-key.pem -out server-cert.pem +``` + ### Using [`--tls-cipher-list`][] You can also set the security level and ciphers from the command line using the