
Rustls: new, modern TLS library written in Rust - adamnemecek
https://github.com/ctz/rustls
======
Perceptes
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.

~~~
progman
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](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.

~~~
gkya
Language having safety features does not guarantee code free of
vulnerabilities.

~~~
smt88
Related reading: [https://tonyarcieri.com/would-rust-have-prevented-
heartbleed...](https://tonyarcieri.com/would-rust-have-prevented-heartbleed-
another-look)

~~~
gkya
Ted comments on this post in the article that it critiques. I do know that
rust has important tools for writing secure programmes but using them is not
really enforced (ie unsafe {}), thus it's possible to write exploitable bug in
it. I want to note that I never used it though.

~~~
fridsun
In the end it's possible in any language to produce exploitable bug (apart
from maybe Erlang VM?). The point is about 1) how hard (probable) it is, 2)
how popular are error checking tools (C static analyzers, Google Thread
Sanitizer, etc), and 3) how fast can the culprit code be found and fixed.

In that regard Rust has reduced both 1) and 3) by only exposing dangerous
features in unsafe {}, and greatly improved 2) since the compiler itself is
checking those errors.

------
oconnore
I'm developing a twitch whenever I see the word "modern" in a software
description. It doesn't actually say anything about what you're doing.

~~~
rurban
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.

~~~
bogomipz
Why are you conflating building architecture and software architecture. I'm
pretty sure no software developer has every thought of their project in terms
of "post-modern."

New Jersey style? The PERL style? I've never heard of "New Jersey style." Are
you joking? I'm almost positive that Perl didn't influence openssl development
at all.

"Modern is more old Stanford-style development." I think you've read way to
much into this. And sorry citing the "The UNIX Hater's Handbook" doesn't do
much for the credibility of your odd argument.

~~~
eatonphil
Look into "New Jersey vs. MIT" and "worse is better". The idea more or less is
that AT&T (in Jersey) cared more about software that shipped whereas MIT cared
about more about good design. MIT produced Lisp and Lisp machines, Bell Labs
produced C and Unix. Who won?

~~~
nickpsecurity
The mainframes and OpenVMS (though its clone, Windows). They're produced
closer to the MIT and cathedral styles with a practical focus. The mainframes
still run the backends of our financial system, logistics, big retailers, and
so on. Most _stuff_ that people consume requires one of them. If a desktop is
involved, it's usually Windows based with 90+% of the market share despite
UNIX workstations and Linux desktops existing for a long time.

So, who won? Nobody. Both had success. Most successful, though, was combining
a little bit of MIT method, cathedral, and ship fast from "worse is better."
That's IBM and Microsoft's approach. A hybrid worthy of another Gabriel essay.

~~~
eatonphil
Thanks for the additional perspective there. I'll have to keep that in mind.

~~~
nickpsecurity
Sure thing. :) And here's the OpenVMS & Windows connection in case you weren't
aware of it:

[http://windowsitpro.com/windows-client/windows-nt-and-vms-
re...](http://windowsitpro.com/windows-client/windows-nt-and-vms-rest-story)

Bill robbing Apple of GUI is well-known. Less known is he stole a more robust
and secure architecture from OpenVMS that was most rock-solid of OS's. They
managed to show what would happen if OpenVMS had no QA process during
development. Yet, recent efforts have gotten Windows Server reliable enough
that the connection is more believable. :)

------
tristor
> 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 :(

~~~
e12e
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".

------
rudenoise
Can anyone comment on how this implementation of TLS compares to the recent
ocaml/mirageOS version?

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](https://mirage.io/blog/why-ocaml-tls)

~~~
hannob
Neither ocaml-tls nor this new one do formal verification. The only TLS
library that does so is miTLS.

~~~
nickpsecurity
Let's not forget the security kernel in Guttman's cryptlib. It's like a
lightweight variant of formal verification that justs makes sure things
interface correctly.

------
nialv7
Rustls use ring for crypto, and it seems most of the crypto algorithm code of
ring is written in C/assembly. Kind of destroy the purpose?

~~~
zmanian
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.

~~~
colemickens
What does Rust the language have to provide in order to achieve side channel
resistant algorithms? That doesn't sound right to me. There are primitives in
other languages that are needed? Or Rust doesn't abstract at the right level?

edit: thanks for the explanations!

~~~
briansmith
Most high-level languages don't provide guaranteed-constant-time behavior at
all. That's a big reason why _ring_ uses lots of BoringSSL's/OpenSSL's
assembly language code.

Also, one of my goals with the _ring_ project is to identify exactly what
constant-time utilities are needed for a crypto library, so that I can draft a
proposal for improving the Rust language and libraries to provide such
features.

~~~
Bromskloss
> Most high-level languages don't provide guaranteed-constant-time behavior at
> all.

Does even C provide such guarantees? Isn't the compiler free to rewrite the
code it's compiling in whatever way it wishes as long as the output is the
same?

~~~
DasIch
C doesn't and even Assembler doesn't entirely. DJB has pushed and is still
pushing(?) Intel to publish more information about these things.

------
teddyh
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.

① _Everything you Never Wanted to Know about PKI but were Forced to Find Out_
([https://www.cs.auckland.ac.nz/~pgut001/pubs/pkitutorial.pdf](https://www.cs.auckland.ac.nz/~pgut001/pubs/pkitutorial.pdf))

~~~
mcpherrinm
This is exactly the sort of cruft that's quite rarely used and should be
omitted from a lean implementation.

I'm not aware of any serious use of RFC 6091. GnuTLS supports it, but I don't
think any other implementations do.

~~~
teddyh
> _I 'm not aware of any serious use of RFC 6091._

Was it really your intention to dismiss my application¹ as not serious?

① [https://www.recompile.se/mandos](https://www.recompile.se/mandos)

~~~
mcpherrinm
It may be serious but I wasn't aware of it.

It seems your project could use x509 client certs as well as gpg ones if you
wanted to use a different TLS library that didn't support GPG.

~~~
teddyh
That seems like a bit of circular reasoning.

We use RFC 6091 because it’s the best fit for our problem, and allows us to
avoid the needless complexity of X.509 certificates, which has caused many
bugs in the past (in essentially all TLS libraries).

~~~
mcpherrinm
Using an obscure feature of one TLS library seems like a bad strategy for
avoiding bugs.

If compatibility doesn't matter, I'd probably use something less crufty, like
[http://noiseprotocol.org/](http://noiseprotocol.org/)

------
bluejekyll
No support for TLS 1.3? Any reason for this, other than work?

~~~
ohazi
It's listed in the "Possible future features" section...

Isn't TLS 1.3 currently still a draft? [1]

[1]:
[https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1...](https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.3_.28draft.29)

~~~
prdonahue
Yes, TLS 1.3 is still in draft[1]. Heard from a co-worker on Friday
(@grittygrease) that draft 14 should be arriving very soon. We (CloudFlare)
have implemented draft 13 in go and are actively testing it—try browsing
[https://tls13.cloudflare.com](https://tls13.cloudflare.com) with Firefox
nightly[2].

I think BoringSSL is also[3] working on their implementation and NSS
(Firefox's SSL/TLS library) implemented[4] draft 11 in v3.23, but OpenSSL
doesn't have plans to until after 1.1 ships[5]; I've heard the former is
expected to land about 6 months prior to the latter as OpenSSL isn't starting
until the RFC is finalized.

1 - [https://tools.ietf.org/html/draft-ietf-tls-
tls13-11](https://tools.ietf.org/html/draft-ietf-tls-tls13-11) (draft 13) 2 -
[https://nightly.mozilla.org/](https://nightly.mozilla.org/) 3 -
[https://www.imperialviolet.org/2015/10/17/boringssl.html](https://www.imperialviolet.org/2015/10/17/boringssl.html)
4 - [https://developer.mozilla.org/en-
US/docs/Mozilla/Projects/NS...](https://developer.mozilla.org/en-
US/docs/Mozilla/Projects/NSS/NSS_3.23_release_notes) 5 -
[https://www.openssl.org/policies/roadmap.html](https://www.openssl.org/policies/roadmap.html)

~~~
oconnore
[http://i.imgur.com/hMqpkev.png](http://i.imgur.com/hMqpkev.png)

~~~
elithrar
Pat missed one bit: you need to head to about:config and set
"security.tls.version.max" to 4.

~~~
prdonahue
Good point. You'd figure I'd remember this after Nick put it on the monster
video wall: [http://imgur.com/cf28rpt](http://imgur.com/cf28rpt) ;)

------
nialv7
Memory safety issues are not the only vulnerabilities in a cryptography
library. A simple example would be timing attacks.

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.

~~~
EugeneOZ
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.

~~~
mtgx
It's also an argument against disruption in general. Great progress happens
when people stop iterating and start rethinking stuff that hasn't been
rethought for decades (and the "stuff" has seen only tiny improvements over
the years following this strategy, too).

~~~
nialv7
Don't get me wrong, I'm not against disruption at all. It's just there're
cases where doing this doesn't make sense. Write a new text editor, invent a
new programming language, sure. But writing a new cryptography library? You
are throwing away decades of effort that went into to harden and secure the
existing library, and your gain is pretty small.

Making things even worse is that you can't really write a crypto library
without using C/assembly. So why write a new crypto library?

~~~
nickpsecurity
"You are throwing away decades of effort that went into to harden and secure
the existing library, and your gain is pretty small."

 _If_ that were true, then it would be a good counterpoint worthy of long
thought. The _reality_ of crypto libraries is that popular ones often had
preventable errors due to bad coding and/or unsafe language that also took
entirely too long to notice.

"you can't really write a crypto library without using C/assembly"

I'd argue you can't write a crypto library using C by default unless you're a
_really_ good coder. C is just an accident of two team's bad hardware:

[http://pastebin.com/UAQaWuWG](http://pastebin.com/UAQaWuWG)

Languages like Modula-3, Free Pascal, and even Fortran were easier to analyze
to ascertain the program's properties. It's why Modula-3 had first, standard
library verified free of specific types of errors. Also took years to make a
certified compiler for C which had been done in other, simpler languages.
Finally, the top performer in secure, systems code is SPARK as illustrated
when re-implementing C crypto in it caught a problem.

[http://www.adacore.com/press/spark-
skein/](http://www.adacore.com/press/spark-skein/)

Note: The portability result was also impressive given it's one of C's
strengths and difficulties.

------
EugeneOZ
Glad to see zero "unsafe" and "panic" :)

------
slimsag
I wonder, will Servo use this?

~~~
Manishearth
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.

~~~
briansmith
> Attacks like downgrade attacks, for example, are not memory unsafety issues.

First, this library only implements TLS 1.2 with AEAD cipher suites
(AES-128-GCM, AES-256-GCM, and ChaCha20-Poly1305) and perfect forward secrecy
(using ECDHE with the X25519, P-256, and P-384 curves, and RSA and ECDSA
signatures). Thus, downgrade to something worse than what NSS or OpenSSL or
BoringSSL consider to be the very best crypto is avoided at a very fundamental
level.

Second, I and other people have been advocating strongly against design
decisions that force implementations to add downgrade vectors. In particular,
there is a version number field in the TLS ClientHello that we know causes
problems. People have proposed solutions to avoid this version number causing
compatibility problems for TLS 1.3, but Mozilla's TLS people have not
supported making this improvement. Thus, we're likely going to have downgrade
issues _by design_ in TLS 1.3 that would be completely avoidable, due in large
part to the people making NSS and other C crypto libraries.

~~~
Manishearth
This is good. However, I mentioned downgrade attacks as an example of the kind
of bug Rust can't solve. Most likely new TLS stacks will not be prone to
downgrade attacks. They might be prone to other logic errors. So will
established TLS stacks, but those are more battle tested. The rust ones will
be too, but eventually, not now.

It's a tradeoff.

~~~
briansmith
Out of curiousity, what sort of evidence of safety is the Servo team using to
evaluate crypto libraries? I'd love to see the criteria.

~~~
larsberg
As we mentioned in the recent Security meetings notes
([https://github.com/servo/servo/wiki/London-
Security](https://github.com/servo/servo/wiki/London-Security) ), there will
be a blog post on blog.servo.org in the coming weeks from the folks on the
team who are making these decisions.

------
zmanian
I can see this being immensely beneficial to environments that rely heavily of
calling out openssl for TLS like node and python.

