Skip to content

NODE_EXTRA_CA_CERTS option seems to conflict with custom OpenSSL config #48143

Closed
@ckcr4lyf

Description

@ckcr4lyf

Version

v18.16.0, v20.2.0

Platform

Linux 15cd296152a7 6.3.2-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 11 May 2023 16:40:42 +0000 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

Adding custom options to OpenSSL config for node, it works as expected. (In my case, adding option to allow UnsafeLegacyRenegotiation (https://github.com/ckcr4lyf/no-rfc5746/blob/23c9abf620b37754a8eb4c206e6c8d37646a7c91/openssl.cnf)

When connecting to a TLS server that doesn't support the renegotiation extension, it DOES NOT throw an error, which implies that it is correctly reading the custom config. (If the config is missing it will fail)

However, if the NODE_EXTRA_CA_CERTS var is set, then it WILL throw an error.

Since it is non-trivial to create a TLS server which does not support renegotiation, I have made a custom TCP socket which replies with a TLS ServerHello with no extensions, causing clients to fail: https://github.com/ckcr4lyf/no-rfc5746/actions/runs/5059898372/jobs/9082065602#step:5:30

I've also packaged the node PoC of this bug w/ node 18 & node 20 into a docker container, so anyone who wants to can easily test it, or open a shell in it and poke around. You an check a Github run of it, to see the difference in when the option is not set vs. when it is: https://github.com/ckcr4lyf/no-rfc5746/actions/runs/5060085507/jobs/9082524060

Example of running the docker container to PoC the normal case:

$ docker run --rm ghcr.io/ckcr4lyf/node-sslconf-poc-node18:master@sha256:66be176fe027b5b98ca4636b2a6b0ad084c603ca51344725f0a47c046bd7e856
started on :4433
Success

And failure case when NODE_EXTRA_CA_CERTS is set:

$ docker run --rm -e NODE_EXTRA_CA_CERTS="/etc/ssl/certs/ca-certificates.crt" ghcr.io/ckcr4lyf/node-sslconf-poc-node18:master@sha256:66be176fe027b5b98ca4636b2a6b0ad084c603ca51344725f0a47c046bd7e856
started on :4433
[Error: C0E7F4C1AE7F0000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled:../deps/openssl/openssl/ssl/statem/extensions.c:922:
] {
  library: 'SSL routines',
  reason: 'unsafe legacy renegotiation disabled',
  code: 'ERR_SSL_UNSAFE_LEGACY_RENEGOTIATION_DISABLED'
}

You can use -e STRACE=true to view strace for openat,read calls.

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

Seems to be 100% of the time, if NODE_EXTRA_CA_CERTS is set.

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

It should still respect the custom SSL config, since there is no obvious conflict documented between NODE_EXTRA_CA_CERTS and the openssl config, and strace implies it is still read

openat(AT_FDCWD, "/etc/ssl/openssl.cnf", O_RDONLY) = 3
read(3, "nodejs_conf = openssl_init\n\n[ope"..., 4096) = 171
read(3, "", 4096)                       = 0
openat(AT_FDCWD, "/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = 3
read(3, "-----BEGIN CERTIFICATE-----\nMIIH"..., 4096) = 4096
read(3, "8B1\nRXxlDPiyN8+sD8+Nb/kZ94/sHvJw"..., 4096) = 4096
[...truncated]

What do you see instead?

It did not respect the custom SSL config, and failed due to unsafe option (https://github.com/ckcr4lyf/no-rfc5746/actions/runs/5059898380/jobs/9082077770#step:4:8)

[Error: C097DA8F8B7F0000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled:../deps/openssl/openssl/ssl/statem/extensions.c:922:
] {
  library: 'SSL routines',
  reason: 'unsafe legacy renegotiation disabled',
  code: 'ERR_SSL_UNSAFE_LEGACY_RENEGOTIATION_DISABLED'
}

Additional information

I tried poking around node source, but I am no expert in C/C++, config and build systems, so I am not sure. Hopefully my conditions to reproduce can help someone else test it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions