element-x-ios icon indicating copy to clipboard operation
element-x-ios copied to clipboard

ElementX doesn't support TLS 1.3

Open singingtelegram opened this issue 3 years ago • 18 comments

Steps to reproduce

Attempting to login on a TLS v1.3 only server.

Outcome

What did you expect?

The authentication process continues.

What happened instead?

log: 🚨 AuthenticationServiceProxy.configure():60 Failed configuring a server: Generic(message: "An error occurred: error sending request for url (https://[hostname]/.well-known/matrix/client): error trying to connect: bad protocol version")

Your phone model

iPhone 12

Operating system version

16.4.1

Application version

1.0.24 (43)

Homeserver

ocf.berkeley.edu

Will you send logs?

No

singingtelegram avatar Apr 11 '23 07:04 singingtelegram

Logs from Rust:

hyper::Error(Connect, Error { code: -9836, message: "bad protocol version" })

RapidAPI:

The operation couldn’t be completed. (kCFStreamErrorDomainSSL error -9836.)

pixlwave avatar Jul 03 '23 08:07 pixlwave

We use the system's native TLS library, could it be that it's just OpenSSL (?) on your system being too old? There's the possibility of bundling rustls but it will increase the binary size (not sure how much).

jplatte avatar Jul 03 '23 08:07 jplatte

The Rust native-tls crate uses the Secure Transport API on iOS.

https://support.apple.com/guide/security/tls-security-sec100a75d12/web

TLS clients using the SecureTransport APIs can’t use TLS 1.3.

yu-re-ka avatar Jul 03 '23 13:07 yu-re-ka

@singingtelegram does legacy EI work on your server?

manuroe avatar Jul 06 '23 15:07 manuroe

yes, the Element app does work with our server.

singingtelegram avatar Jul 06 '23 15:07 singingtelegram

For anyone encountering this, I needed to set tls 1.2 as the MAXIMUM allowed TLS version on ALL my servers (domain with the .well-known, actual matrix server and proxy as well)

On caddy that can be done via

# Temp fix because of https://github.com/vector-im/element-x-ios/issues/786
tls {
protocols tls1.2 tls1.2
}

fuomag9 avatar Jul 10 '23 12:07 fuomag9

It seems that only Rusts native-tls crate does not support TLS 1.3: https://github.com/sfackler/rust-native-tls/issues/140, while the underlying security-framework crate supports it (https://docs.rs/security-framework/latest/security_framework/secure_transport/struct.SslProtocol.html#associatedconstant.TLS13), because Apples underlying Secure Transport support it since a while now: https://developer.apple.com/documentation/security/tls_protocol_version_t/tls_protocol_version_tlsv13

Fortunately someone is working on it already: https://github.com/sfackler/rust-native-tls/pull/235

Also Element iOS works fine with TLS 1.3 only homeservers.

csett86 avatar Jul 15 '23 21:07 csett86

Looks like there's a second PR to enable this now too… https://github.com/sfackler/rust-native-tls/pull/278

pixlwave avatar Oct 30 '23 08:10 pixlwave

Looks like I had a thinko on this and while iOS supported TLS 1.3 for a while eg via URLSession etc, the specific Secure Transport Framework (which is deprecated) does not support TLS 1.3 (https://github.com/sfackler/rust-native-tls/blob/b81f70295bdb6672dd0b5c4686673c0775968d1d/src/imp/security_framework.rs#L53. Sorry for the confusion on my side here.

So the new PR for rust-native-tls will not help us here on iOS/macOS, as it wont bring TLS 1.3 to iOS.

As Element X Android is already using rustls instead of native-tls (if I read https://github.com/matrix-org/matrix-rust-sdk/blob/main/bindings/matrix-sdk-ffi/Cargo.toml#L69 correctly), and native-tls will not be able to provide TLS 1.3 for the forseeable future, how do you feel about using rustls on iOS as well? I would be happy to send PRs and be part of testing, I can provide a TLS1.3-only homeserver as well

csett86 avatar Jan 21 '24 10:01 csett86

TLDR: use rustls on iOS/macOS in the matrix-rust-sdk Swift version as Apple recommends to use your own TLS implementation if you use cross-platform code via sockets.

Long version:

I did more digging into this, and if you look long enough, there is also an official recommendation from Apple, that boils down to this if you use cross-platform code with sockets (as we do with the rust sdk):

To use TLS in that case [BSD Sockets], add your own TLS implementation.

Don’t use Secure Transport for your TLS implementation. It’s been deprecated since 2019 (see Versions) and doesn’t support TLS 1.3. If you have existing code that uses Secure Transport, make a plan to migrate off it.

Modern TLS implementations including TLS 1.3 on macOS are only available as a built-on via the Apple-specific URLSession / Network framework APIs, so APIs where you feed in a URL and get the response back. They are not available in combination with a generic sockets-based cross-platform code.

With that in mind, there is currently no hope that rust-native-tls would support TLS 1.3 in the forseeable future as there is simply no native TLS implementation in current macOS/iOS that could be used by rust-native-tls.

I'll prepare a PR to switch to rustls for the Swift version of the matrix-rust-sdk.

csett86 avatar Feb 08 '24 17:02 csett86

@csett86 Sorry for the delay replying. Your message came in right at the point where we discovered that Element X Android wasn't working with custom certificates installed through the OS whereas Element X iOS was (because of Native TLS). So there were discussions about moving EXA to native-tls which was the exact opposite of what you were suggesting. We haven't come to a concrete conclusion on that discussion yet, so for now I think it would be best to leave things as they are.

pixlwave avatar Feb 09 '24 08:02 pixlwave

That's actually super easy to fix! Just switch from reqwest's rustls-tls feature to rustls-tls-native-roots.

jplatte avatar Feb 09 '24 20:02 jplatte

Unfortunately its not yet that simple, as the underlying rustls-native-certs does not support iOS or Android, if I read this correctly: https://github.com/rustls/rustls-native-certs/issues/3

But the new https://github.com/rustls/rustls-platform-verifier should be able to solve that long-term, both for iOS and Android, once that is supported by reqwest at some point

csett86 avatar Feb 10 '24 13:02 csett86

Linking to https://github.com/seanmonstar/reqwest/issues/2159 for easy access to the current status of this.

pixlwave avatar Nov 07 '24 12:11 pixlwave

It might make sense to document that in the section of configuring reverse proxies for Synapse, especially given that Element X is now actively pushed forward for everybody's use and Element 'Classic' is almost deprecated.

It took me a few days and a tcpdump at the end, to get to the root cause of that.

alexander-potemkin avatar Apr 20 '25 20:04 alexander-potemkin

it feels important, bumping this up

alexander-potemkin avatar Aug 14 '25 13:08 alexander-potemkin

It'd probably be more impactful to bump the issue about supporting rustls-platform-verifier in Reqwest as we're blocked on that.

pixlwave avatar Aug 14 '25 13:08 pixlwave

Makes sense, done.

alexander-potemkin avatar Aug 14 '25 14:08 alexander-potemkin

It might make sense to document that in the section of configuring reverse proxies for Synapse, especially given that Element X is now actively pushed forward for everybody's use and Element 'Classic' is almost deprecated.

I've been looking for the root cause of Element X not working literally for months until I found this issue now. And I can see, that it's still not documented in the reverse proxy configuration documentation.

It would have been really helpful, if it would have been added there.

moabeat-berlin avatar Nov 16 '25 11:11 moabeat-berlin