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

CLIENT ALERT: Fatal - Handshake Failure for www.gutenberg.org #8466

Closed
wojtekmach opened this issue May 8, 2024 · 7 comments
Closed

CLIENT ALERT: Fatal - Handshake Failure for www.gutenberg.org #8466

wojtekmach opened this issue May 8, 2024 · 7 comments
Assignees
Labels
bug Issue is reported as a bug not a bug Issue is determined as not a bug by OTP team:PS Assigned to OTP team PS

Comments

@wojtekmach
Copy link
Contributor

Not sure if this is a bug or the server/certificate is misconfigured.

To Reproduce

$ rtx current erlang
26.2.5
$ erl
Erlang/OTP 26 [erts-14.2.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Eshell V14.2.5 (press Ctrl+G to abort, type help(). for help)
1> ssl:start(), {ok, _} = ssl:connect("elixir-lang.org", 443, [{cacerts, public_key:cacerts_get()}]).
{ok,{sslsocket,{gen_tcp,#Port<0.5>,tls_connection,undefined},
               [<0.126.0>,<0.125.0>]}}
2> ssl:start(), {ok, _} = ssl:connect("www.gutenberg.org", 443, [{cacerts, public_key:cacerts_get()}]).
=NOTICE REPORT==== 8-May-2024::15:47:06.645138 ===
TLS client: In state wait_cert_cr at ssl_handshake.erl:2113 generated CLIENT ALERT: Fatal - Bad Certificate

** exception error: no match of right hand side value {error,{tls_alert,{bad_certificate,"TLS client: In state wait_cert_cr at ssl_handshake.erl:2113 generated CLIENT ALERT: Fatal - Bad Certificate\n"}}}

On OTP 25.3.2.11:

$ erl
Erlang/OTP 25 [erts-13.2.2.8] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]

Eshell V13.2.2.8  (abort with ^G)
1> ssl:start(), {ok, _} = ssl:connect("www.gutenberg.org", 443, [{cacerts, public_key:cacerts_get()}]).
=WARNING REPORT==== 8-May-2024::15:49:35.290652 ===
Description: "Server authenticity is not verified since certificate path validation is not enabled"
     Reason: "The option {verify, verify_peer} and one of the options 'cacertfile' or 'cacerts' are required to enable this."

{ok,{sslsocket,{gen_tcp,#Port<0.6>,tls_connection,undefined},
               [<0.122.0>,<0.121.0>]}}
2> ssl:start(), {ok, _} = ssl:connect("www.gutenberg.org", 443, [{cacerts, public_key:cacerts_get()}, {verify, verify_peer}]).
=NOTICE REPORT==== 8-May-2024::15:49:51.226210 ===
TLS client: In state wait_cert_cr at ssl_handshake.erl:2113 generated CLIENT ALERT: Fatal - Handshake Failure
 - {bad_cert,hostname_check_failed}
** exception error: no match of right hand side value {error,{tls_alert,{handshake_failure,"TLS client: In state wait_cert_cr at ssl_handshake.erl:2113 generated CLIENT ALERT: Fatal - Handshake Failure\n {bad_cert,hostname_check_failed}"}}}

Affected versions

Tested on OTP 25.3.2.11 and 26.2.5.

Additional context

Original report at: elixir-nx/axon#570 (comment)

@wojtekmach wojtekmach added the bug Issue is reported as a bug label May 8, 2024
@IngelaAndin
Copy link
Contributor

IngelaAndin commented May 8, 2024

For the hostname check not to fail you want to use the option {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)} to handle wildcard certs.

From doc:

{customize_hostname_check, HostNameCheckOpts} - Customization option

Customizes the hostname verification of the peer certificate, as different protocols that use TLS such as HTTP or LDAP may want to do it differently. For example the get standard HTTPS handling provide the already implememnted fun from the public_key application for HTTPS. {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]} For futher description of customize options see [public_key:pkix_verify_hostname/3](http://otp.ericsson.se/product/internal/test/daily/logs/net/artemis/ldisk/daily_build/27_master-opu_o_ensure-os-monotonic-time_docker_100029.2024-05-06_21/docs/lib/public_key-1.16/doc/html/public_key.html#pkix_verify_hostname/3)

But it seems there is something wrong with the chain as I get this result in OTP-27 with or without the customize_hostname_check.

Trace of function checking the chain:

public_key:pkix_path_validation/3 -> {error,
                                                                {bad_cert,
                                                                 invalid_signature}}

@IngelaAndin IngelaAndin self-assigned this May 8, 2024
@IngelaAndin IngelaAndin added the team:PS Assigned to OTP team PS label May 8, 2024
@wojtekmach
Copy link
Contributor Author

wojtekmach commented May 8, 2024

Thank you for quick reply. I tried creating the minimum reproduction but I skipped that detail about hostname, thank you for point that out. FWIW a more real world reproduction is this I believe, same result and also on OTP 26.2.5:

1> inets:start(), ssl:start(), httpc:request("https://www.gutenberg.org").
=NOTICE REPORT==== 8-May-2024::16:58:46.016644 ===
TLS client: In state wait_cert_cr at ssl_handshake.erl:2113 generated CLIENT ALERT: Fatal - Bad Certificate

{error,{failed_connect,[{to_address,{"www.gutenberg.org",
                                     443}},
                        {inet,[inet],
                              {tls_alert,{bad_certificate,"TLS client: In state wait_cert_cr at ssl_handshake.erl:2113 generated CLIENT ALERT: Fatal - Bad Certificate\n"}}}]}}

@IngelaAndin
Copy link
Contributor

Yes and my run also ends up with Bad Certificate alert from the ssl application.

@IngelaAndin
Copy link
Contributor

IngelaAndin commented May 9, 2024

@wojtekmach Hum ... I noticed that the problem with the cert chain is that it has one cert that uses sha (sha1) in its signature algorithm and that is no longer supported by default.

So you need to add that. You can allow it just for certificate signatures like this:

> Defalut = ssl:signature_algs(default, 'tlsv1.3').
[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
 ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
 ecdsa_brainpoolP512r1tls13_sha512,
 ecdsa_brainpoolP384r1tls13_sha384,
 ecdsa_brainpoolP256r1tls13_sha256,rsa_pss_pss_sha512,
 rsa_pss_pss_sha384,rsa_pss_pss_sha256,rsa_pss_rsae_sha512,
 rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,rsa_pkcs1_sha512,
 rsa_pkcs1_sha384,rsa_pkcs1_sha256,
 {sha512,ecdsa},
 {sha384,ecdsa},
 {sha256,ecdsa}]

> ssl:connect("www.gutenberg.org", 443, [{cacerts, public_key:cacerts_get()}, {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}, {signature_algs_cert, 
Default ++ [{sha, rsa}]}]).
 

@IngelaAndin IngelaAndin added the not a bug Issue is determined as not a bug by OTP label May 9, 2024
@mwhitworth
Copy link

Is there scope for a more specific error return for this case?

Strictly speaking the certificate is not bad. The specific error case is that the certificate's signature algorithm will not be processed due to client configuration.

@IngelaAndin
Copy link
Contributor

We can look into if at least the logging of the error can be more specific. On the top of my head I can not say if it would be possible to give another TLS-alert, it might be, will check when I am back at work. Will leave this open for future enhancement of error handling.

IngelaAndin added a commit to IngelaAndin/otp that referenced this issue May 14, 2024
Make it easier to distinguish between invalid sifnature and unsupported signature

Closes erlang#8466
IngelaAndin added a commit to IngelaAndin/otp that referenced this issue May 14, 2024
Make it easier to distinguish between a invalid signature and unsupported signature

Closes erlang#8466
@IngelaAndin
Copy link
Contributor

@mwhitworth I think unsupported certificate alert could be more appropriate for this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug not a bug Issue is determined as not a bug by OTP team:PS Assigned to OTP team PS
Projects
None yet
Development

No branches or pull requests

3 participants