Hacker Newsnew | past | comments | ask | show | jobs | submit | more briansmith's commentslogin

> The EverCrypt primitives are formally proven, whereas ring has no such formal proofs.

We do use some of the Fiat Crypto stuff for elliptic curve computations. I am not opposed to switching some stuff to use EverCrypt or other things that might be better, as long as the performance is the same or better, and as long as there's a clear path towards that code being in Rust.

> ring has several primitives that are assembly only and have no portable fallback.

Either in the latest release (0.16.20) or the upcoming release, there is a portable non-assembly implementation of everything in ring.


Thanks for the correction!


The goal of the ring project is to be much safer than OpenSSL without any notable decrease in performance. That is, my goal is to give you memory safety "for free" if you switch from OpenSSL/BoringSSL to ring. In some cases it is better than free because we end up being faster.

The assembly code in ring is some of the most heavily-tested code in the world. It's fuzzed pretty much continuously in various projects that use it, and a bunch of testing has been done on it. It is from BoringSSL, and much of it is shared with OpenSSL and/or Linux kernel. As we are able to replace the assembly code with safer code, we'll continue to do so, just like we've replaced most of the C code with which we started.


thank you for your work in this. we've been using rust-tls/ ring for some time now in our product.


When I merged security fixes from BoringSSL/OpenSSL, I yanked the old versions of ring that didn't have the security fixes. I thought that was a pretty reasonable policy, however people who like to comment in these forums disagreed very loudly, so I stopped doing that. Not sure that's better, but there's less complaining.

In general, my initial thinking was based too much on the assumption that people would help maintain the things that depend on ring to update them to the latest release. It turns out there's less cooperative maintenance like that than I expected.


I loved your policy and appreciated how principled it was. People here are too harsh and most of them don't write code in Rust where regular updates are much more the norm than other communities.


Yanking releases which have bugs / vulnerabilities in them is very much not the norm in the Rust community.

This is why projects like https://github.com/RustSec exist.


I don't know about that, crates that RustSec has advisories for are often yanked, in my experience.

Bugs? No. Security bugs? Yes.



Sure, it's quite possible that not every single one ever is. One single version of one single library not being yanked doesn't mean that nobody ever does it.


> In general, my initial thinking was based too much on the assumption that people would help maintain the things that depend on ring to update them to the latest release. It turns out there's less cooperative maintenance like that than I expected.

I think that's a reasonable assumption.

What isn't reasonable is to expect people to "upgrade right now". Not everybody lives in your time zone, so when you yank a dependency, you might be breaking a workflow in the other part of the world at 3 am, and if some webserver doesn't deploy or whatever, somebody will get a call.

I'm not suggesting this is an easy problem to solve, but there is a wide range of options before "never upgrading" and "force an upgrade right now". Some of these are supported by Cargo via Cargo.lock, etc. so the responsibility for how this is handled doesn't fall on one library or person.

Building a secure system is also not the exclusive responsibility of `ring`. If I'm building a secure system, I have to assume that `ring` will have a bug that's exploitable at some point, and that someone will use it in a zero-day, and my system needs to be secure even if that happens.

So "updating right now" doesn't buy me much. Its something that can wait until after a meeting, or after my vacation, or until monday. Its not a "the world is on fire" situation, even though it would still be pretty severe.

I'd still like to get "notified" ASAP and asynchronously somehow. While updating ring is low effort, the update still needs to "internal QA,..." etc. at companies, and that takes people's time that must be planned on.


In a properly-designed CI/CD system, a dependency getting yanked isn't an emergency unless you choose to treat it as such. In particular, if you don't want your build to fail because some dependency got yanked then you need to use a Cargo.lock, and you need to ensure that you're not overzealous in your use of cargo-deny and similar tools.

I'm not sure if you were affected by this, but Cargo introduced a (regression) bug a couple years ago that caused it to fail when a crate got yanked when it shouldn't have. This bug was eventually fixed, but lots of people blamed ring for this bug. If this Cargo bug hadn't been introduced then most people who were using Cargo correctly wouldn't have been negatively affected by ring's old policy.


With software which needs security considerations it's also common to want to test the vulnerable versions, write tests internally and verify the broken/fixed behaviour. Yanking old versions makes this annoying. (Yes you can rebuild from the repo tag, but that's annoying, especially in indirect dependencies)


That hasn't been the case for a long time, a year or more.


There are lots of people doing awesome stuff with cryptography in Rust, including (but not limited to) the people who maintain Mundane.

You are right that ring has a much-reduced set of build dependencies compared to Mundane/BoringSSL. However, it is also true that Google implemented some build system support (to support Mundane?) that will help ring's custom build system a lot too, once I find some time to make use of it.


There isn't yet any name mangling in the C/assembly function names that would prevent collisions between two incompatible versions. I use `links = "ring-asm"` in Cargo.toml to prevent people from accidentally including two versions of ring for that reason. I am going to switch that to use a different mechanism.


> This problem is compounded by it only being possible to link one version of Ring in to the same program.

I am planning to fix this in ring early in 2021 (January)...

> Even if you don't depend on Ring directly, Ring could appear as a dependency of many of your dependencies. This forces you into upgrading all of your Ring-depending dependencies in lockstep. You cannot upgrade any until all of these dependencies support the same latest version of Ring.

Then you won't need to upgrade everything in lockstep.

That said, I still do recommend everybody only use the latest version.


