inko-lang / inko

A language for building concurrent software with confidence
http://inko-lang.org/
Mozilla Public License 2.0
813 stars 38 forks source link

Support for TLS sockets #329

Open yorickpeterse opened 1 year ago

yorickpeterse commented 1 year ago

Inko's sockets are just regular sockets, without any built-in support for TLS (as in SSL/TLS, not thread-local storage). Combine that with the lack of built-in support for various ciphers/cryptographic functions, and using encrypted connections is a real challenge.

To make this possible, Inko should provide a TLS stack of some sort which can be used with its non-blocking sockets. As first sight the best option may appear to be using rustls and exposing it through the VM. While this would likely save us time, I'm not a fan of it, for a few reasons:

A first step towards this it to identify what exactly we'd need. After that we need to figure out if there's some sort of shared test suite/reference we can use to determine if we're implementing things correctly. The last thing I want to do is implement this wrong.

Related issues:

Related links:

yorickpeterse commented 1 year ago

marked this issue as related to #283

yorickpeterse commented 5 months ago

While the original desire was a pure Inko TLS stack, I'm currently leaning more towards just using OpenSSL 3.x instead. For one, writing such a stack is a massive effort. Second, it will probably be a long time before we can guarantee constant-time operations needed for various crypto bits, potentially opening us up for timing attacks until then.

Using OpenSSL does mean that cross-compilation becomes more of a challenge, whereas a pure Inko stack wouldn't suffer from this.

Of course wrapping rustls is still a promising option, and would probably make cross-compilation a heck of a lot easier.

yorickpeterse commented 5 months ago

Based on https://github.com/rustls/rustls/blob/main/examples/src/bin/simpleclient.rs, I think wrapping rustls shouldn't be too hard. Essentially TLS sockets would need to store three values: a file descriptor to the raw socket, the rustls wrapper reader/writer, and a reference to the rustls connection object.

yorickpeterse commented 2 weeks ago

https://github.com/fres621/inko-tls/ might prove useful as a reference.

yorickpeterse commented 2 days ago

Per the source code of rustls' Stream type (https://docs.rs/rustls/latest/src/rustls/stream.rs.html#11-17), it seems we can just create a Stream ad-hoc for every TLS read/write, instead of having to keep it around. This means that for a TLS socket we only need to persist a ClientConnection and ClientConfig somewhere.

yorickpeterse commented 1 day ago

Writing an entire TLS stack from scratch is going to be way too much work, and probably isn't a good idea to begin with as Inko has nothing to allow constant-time operations (as needed for correct encryption). As such, we'll start with basing TLS sockets on either OpenSSL or rustls, whichever works best.