I'm so happy to see something like this in development. Every time there's a discussion about OpenSSL vulnerabilities, the topic of a future replacement written in Rust comes up, but no one was stepping up to the plate. Now we have some real progress towards a safer future.
There is also Thrussh, a Rust library for SSH. Rust now begins to shine where it was designed for -- in security.
According to https://doc.rust-lang.org/book/ffi.html it is possible to make callbacks from C code to Rust functions. This way other languages could take advantage of Rust's safe libraries.
It does. There are distinct properties attached to Modernism and Modern. (I'm architect, hence I'm very much attached to these terms. Unlike SW people who didn't grow up with that).
First of all, it's the opposite of Post-Modern, to the perl style do it all in myriads of ways, everything is allowed, OpenSSL style.
With Modern, only the best API and implementation is allowed. API's are Stanford style well-planned ahead of time, and not adhoc added New-Jersey style.
Changes to the API need a rename, not just a major version bump. Hand-waving simplified development models are okay for a post-modern everything is allowed world, whilst modernism aims for long-term goals, making it easier for the user, not the developer.
Modernism is based on "Form Follows Function", and not the other way round.
Reduce it, abstract it. Functionalism is everything, marketing is less important.
And to avoid popular misconceptions, in our current era "Modern" doesn't mean "New" at all. Modern is more old Stanford-style development. Check the Unix Haters handbook e.g.
Rust is new, but this choice alone doesn't allow the use of Modern. Rust is better, because of its superior semantics and guarantees, whilst still adhering to the C ABI. It's a library for everybody afterall, and not comparable to the latest ocaml, haskell or lisp TLS library, which only adheres to their ABI and needs wrappers to be useful for projects in other languages.
I take it to mean "uses current, best practices." For example:
- C++: uses C++11 features, avoids non-RAII resources, prefers standard libraries over older, platform-specific libraries, not written as "C with classes."
- C: doesn't do weird stuff like bypassing malloc(), avoids undefined behavior.
- in general: has a test suite, probably uses continuous testing like Travis, uses modern language features to achieve cleaner & more robust code.
Likewise. "Modern" is a worthless word. In time, the flaws of any "modern" product will become apparent and it will be replaced by something more "modern".
> The following things are broken, obsolete, badly designed, underspecified, dangerous and/or insane. Rustls does not support:
> Client authentication.
> Kerberos.
From a complexity perspective I understand why these things would not be the first choice to implement in a new library. What I don't understand is why they're on the "will never implement" list. Public-key client authentication is to this day one of the strongest methods of authentication that can be used, and not having that available in a library greatly limits its usages in high-security applications, exactly the places where someone might want to stop using OpenSSL and its broken peers.
Kerberos... well... Kerberos is a cluster-fuck. I think everyone knows that. But there are specific applications where Kerberos (or something similar) is exceptionally useful and maybe even necessary. I will acknowledge though that if Kerberos is missing its not a world-ender, because you can implement your own token-based authentication on top of normal TLS without using Kerberos, which in some cases might even be easier because Kerberos is a cluster-fuck. Despite this, though, if configured properly Kerberos is still one of the best methods for doing secure authentication between multiple servers/services via a central authentication mechanism.
If the justification here is simply implementation complexity that might cloud the codebase or otherwise make it harder to audit for security, I do understand that reasoning. I'm just curious specifically in these two cases because they stood out from the list as things that I don't consider "insane", unlike most of the rest of the list.
As an aside, thanks for not implementing RC4. RC4 needs to die die die die. I don't know why anyone is still using it, but nonetheless I see it in the wild still sometimes :(
Odd to see "PSK" on the possible future feature list, with "client authentication" on the "never" list.
Other than that, looks like a nice and sane subset they've picked.
Real shame if they end up avoiding cert-based authentication, though. All other options for authentication are strictly worse, from a security perspective - and leaves more room for implementors to shoot themselves in the foot. For passwords that are intended for human users, for example, you really need some form of rate-limiting. Not to mention the problem of setting up a session first, and then later binding to a user (if authentication succeeds) rather than the simpler "only valid client can connect".
OCaml has more runtime requirements. Can someone comment on how invasive those requirements are, and whether that would limit adoption of the OCaml version compared with C or rust?
Rust is not a good language for low level crypto implementation because it offers no facilities for side channel resistant algorithims. Ring uses the extensively reviewed implementation from BoringSSL and considerable expertise from the author. Ring has a goal of moving as much code that does not need side channel resistant to Rust.
By moving the protocol logic to Rust, the amount of code that needs to be reviewed for memory safety in a TLS library is drastically reduced.
Hi, I'm the person who started the ring project. There is a lot of assembly language code in ring, and there's still some C code too. The thing to keep in mind is that we started from 100% C and assembly language code. Since August 2015, ring has supported a 100% Rust certificate validation library (webpki, it's open source on GitHub), and a 100% Rust TLS implementation (not Rustls, but one that wasn't open source). As we've improved upon the code we started with, we do generally replace it with Rust code, while keeping everything on top of it working. But, we don't replace C code with Rust code just for the sake of doing so. There's always some concrete benefit to each change we make, beyond language advocacy.
The assembly language code we inherited from BoringSSL (and OpenSSL) is really important for performance and for safety from side-channel attacks, like timing attacks. I believe that rewriting most of the assembly language code in Rust would be a net loss for security. I have very long-term ideas for how to avoid needing so much hand-coded assembly, but we have higher-priority things to do now. And, the assembly language code is really good. Really.
The C code is increasingly getting replaced (not rewritten or just transliterated) with Rust code, wherever it makes sense to do so. You can see some of the planned work of this type at https://github.com/briansmith/ring/labels/oxidation. To see the past work, review the commit log of ring.
However, we've done tons of work to make the C code safer too. For example, I've written dozens of patches to eliminate cases of undefined behavior and other unsafe coding patterns in the C code. Many of these changes have been integrated into BoringSSL.
Also, we've greatly reduced the usage of the heap. Already, you can use most of ring's functionality without a heap. Importantly, this means that we have solid evidence that, for almost every ring feature, there is zero chance of use-after-frees, double-frees, or memory leaks. It also means that the memory usage is very predictable, which makes it easier to use in constrained environments.
In addition, I've tried to design the ring API very carefully to limit the potential for things built on top of it to misuse the crypto. For example, the API enforces--statically, at compile time--that an ECDHE key can be used only once. Similarly, it enforces--statically, at compile time--that an AES/ChaCha20 encryption key is never used for decryption, and vice versa. Similarly, it ensures that encryption is always properly authenticated--there's no way to accidentally do "MAC before encrypt" and similar things. We even make sure that you don't use less-safe AES-GCM nonces that aren't exactly 96 bits.
Finally, anything that uses ring get all the advantages that come with Rust automatically, such as Rust's use-after-free protection and data race protection. (ring replaced all the C threading/synchronization stuff using the safer Rust constructs already.)
So, even though there is some C code, and even though there's a lot of assembly language code, things that use ring are still getting lots of Rust's advantages.
There are other alternatives that are "pure" or close to "pure" Rust, such as rust-crypto. But, those libraries are missing important things like RSA and ECDH and ECDSA over the NIST P-256 and P-384 curves. That's all needed for a practical TLS implementation.
My application needs RFC 6091, i.e. using OpenPGP keys instead of the usual X.509 certificates. (Why not X.509? Ask Peter Gutmann¹). This feature is not listed as something they don’t support, nor as something they won’t support, which is odd. Likewise for DTLS (RFC 6347). These omissions are strange.
Rustls doesn't really have to deal with the timing attack issue, because those issues are handled by the underlying crypto library, ring. And, ring wasn't built from scratch. It builds upon all the constant-time crypto code in BoringSSL and OpenSSL. And, we've improved the constant-timedness of the code in several ways and contributed most of those improvements back to BoringSSL.
I hate so much this logic - it stops evolution. Humanity have enough programmers to write new libraries and patch existing code. Competition is better than stagnation.
> Writing a cryptography library from scratch because the old one has too many security holes? Your implementation is likely to have even more.
That's not a reason to never write another crypto library ever. It's a reason to get started on a new one as soon as possible so it can start the process of being vetted.
Probably not. With security sensitive things, the security of the logic itself needs to be good too.
Attacks like downgrade attacks, for example, are not memory unsafety issues.
Servo would need a library that is battle-tested and has a vulnerability policy. The Rust libraries could be in this category in the future, but not right now. Using something like nss or boringssl, like other browsers, would be our best bet.
[+] [-] Perceptes|9 years ago|reply
[+] [-] progman|9 years ago|reply
According to https://doc.rust-lang.org/book/ffi.html it is possible to make callbacks from C code to Rust functions. This way other languages could take advantage of Rust's safe libraries.
[+] [-] oconnore|9 years ago|reply
[+] [-] rurban|9 years ago|reply
First of all, it's the opposite of Post-Modern, to the perl style do it all in myriads of ways, everything is allowed, OpenSSL style. With Modern, only the best API and implementation is allowed. API's are Stanford style well-planned ahead of time, and not adhoc added New-Jersey style. Changes to the API need a rename, not just a major version bump. Hand-waving simplified development models are okay for a post-modern everything is allowed world, whilst modernism aims for long-term goals, making it easier for the user, not the developer.
Modernism is based on "Form Follows Function", and not the other way round. Reduce it, abstract it. Functionalism is everything, marketing is less important.
And to avoid popular misconceptions, in our current era "Modern" doesn't mean "New" at all. Modern is more old Stanford-style development. Check the Unix Haters handbook e.g. Rust is new, but this choice alone doesn't allow the use of Modern. Rust is better, because of its superior semantics and guarantees, whilst still adhering to the C ABI. It's a library for everybody afterall, and not comparable to the latest ocaml, haskell or lisp TLS library, which only adheres to their ABI and needs wrappers to be useful for projects in other languages.
[+] [-] haberman|9 years ago|reply
- C++: uses C++11 features, avoids non-RAII resources, prefers standard libraries over older, platform-specific libraries, not written as "C with classes."
- C: doesn't do weird stuff like bypassing malloc(), avoids undefined behavior.
- in general: has a test suite, probably uses continuous testing like Travis, uses modern language features to achieve cleaner & more robust code.
[+] [-] ctz|9 years ago|reply
- in reference to Mozilla's "Modern TLS" profile: https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_com...
- as an antonym for the unlimited backwards-compatibility, kitchen-sink-comprehensive approach of (say) OpenSSL or NSS.
[+] [-] stormbrew|9 years ago|reply
[+] [-] sdegutis|9 years ago|reply
[+] [-] caf|9 years ago|reply
[+] [-] rectang|9 years ago|reply
[+] [-] tristor|9 years ago|reply
> Client authentication.
> Kerberos.
From a complexity perspective I understand why these things would not be the first choice to implement in a new library. What I don't understand is why they're on the "will never implement" list. Public-key client authentication is to this day one of the strongest methods of authentication that can be used, and not having that available in a library greatly limits its usages in high-security applications, exactly the places where someone might want to stop using OpenSSL and its broken peers.
Kerberos... well... Kerberos is a cluster-fuck. I think everyone knows that. But there are specific applications where Kerberos (or something similar) is exceptionally useful and maybe even necessary. I will acknowledge though that if Kerberos is missing its not a world-ender, because you can implement your own token-based authentication on top of normal TLS without using Kerberos, which in some cases might even be easier because Kerberos is a cluster-fuck. Despite this, though, if configured properly Kerberos is still one of the best methods for doing secure authentication between multiple servers/services via a central authentication mechanism.
If the justification here is simply implementation complexity that might cloud the codebase or otherwise make it harder to audit for security, I do understand that reasoning. I'm just curious specifically in these two cases because they stood out from the list as things that I don't consider "insane", unlike most of the rest of the list.
As an aside, thanks for not implementing RC4. RC4 needs to die die die die. I don't know why anyone is still using it, but nonetheless I see it in the wild still sometimes :(
[+] [-] e12e|9 years ago|reply
Other than that, looks like a nice and sane subset they've picked.
Real shame if they end up avoiding cert-based authentication, though. All other options for authentication are strictly worse, from a security perspective - and leaves more room for implementors to shoot themselves in the foot. For passwords that are intended for human users, for example, you really need some form of rate-limiting. Not to mention the problem of setting up a session first, and then later binding to a user (if authentication succeeds) rather than the simpler "only valid client can connect".
[+] [-] unknown|9 years ago|reply
[deleted]
[+] [-] rudenoise|9 years ago|reply
How much does formal verification matter/increase confidence?
Is the rust version easier to integrate with other stacks?
https://mirage.io/blog/why-ocaml-tls
[+] [-] hannob|9 years ago|reply
[+] [-] jeffdavis|9 years ago|reply
[+] [-] nialv7|9 years ago|reply
[+] [-] zmanian|9 years ago|reply
By moving the protocol logic to Rust, the amount of code that needs to be reviewed for memory safety in a TLS library is drastically reduced.
[+] [-] briansmith|9 years ago|reply
The assembly language code we inherited from BoringSSL (and OpenSSL) is really important for performance and for safety from side-channel attacks, like timing attacks. I believe that rewriting most of the assembly language code in Rust would be a net loss for security. I have very long-term ideas for how to avoid needing so much hand-coded assembly, but we have higher-priority things to do now. And, the assembly language code is really good. Really.
The C code is increasingly getting replaced (not rewritten or just transliterated) with Rust code, wherever it makes sense to do so. You can see some of the planned work of this type at https://github.com/briansmith/ring/labels/oxidation. To see the past work, review the commit log of ring.
However, we've done tons of work to make the C code safer too. For example, I've written dozens of patches to eliminate cases of undefined behavior and other unsafe coding patterns in the C code. Many of these changes have been integrated into BoringSSL.
Also, we've greatly reduced the usage of the heap. Already, you can use most of ring's functionality without a heap. Importantly, this means that we have solid evidence that, for almost every ring feature, there is zero chance of use-after-frees, double-frees, or memory leaks. It also means that the memory usage is very predictable, which makes it easier to use in constrained environments.
In addition, I've tried to design the ring API very carefully to limit the potential for things built on top of it to misuse the crypto. For example, the API enforces--statically, at compile time--that an ECDHE key can be used only once. Similarly, it enforces--statically, at compile time--that an AES/ChaCha20 encryption key is never used for decryption, and vice versa. Similarly, it ensures that encryption is always properly authenticated--there's no way to accidentally do "MAC before encrypt" and similar things. We even make sure that you don't use less-safe AES-GCM nonces that aren't exactly 96 bits.
Finally, anything that uses ring get all the advantages that come with Rust automatically, such as Rust's use-after-free protection and data race protection. (ring replaced all the C threading/synchronization stuff using the safer Rust constructs already.)
So, even though there is some C code, and even though there's a lot of assembly language code, things that use ring are still getting lots of Rust's advantages.
There are other alternatives that are "pure" or close to "pure" Rust, such as rust-crypto. But, those libraries are missing important things like RSA and ECDH and ECDSA over the NIST P-256 and P-384 curves. That's all needed for a practical TLS implementation.
[+] [-] teddyh|9 years ago|reply
① Everything you Never Wanted to Know about PKI but were Forced to Find Out (https://www.cs.auckland.ac.nz/~pgut001/pubs/pkitutorial.pdf)
[+] [-] mcpherrinm|9 years ago|reply
I'm not aware of any serious use of RFC 6091. GnuTLS supports it, but I don't think any other implementations do.
[+] [-] Perceptes|9 years ago|reply
[+] [-] Bromskloss|9 years ago|reply
Wow, the future is here!
[+] [-] tener|9 years ago|reply
[+] [-] bluejekyll|9 years ago|reply
[+] [-] ohazi|9 years ago|reply
Isn't TLS 1.3 currently still a draft? [1]
[1]: https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1...
[+] [-] peter_tonoli|9 years ago|reply
[+] [-] nialv7|9 years ago|reply
Writing a cryptography library from scratch because the old one has too many security holes? Your implementation is likely to have even more.
We should really concentrate on making one implementation secure, instead of creating more libraries.
[+] [-] briansmith|9 years ago|reply
[+] [-] EugeneOZ|9 years ago|reply
[+] [-] johncolanduoni|9 years ago|reply
That's not a reason to never write another crypto library ever. It's a reason to get started on a new one as soon as possible so it can start the process of being vetted.
[+] [-] EugeneOZ|9 years ago|reply
[+] [-] slimsag|9 years ago|reply
[+] [-] Manishearth|9 years ago|reply
Attacks like downgrade attacks, for example, are not memory unsafety issues.
Servo would need a library that is battle-tested and has a vulnerability policy. The Rust libraries could be in this category in the future, but not right now. Using something like nss or boringssl, like other browsers, would be our best bet.
[+] [-] unknown|9 years ago|reply
[deleted]
[+] [-] unknown|9 years ago|reply
[deleted]
[+] [-] zmanian|9 years ago|reply