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

--ciphers may not properly set --tls13-ciphers #13873

Open
MasterInQuestion opened this issue Jun 4, 2024 · 6 comments
Open

--ciphers may not properly set --tls13-ciphers #13873

MasterInQuestion opened this issue Jun 4, 2024 · 6 comments
Labels

Comments

@MasterInQuestion
Copy link

MasterInQuestion commented Jun 4, 2024

    The current behavior ("--ciphers", "--tls13-ciphers" each independent) may feel tricky.
    Would it be more appropriate to readapt the design?
    (or maybe better explain the rationale..?)

    E.g.
    --tls13-ciphers "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256"
    --ciphers "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256"
    .
    --tls13-ciphers "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256" --ciphers "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
    --ciphers "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"

    See also:
    "--ciphers" may include other, unspecified ciphers in TLS handshake
    https://github.com/curl/curl/issues/7198
    .
    Clarify setting TLS 1.3 ciphers using different backends
    https://github.com/curl/curl/issues/3938
    https://github.com/curl/curl/issues/3077#issuecomment-426561378
    https://github.com/curl/curl/issues/2435

    Test site: https://browserleaks.com/tls

@MasterInQuestion
Copy link
Author

    What's the expectation for the "--ciphers" alike..?
    https://github.com/curl/curl/issues/1316#issuecomment-285779700

    Mere pass-through?
    https://www.openssl.org/docs/manmaster/man1/openssl-ciphers.html#CIPHER-LIST-FORMAT

@bagder bagder added the TLS label Jun 4, 2024
@jan2000
Copy link
Contributor

jan2000 commented Jun 5, 2024

The situation with the cipher options is not as straightforward as one might expect, because handling of these options differ for each SSL backends that libcurl is build against. For some backends (e.g. mbedtls) the --cipher option is parsed by libcurl itself, for others (e.g. openssl, wolfssl) it is passed through directly to the SSL backend.

Due to this the format of the --cipher option can differ between backends. While most backends support a list of openssl names1 (e.g. ECDHE-RSA-AES128-GCM-SHA256), some might also support IANA names (e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256). Some backends expect an all different format all together (e.g. schannel).

When TLSv1.3 was introduced, openssl added a separate option in their api for setting TLSv1.3 ciphers, so libcurl accommodated for that by introducing the --tls13-ciphers option. But then when other SSL backends gained TLSv1.3 support they did not follow suit (e.g. wolfssl, mbedtls), and thus their TLSv1.3 ciphers must set by the --cipher option next to the TLSv1.0/TLSv1.1/TLSv1.2 ciphers.

This has also the effect that when using the openssl backend, setting the --cipher option but omitting the --tls13-ciphers option will cause the default TLSv1.3 ciphers to be used. But when using the mbedtls backend only the ciphers in the --cipher option will be used.

So the cipher options are not as consistent as one might hope for, due to the idiosyncrasies of the different SSL backends. The situation could be improved, for example libcurl could pre-parse the options so that the expected format and behavior could be made more consistent across the board. That would be not without downsides however (BC breaking changes, extra overhead, added complexity in libcurl), and even then it would not be a panacea for all SSL backends.

For the moment the best you can do, is to check which SSL backend is being used and adjust the cipher options according to the documentation: https://curl.se/docs/ssl-ciphers.html
You might also gain some extra insight by looking at the unit test for the cipher options: test_17_07_ssl_ciphers in https://github.com/curl/curl/blob/master/tests/http/test_17_ssl_use.py

Footnotes

  1. Notice that for the TLSv1.3 ciphers there are no openssl names. The 1.3 cipher names can be easily told apart from the 1.0/1.1/1.2 IANA names, because all 1.0/1.1/1.2 names contain WITH_, while 1.3 names do not.

@MasterInQuestion
Copy link
Author

    So simply put, the current situation is simply havoc...
    For the moment, the most viable fix is better documentation to this situation.

    Making `curl` to wrap-around such idiosyncrasies is possible and should perfectly work mostly.
    The primary issue is the complexity of the implementation bother.

@vszakats vszakats changed the title "--ciphers" may not properly set "--tls13-ciphers" --ciphers may not properly set --tls13-ciphers Jun 15, 2024
@humbertocastelo
Copy link

--tls13-ciphers works only if --tlsv1.3 is present in the command line, example:

--tls13-ciphers 'TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256' \
--tlsv1.3 \

--ciphers always works, example:

--ciphers 'TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256'

Server receives:

TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:TLS_EMPTY_RENEGOTIATION_INFO_SCSV

This value TLS_EMPTY_RENEGOTIATION_INFO_SCSV is appended to the end of the cipher list, it seems like it is mandatory and it is impossible to turn off this behavior.

Version:

curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.1.0 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.17
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd

This has probably already been corrected in newer versions, but I thought it appropriate to leave the comment here, as I found some mentions of this issue.

@MasterInQuestion
Copy link
Author

MasterInQuestion commented Jun 22, 2024

    "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" is not directly related to this issue. (CLI of `curl`)

    I have a writing pending for the "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" trouble.
    Meanwhile you may look at:
    https://archive.org/details/4431785826199-Fix-Discord-Zendesk-Sign-In
    .
    Essential cause: OpenSSL and upstream (TLS standard).

    See also: https://stackoverflow.com/questions/35254883/avoid-sending-tls-empty-renegotiation-info-scsv-cipher-in-tls-client-hello#67712839

@MasterInQuestion
Copy link
Author

    Also I believe using "--ciphers" to set "--tls13-ciphers" is no-op:
    The default TLS 1.3 Cipher Suites would be then used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants