Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TLSv1 and TLSv1.1 doesn't work #49210

Closed
afanasy opened this issue Aug 17, 2023 · 7 comments
Closed

TLSv1 and TLSv1.1 doesn't work #49210

afanasy opened this issue Aug 17, 2023 · 7 comments
Labels
doc Issues and PRs related to the documentations. tls Issues and PRs related to the tls subsystem.

Comments

@afanasy
Copy link
Contributor

afanasy commented Aug 17, 2023

Version

v18.17.0

Platform

Linux 5.15.0-1033-aws ~20.04.1-Ubuntu SMP Fri Mar 17 11:39:30 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

What steps will reproduce the bug?

Server created with TLSv1 refuses to connect:

var execSync = require('child_process').execSync
var fs = require('fs')
var tls = require('tls')
var port = 8000
var maxVersion = 'TLSv1' // works with TLSv1.2 and TLSv1.3, doesn't work with TLSv1 and TLSv1.1

execSync('openssl req -x509 -newkey rsa:1024 -keyout key -out cert -nodes -subj "/C=US/CN=localhost"')

var key = fs.readFileSync('key')
var cert = fs.readFileSync('cert')

tls.createServer({key, cert, maxVersion}, function (socket) {
  console.log('it works!', socket.getProtocol())
  socket.end()
  this.close()
}).
listen(port, () => {
  tls.connect(8000, {ca: [cert]})
})

How often does it reproduce? Is there a required condition?

Always fails

What is the expected behavior? Why is that the expected behavior?

Should support maxVersion: 'TLSv1' and 'TLSv1.1' as specified in the docs
https://nodejs.org/dist/latest-v18.x/docs/api/tls.html#tlscreatesecurecontextoptions

What do you see instead?

Error: C0177008447F0000:error:0A00042E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1586:SSL alert number 70

Emitted 'error' event on TLSSocket instance at:
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  library: 'SSL routines',
  reason: 'tlsv1 alert protocol version',
  code: 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION'
}
@bnoordhuis bnoordhuis added tls Issues and PRs related to the tls subsystem. doc Issues and PRs related to the documentations. labels Aug 17, 2023
@bnoordhuis
Copy link
Member

That's the expected behavior (you also need minVersion) but it's possible the documentation could be clearer. I do believe it is documented in doc/api/tls.md, but maybe it's not very obvious or findable. Pull request welcome.

@afanasy
Copy link
Contributor Author

afanasy commented Aug 17, 2023

@bnoordhuis Thank you for checking this. However, it doesn't work even if I add the minVersion:

var execSync = require('child_process').execSync
var fs = require('fs')
var tls = require('tls')
var port = 8000
var minVersion = 'TLSv1'
var maxVersion = 'TLSv1' // works with TLSv1.2 and TLSv1.3, doesn't work with TLSv1 and TLSv1.1

execSync('openssl req -x509 -newkey rsa:1024 -keyout key -out cert -nodes -subj "/C=US/CN=localhost"')

var key = fs.readFileSync('key')
var cert = fs.readFileSync('cert')

tls.createServer({key, cert, minVersion, maxVersion}, function (socket) {
  console.log('it works!', socket.getProtocol())
  socket.end()
  this.close()
}).
listen(port, () => {
  tls.connect(8000, {ca: [cert]})
})

Failing with the same error:

Error: C0C7DC30417F0000:error:0A00042E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1586:SSL alert number 70

Emitted 'error' event on TLSSocket instance at:
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  library: 'SSL routines',
  reason: 'tlsv1 alert protocol version',
  code: 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION'
}

@bnoordhuis
Copy link
Member

I may be misremembering but you probably also need to pass --tls-min-v1.0 on the command line or through NODE_OPTIONS.

@afanasy
Copy link
Contributor Author

afanasy commented Aug 18, 2023

@bnoordhuis It doesn't work with --tls-min-v1.0 on node v18.17.0, with a different error:

Error: C0078E6C877F0000:error:0A000438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1586:SSL alert number 80

Emitted 'error' event on TLSSocket instance at:
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  library: 'SSL routines',
  reason: 'tlsv1 alert internal error',
  code: 'ERR_SSL_TLSV1_ALERT_INTERNAL_ERROR'
}

Node.js v18.17.0

Surprisingly, it does work on v16.20.2, without errors!
v17.0.0 gives an error as well:

node:events:368
      throw er; // Unhandled 'error' event
      ^

Error: Client network socket disconnected before secure TLS connection was established
    at connResetException (node:internal/errors:691:14)
    at TLSSocket.onConnectEnd (node:_tls_wrap:1585:19)
    at TLSSocket.emit (node:events:402:35)
    at endReadableNT (node:internal/streams/readable:1340:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)
Emitted 'error' event on TLSSocket instance at:
    at emitErrorNT (node:internal/streams/destroy:164:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  code: 'ECONNRESET',
  path: undefined,
  host: undefined,
  port: 8000,
  localAddress: undefined
}

Node.js v17.0.0

@bnoordhuis
Copy link
Member

It's progress of a kind. Alert 70 is PROTOCOL_VERSION (i.e. protocol mismatch/unsupported), alert 80 is INTERNAL_ERROR, so basically a configuration error.

Now that I think of it, you can probably drop the --tls-min-v1.0 switch but you'll need to pass {ciphers: "DEFAULT@SECLEVEL=0"} in the options (and that SECLEVEL=0 hints at why < TLSv1.2 is disabled by default.)

@afanasy
Copy link
Contributor Author

afanasy commented Aug 19, 2023

@bnoordhuis It works with node --tls-min-v1.0 --tls-cipher-list=DEFAULT@SECLEVEL=0 (can't drop --tls-min-v1.0) for all versions (v16.20.2, v17.0.0, v18.17.0). On the v17 you can't have both TLSv1 and TLSv1.3 with this approach though, but this was addressed in #43427 I believe. Thank you so much! I was really confused when migration from v16 to v18 broke TLSv1 support. I've created a PR to mention this in the docs: #49236.

@bnoordhuis
Copy link
Member

Closing as this has been resolved and wasn't a node bug. No opinion on the pull request.

@bnoordhuis bnoordhuis closed this as not planned Won't fix, can't repro, duplicate, stale Sep 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. tls Issues and PRs related to the tls subsystem.
Projects
None yet
Development

No branches or pull requests

2 participants