Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cargo signing #25

Open
lukehinds opened this issue May 8, 2021 · 12 comments
Open

Cargo signing #25

lukehinds opened this issue May 8, 2021 · 12 comments
Assignees

Comments

@lukehinds
Copy link
Member

lukehinds commented May 8, 2021

Creating this issue to start gathering thoughts on crates sigstore signing.

Current Status

Cargo performs no signing verification of crates at present.

Users running the cargo install command will download unsigned code which will be compiled and executed.

There has been discussions around using TUF, but progress is arguably very slow, as its been in discussion for over 5 years now [0] / [1].

In thread [0] there appears to be a preference for a TUF based CA / PKI: "So, my vote is for a centrally managed PKI, and more specifically for TUF."

A pull request was made to sign registry index commits [2], was never merged and discussion has moved to this issue [3]. Discussions there have dried up (last comment was late last year). Two sigstore community folks @trishankatdatadog and @joshuagl comment on a document produced here at [4] which supports what we all believe, TUF + TLOGS is a "belt and braces" approach and they compliment each other. I know @SantiagoTorres has looked at this before.

[0] rust-lang/crates.io#75
[1] https://www.reddit.com/r/rust/comments/6qjpzf/could_the_security_of_cargo_and_the_crates_system/
[2] rust-lang/rfcs#2474
[3] rust-lang/cargo#4768
[4] https://ssl.engineering.nyu.edu/blog/2020-02-03-transparent-logs

@lukehinds
Copy link
Member Author

lukehinds commented May 8, 2021

I will add to the above as more information comes in and I have had some time to look at cargos infra and code. Please do chime in with any views or any other historically useful threads..

My own view on this matter is that the rust community are stuck in the quandary of wanting the best approach (which of course they should be driving for), but as a result perfect is becoming the enemy of good and they have spent around 5-6 years running infra with no cryptographic guarantees of its packages.

@lukehinds lukehinds self-assigned this May 8, 2021
@tarcieri
Copy link

tarcieri commented May 18, 2021

As a general thought: the crates.io team seems pretty overworked right now just keeping the lights on. It's probably not a good time to put anything more on their plate.

I think an interesting way to move forward here that will at least temporarily avoid integration headaches with cargo would be to prototype something like TUF + cargo as an external tool, possibly leveraging the work in something like rust-tuf or rough, or just doing sigstore verification in a manner similar to Go's sumdb.

Such a tool could take care of things like updating the crates.io index (e.g. checking the latest index is indexed in something like sigstore, then updating the local index using something like the crates-index crate) as well as downloading dependencies which aren't already in the local crate cache and verifying they also have a hash indexed in something like sigstore.

You could imagine a tool that exposes the same UI as cargo, but handles doing verified index updates/crate downloads, then drives cargo with the --offline flag.

@tarcieri
Copy link

Something else I suggested on the call was that rustup might be a better starting point, and actually plays nicely into a story for cargo/crates.io.

One thing I've gotten out of discussions with some core devs is that they'd like to have a single trust root for rustup, Rust releases/channels, and crates.io, and in that regard rustup is a great place to start as it could also bootstrap the root keys for cargo.

Here's a relevant issue: rust-lang/rustup#2028

I think this would be a pretty interesting application of sigstore: rustup self update could check sigstore to ensure that new releases it's about to install are included.

@tarcieri
Copy link

I think an interesting way to move forward here that will at least temporarily avoid integration headaches with cargo would be to prototype something like TUF + cargo as an external tool, possibly leveraging the work in something like rust-tuf or rough, or just doing sigstore verification in a manner similar to Go's sumdb.

Regarding this, here's a WIP tool which roughly fits this bill: https://github.com/kutometa/carnet

@lukehinds
Copy link
Member Author

Sorry for the inaction @tarcieri , agree rustup is definately good a place to start here. Will take a look at carnet

@lukehinds
Copy link
Member Author

@tarcieri et al, where does rustup currently store its artefacts (such as the shell script, windows binaries)?

@tarcieri
Copy link

tarcieri commented Jun 1, 2021

rustup is designed to be used by an individual user and does not support global installation (to my knowledge).

It uses this crate to determine the user's home directory, along with CARGO_HOME and RUSTUP_HOME:

https://crates.io/crates/home

@lukehinds
Copy link
Member Author

lukehinds commented Jun 1, 2021

ah sorry, should have been more specific: where is the shell script (that you pipe into sh) and the blobs that the shell script pulls down get hosted (something like ec2 bucket etc)?

@tarcieri
Copy link

tarcieri commented Jun 1, 2021

Appears to be pointed at Cloudfront:

$ host sh.rustup.rs
sh.rustup.rs is an alias for dks7yomi95k2d.cloudfront.net.

Beyond that, I'm not sure.

@lukehinds
Copy link
Member Author

lukehinds commented Jun 15, 2021

as for rustup, I built this protoype so that we at least have some trust around the script which is being pulled down (and is where codedev got breached).

https://twitter.com/decodebytes/status/1404540227474046980

This works as follows.

  1. Someone makes a change to rust-init.sh
  2. They sign that change using sigstore (signing cert based on OIDC / entry into transparency log)
  3. A commit is then made which contains the sig, signing cert and the updated script: https://github.com/lukehinds/rustup/commit/cd091d867aec7038322bfe2bc41a2bdd9235bef0
  4. A release is made based on the above commit: https://github.com/lukehinds/rustup/releases/tag/v1.0

This is then what happens in the background.

curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/lukehinds/rustup/releases/latest | jq '.tag_name'
"v1.0"
curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/lukehinds/rustup/git/ref/tags/v1.0 |jq '.object'|grep sha
  "sha": "cd091d867aec7038322bfe2bc41a2bdd9235bef0",
curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/lukehinds/rustup/commits/cd091d867aec7038322bfe2bc41a2bdd9235bef0 |
 jq '.files'

The nice thing then is we have even more trust guarantees. The signing event is stored into github repo, which in turn has its own security controls (uses need 2FA) etc. We then have sigstore which adds even more layers, a maintainer uses an ODIC account to sign (no long term management of private keys). The signing event gets recorded into a public transparency log.

@tarcieri
Copy link

FYI, discussion around Sigstore and TUF for crate signing seems to be picking up:

https://internals.rust-lang.org/t/pre-rfc-using-sigstore-for-signing-and-verifying-crates/18115/2

@tarcieri
Copy link

There's now an RFC open here for signing crates with Sigstore: rust-lang/rfcs#3403

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants