back

by dochtman·3y ago·view on hn ↗
Reminder that rustls exists as a pretty mature TLS implementation in safe Rust (thus systematically avoiding issues like this). Thanks to Brian Smith for creating the webpki crate which was thoroughly engineered from the start to avoid stuff like this.

rustls has C bindings these days: https://github.com/rustls/rustls-ffi

I've started work on Python bindings too, with the idea that it probably wouldn't be crazy hard to do something that can pass as an `ssl.SSLSocket`. Please sponsor me on GitHub if that's something you'd like to use (https://github.com/sponsors/djc).

Note, we're aware that by far the biggest impediment to adopting rustls is the lack of support for IP addresses in certificates (we currently need a DNS name). This work is funded and should be completed in the next few months.

4 comments
Rustls only supports tls 1.3 and 1.2, as a design choice - so long as cutting older clients off is an acceptable choice, you should be using rustls.
TLS 1.2 has been supported by every major browser since 2014. Using a browser older than that is just simply irresponsible.
There's a reason why IETF deprecated TLS 1.0 and 1.1. So your point is somewhat moot. If anyone's using either of these, they're just waiting to be exploited.
The criticisms that I have heard regarding ring/rustls is that the crypto primitives are implemented in assembly and there is no portable reference implementations that can be used to verify them.

In contrast, EverCrypt is a formally proven TLS implementation. There is a portable implementation of all algorithms that is used to verify the correctness of the assembly implementations.

https://project-everest.github.io/

Work is ongoing to use FiatCrypto-based implementations for the primitives, which is discussed a bit here:

https://www.crowdsupply.com/sutajio-kosagi/precursor/updates...

That is great to see and a welcome change.

Also interesting to see the Precursor project getting so deep in the weeds! I saw that project on crowd supply months ago and thought it was notable.

What is performance like? We had to move off libressl because of performance, which makes me sad.

In particular, does it support all the common crypto accelerator CPU instructions? How does it fare on the microbenchmarks the various openssl forks ship?

There are fairly comprehensive measurements from 2019:

https://jbp.io/2019/07/01/rustls-vs-openssl-performance.html

I'm pretty sure current versions of rustls are faster than the ones from 2019, but I don't have an intuition for how OpenSSL performance has evolved in the past three years.

I'd like to do another comparison some time soon.

(Yes, the underlying ring crypto library should take advantages of specific instructions available on common CPU architectures.)

Where's the language spec? The reference is nice but it's not a formal specification.

So much undefined behavior - more than C! /s

Edited to reflect sarcasm as rustaceans apparently can't infer it.

In my understanding it would be hard to make the case that Rust actually has more undefined behavior than C -- most kinds of undefined behavior in C have been carefully avoided in Rust, although, yes, there is no piece of paper ratified by a bunch of national technology institutes that describes Rust.

See also this recent blog post:

https://blog.m-ou.se/rust-standard/

While the rust community might not believe their language needs a specification, some of their would-be customers have business requirements surrounding a specification that cannot be fulfilled with a reference.

edit: clarity

A standard or a specification? Anyway, hopefully Ferrocene will be able to provide those folks what they need.

https://ferrous-systems.com/ferrocene/

Thank you for catching this mistake on my part, fixed.
Can you explain what the difference is between a standard and a reference?
See edit
Of course you'd expect a formal specification to include details on what the fundamental data types actually are - C11 can't be nailed down on what char is, it defines it as a type large enough to store a member of the implementation-defined basic character set with implementation defined signedness. Which means you could have a valid implementation with anything from a 4-bit unsigned char to a 256 bit or larger signed char
> Which means you could have a valid implementation with anything from a 4-bit unsigned char to a 256 bit or larger signed char

This is not quite accurate; there is no upper limit to the number of bits in a char (except for INTMAX_MAX, perhaps), but it cannot have any fewer than 8 bits, including a possible sign bit.

All the C types have had minimum allowed ranges going back to ANSI C.

For 'char', it must at least support the range 0 to 127 (and in addition, it must have the same range as either 'unsigned char' or 'signed char').