Unable to establish TLS socket with SNI for certain hostnames (e.g. bucket.s3.amazonaws.com)

I’m attempting to establish a TLS socket with a hostname of the form bucket.s3.amazonaws.com while using SNI (server_name_indication), but the ssl module is throwing an unexpected error.

For demonstration purposes, I’m going to use the public rebar3.s3.amazonaws.com hostname, but this problem is not specific to the rebar3 bucket, and can be reproduced on any bucket I’ve tried so far.

8> ssl:connect("rebar3.s3.amazonaws.com", 443, [{verify, verify_peer}, {cacerts, public_key:cacerts_get()}, {server_name_indication, "rebar3.s3.amazonaws.com"}], 2000).
=NOTICE REPORT==== 20-Mar-2023::15:19:09.003556 ===
TLS client: In state certify at ssl_handshake.erl:2100 generated CLIENT ALERT: Fatal - Handshake Failure
 - {bad_cert,hostname_check_failed}
{error,{tls_alert,{handshake_failure,"TLS client: In state certify at ssl_handshake.erl:2100 generated CLIENT ALERT: Fatal - Handshake Failure\n {bad_cert,hostname_check_failed}"}}}

I am able to successfully establish a TLS socket with openssl s_client like so:

openssl s_client -connect rebar3.s3.amazonaws.com:443 -servername rebar3.s3.amazonaws.com

And when doing so, the server is presenting a *.s3.amazonaws.com certificate.

I am also able to successfully establish a socket if I modify the server_name_indication option to be s3.amazonaws.com instead of rebar3.s3.amazonaws.com. This may be a reasonable workaround for this particular failure, but I am hoping to find a solution that would allow the full hostname to be specified in the SNI.

These tests were run on Erlang 25.3.

Am I doing something wrong with SNI here?

Thanks!

1 Like

It is a wildcard and so you need to pick the correct name validation:

A snippet from one of my projects you can crib from:

SSL = [{customize_hostname_check, [{match_fun,public_key:pkix_verify_hostname_match_fun(https)}]}|SSL0],
3 Likes

Thank you, this is precisely what I needed. I also appreciate the added context.

1 Like