> I am planning to fix this in ring early in 2021 (January)...

This is definitely the piece that gives the current versioning policy its sharp edge, so it's great news that the fix will arrive soon.

Thanks for your hard work on Ring!


Thanks, this would be great! Recently had to help someone at work update our dependencies and it was difficult to justify why it was so difficult. Ring was unfortunately the cause of the difficulty.


I commented on this at https://github.com/briansmith/webpki/issues/130. This is nothing to be concerned about, for quite a few reasons. I don't expect any compatibility issues with being stricter since Google Chrome's new X.509 processing does enforce the stricter syntax.


I spent significant effort writing the name constraint implementation in mozilla::pkix (used by Firefox) and by webpki (used by Rustls) to fix this situation. The result is summarized by Netflix:

> The result was that every browser (except for Firefox, which showed a 100% pass rate) and every HTTPS client (such as Java, Node.JS, and Python) allowed some sort of Name Constraint bypass.

- https://netflixtechblog.com/bettertls-c9915cd255c0

Since then, Google Chrome has implemented and deployed a new certificate processing library on some (most?) platforms it supports, and I bet they have similar or better name constraint support. I believe Apple has also improved their implementation.

> I wish that NameConstraints were better supported, to make it easier to support intermediate CAs; for instance, prove you own example.com and you could then have a CA restricted to *.example.com. But right now, that just doesn't seem feasible.

Since the aforementioned improvements have shipped in production browsers, it is much more practical, from a technical standpoint, to do that. The real problem now is browsers' CA policies. As I understand it, they do not want you to be able to get your own name-constrained intermediate CA certificate. The CA that issues you the intermediate CA certificate would be on the hook, with the consequence of being removed from the root CA programs, if you issued a malformed certificate. And there are other issues with the policy. I hope there are improvements to the browsers' CA policies to make this practical, but I wouldn't hold my breath.


Thank you for working on this!

> Since the aforementioned improvements have shipped in production browsers, it is much more practical, from a technical standpoint, to do that.

What about non-browser HTTPS/TLS libraries? Even if browsers support it perfectly, this doesn't seem like something CAs should start deploying if widely used libraries have problems with it. And based on the test results from BetterTLS, it looks like widely used libraries still have problems with it.

Also, the BetterTLS article gives an example of a NameConstraints for "192.168.0.0/16"; I don't think that's something a public CA could reasonably issue, for a variety of reasons (conflicts with routers, IoT devices, and many other things). We need some reasonable solution for "local network" devices, and in particular for devices where a user may be able to get hold of the private key, but in the meantime I don't think publicly valid IP-address certificates make sense.

> The CA that issues you the intermediate CA certificate would be on the hook, with the consequence of being removed from the root CA programs, if you issued a malformed certificate.

Given that today, such an intermediate CA could be used for arbitrary MITM, that's entirely understandable. If there are additional constraints that an intermediate certificate needs to have, we need to have enforcement mechanisms to support such policies, so that an intermediate CA can't create certificates that may lead to MITM or similar attacks.

- Root CA policies for proving access to (star).yoursite.example such that you can get an intermediate CA.

- Root CA policies for the valid duration of intermediate CA certificates (no longer than X, no longer than the proven ownership of your domain...). This already constraints the valid duration of certificates underneath the intermediate CA.

- Policies for requiring Certificate Transparency (e.g. any such intermediate certificate still has to use CT logs, such that individual certificates must appear in the CT logs to be considered valid). This could be done by policy in browsers, such that any CA opting into issuing intermediate CA certificates must use CT for everything; that's where we're going for all CAs anyway.

- Do we have mechanisms to ensure that an intermediate CA can't issue another intermediate CA certificate?

- Policies for wildcards underneath intermediate CAs. If you have an intermediate CA for (star).yoursite.example, under what circumstances can you issue a wildcard certificate underneath it, and for what domains?

- Under what circumstances should you be able to get an intermediate certificate for something like (star).yoursite.internal? Should you, or should all names chain up to a domain you prove ownership of (e.g. (star).internal.yoursite.example)? There's potential value in internal-only domain names, and this would reduce the scope of attacks (preventing the intermediate CA from issuing certificates for your public site), but ownership issues might become tricky.

- Related: Today, if you want to MITM example.com, you need to get a root CA to sign your certificate. If example.com obtains an intermediate CA, it's potentially easier for an adversary to somehow obtain a certificate for example.com or www.example.com signed by that intermediary, depending on example.com's infrastructure. (It's also potentially easier for an adversarial jurisdiction to force example.com to surreptitiously mint a certificate; CT would help there, but this still seems like substantially more attack surface.) Is there some way we can make that less likely and more difficult as an exploit vector?

- Policies for the duration of certificates underneath intermediate CAs.

- Policies for handling revocation of certificates underneath intermediate CAs.

- Policies for the use of dedicated HSMs for intermediate CAs. Should we make that a policy requirement?

- Eventually, when NameConstraints becomes not only usable but best-practice for intranets, browsers and libraries could start defaulting to only loading certificates from the system certificate store iff they have NameConstraints that meet some appropriate policy.


I received a bug bounty from Mozilla after leaving, in a browser component I previously worked on. I didn't write the vulnerable code though.

On the other hand, Google refused to pay me a bug bounty for a bug I found in the same component, in part because I used to work on it when I was at Mozilla, even though I didn't write the vulnerable code.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: