Skip to content

Add TLS transport option to pin the TLS version - #3

Merged
codeadict merged 1 commit into
codeadict:mainfrom
Zabrane:main
Sep 25, 2026
Merged

codeadict merged 1 commit into
codeadict:mainfrom
Zabrane:main

Conversation

@Zabrane

@Zabrane Zabrane commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Problem

Callers have no working way to pin the TLS version. A versions entry in transport_opts is silently dropped: gen_http_ssl:connect/3 only forwards socket_opts, verify, cacerts and the buffer sizes to ssl:connect.

Change

  • New {tls, "1.2"} / {tls, "1.3"} transport option, mapped to {versions, ['tlsv1.2']} / {versions, ['tlsv1.3']} in both connect/3 and upgrade/5.
  • Any other value raises {invalid_tls_version, Value} before connecting.
  • Without the option, the OTP default applies, as before.
  • When TLS 1.3 is pinned, the hardcoded {reuse_sessions, true} is dropped. It is a TLS =< 1.2 option, and OTP rejects it alongside a TLS-1.3-only version list:
    {options, incompatible, [reuse_sessions, {versions, ['tlsv1.3']}]}
gen_http:connect(https, "example.com", 443,
                 #{transport_opts => [{tls, "1.3"}]}).

Verification

Against a live server, reading ssl:connection_information(Socket, [protocol]):

Option Result
{tls, "1.2"} tlsv1.2 negotiated
{tls, "1.3"} tlsv1.3 negotiated
{tls, "1.1"} raises {invalid_tls_version, "1.1"}


Callers had no working way to pin the TLS version: a `versions`
entry in transport_opts is silently dropped, since connect/3 only
forwards `socket_opts`, `verify`, `cacerts` and the buffer sizes to
ssl:connect.

Add `{tls, "1.2"}` / `{tls, "1.3"}`, mapped to
`{versions, ['tlsv1.2']}` / `{versions, ['tlsv1.3']}` in both
connect/3 and upgrade/5. Any other value raises
`{invalid_tls_version, Value}` before connecting. Without the option,
the OTP default applies, as before.

When TLS 1.3 is pinned, drop the hardcoded `{reuse_sessions, true}`:
it is a TLS =< 1.2 option, and OTP rejects it alongside a
TLS-1.3-only version list with
`{options, incompatible, [reuse_sessions, {versions, ['tlsv1.3']}]}`.

Verified against a live server: "1.2" negotiates tlsv1.2, "1.3"
negotiates tlsv1.3, "1.1" is rejected.

@codeadict codeadict left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, really exciting to see a PR on this. Wondering if you are using the library for something. Thanks

@codeadict
codeadict merged commit 650084f into codeadict:main Sep 25, 2026
@Zabrane

Zabrane commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Awesome, really exciting to see a PR on this. Wondering if you are using the library for something. Thanks

Oh yes. We use gen_http to connect to an ERP. Extremely stable.
Keep up the good work.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants