Closed snoyberg closed 7 years ago
Right, initial distribution of keys is outside the purview of the spec. The intention is, as you said, that tools such as stack
or cabal-install
will ship with the set of root keys.
Thanks for the response. For the record, this isn't idle curiosity, I'm trying to figure out how to roll out this support in Stack.
Shipping the list of keys in a build tool seems like it would most easily be handled via:
root.json
file into the distribution, likely in the executable itselfroot.json
fileroot.json
file"Is that the plan for cabal-install as well?
I'm not a crypto expert by any means, but in a sense I'm not sure that this is actually any more secure than just downloading the root.json
file over HTTPS, given that the cabal-install/stack executables themselves will be downloaded like this. The other downside I see is likely just based on a lack of knowledge: what happens if the upstream root.json file changes after the executable is shipped?
It's a matter of minimizing TCB. Yes, if cabal-install/stack are downloaded over HTTPS, someone could compromise the root.json they ship with. But they could also compromise the entire executable, so... Whereas, if the keys are downloaded after the fact, that's another possible compromise point; now you can have a good executable but bad keys. It's also worth noting that if cabal-install/stack are shipped via your operating system distro, now the keys can be bootstrapped via the distro's keys. If there's a separate download step, the distro has to know to pre-ship keys to prevent the bootstrapping process from taking place, which is another place where failure can occur.
In any case, TUF provides a mechanism for upgrading when root.json is updated (see section 6.1 of https://github.com/theupdateframework/tuf/blob/develop/docs/tuf-spec.txt ); as a not-hackage-security-contributor I don't know if we've actually implemented it, but in principle this should work.
You're right I guess that downloading the keys over HTTPS, versus downloading the entire distribution over HTTPS, is not more secure in principle. Initial key distribution is always a thorny problems. Ideally you'd piggy back on some other kind of key validation, like for instance a distro's keys. Even that of course then piggy-backs on HTTPS keys in the end because, well, you downloaded that distribution at some point.. In practice I don't think downloading the initial set of root keys over HTTPS is a huge deal. It happens only once and although you'd have a problem if you were unlucky enough to download compromised keys, in all other situations you'd be fine from that point forward.
As regards updates to the root.json -- as Edward mentions, this is in the purview of the spec, and it has in fact been implemented as well. The root dataset contains a relatively large set of root keys (about 10 or so), but does not need to be signed with all 10 (it needs to be signed with some threshold number, which IIRC we've set to 3). So if a client has an old version of the root file, notices that a new version exists, it will download the new version, verify it with its old set of keys, and then accept the new version as the new authoritative version. This allows the root set of keys to slowly change over time.
Interesting about the root.json updates. Are those handled automatically by the calls to check
, or would an explicit call to bootstrap
be necessary to make that happen? If something explicit needs to happen, how can we tell when it's supposed to happen?
That will be handled entirely automatically by check
. Verified updates to the root.json are not considered a bootstrap.
OK, cool, thanks for all the feedback. Here's my summary of the situation, let me know if you disagree:
check
.
Yup, that all sounds reasonable to me.
OK, thanks again. I've implemented the key and key threshold settings in Stack's Hackage Security configuration, and provided default values, so I think the Stack side is in good shape.
You're welcome :-)
In reviewing the workflow in the example-client executable, it appears that the standard workflow would be:
From my understanding, the bootstrap download will grab the public keys used to verify any future downloads. Once those keys are downloaded, they are used to ensure the authenticity of all future steps.
However, the bootstrap download itself has no way to verify it. Furthermore, at least in the example-client, it appears that the HTTP libraries selected do not have TLS support (I know that http-client was used without http-client-tls, as well as the HTTP package), and therefore that bootstrap download seemingly could be trivially MITMed, without even compromising a certificate authority.
What is the expected workflow here for actual clients? Is it intended that security keys be shipped with tools like cabal-install/Stack which use hackage-security? Is the intention to rely on HTTPS for the bootstrap, but the example client skips that for simplicity?