4 ms·
Signing new commit with new subkey on top of all others is a valid strategy to deal with this problem. Another would be creating new tag and signing it with the
by hdhzy 9y ago
Signing new commit with new subkey on top of all others is a valid strategy to deal with this problem. Another would be creating new tag and signing it with the new subkey.
For me it's not a problem that old commits are signed with revoked keys, there are several ways one can get old broken signatures (e.g. key rotation) and by design they should not be trusted.
One interesting voice in signing all commits by Linus:
> Signing
each commit is totally stupid. It just means that you automate it, and you make the signature worth less. It also doesn't add any real value, since the way the git DAG-chain of SHA1's work, you only ever need _one_ signature to make all the commits reachable from that one be effectively covered by that one. So signing each commit is simply missing the point.
Source: http://git.661346.n2.nabble.com/GPG-signing-for-git-commit-td2582986.html http://git.661346.n2.nabble.com/GPG-signing-for-git-commit-t...
Also, depending one one's threat model signing all commits can still be not sufficient: https://github.com/git/git/commit/a85b377d0419a9dfaca8af2320cc33b051cbed04 https://github.com/git/git/commit/a85b377d0419a9dfaca8af2320...
- 3pt14159 9y agoThe DAG-chain argument is kinda valid but misses the core point: I don't validate an entire codebase every time I commit. I just validate the diff. If later on a commit comes into the codebase that has some sort of evil action then it means that a host of possible scenarios can be ruled out (such as someone else easily faking the commit as me). But if you want to get my key you have to get into my dev machine. There is a class of people that can do that, but it substantially raises the bar. Really what I would like is to make it so my Github account only accepts signed commits, so that it is impossible to impersonate me without my key.
- hdhzy 9y ago> I don't validate an entire codebase every time I commit. Linus' point is that you don't need to validate the entire code base, if you have one signed commit then everything that is "below" is also (implicitly) signed. For example you can have a feature branch that has many small commits and one merge commit that joins feature branch with master and you just need to sign the merge commit to make sure all of these small commits are OK.
- CaliforniaKarl 9y agoIn our group's use case, we're not after the "implicitly-signed" property. We are trying to ensure that the person who is listed as doing the commit actually did the commit. We then have a server-side hook script, which ensures each new commit has been signed by a key kept in a local keyring.
- hdhzy 9y agoJust out of curiosity do you somehow update the local keyring? So that one can update their key information (for example to add revocations and new keys).
- CaliforniaKarl 9y agoThere's a single-digit number of people who can update the local keyring. Which works right now, given that the number of people who push to the repos concerned is in the double-digit range. Our PGP keys don't really change that often.
- stouset 9y ago> Linus' point is that you don't need to validate the entire code base, if you have one signed commit then everything that is "below" is also (implicitly) signed. And Linus is missing the point entirely. Yes, signing a commit implicitly signs the repo all the way back to its beginning. But when I'm actually performing the action of signing this commit, I am not actually going back through every commit and verifying them. The fact that you can use the properties of commit hashes to verify a chain all the way back to the origin of the repo is irrelevant, because that's not what someone actually signing a commit is intending or should be expected to do. When I'm signing a commit, I'm vouching that I am responsible for applying this set of changes to a given state of a repo. It says nothing about my belief in the validity of changes to the repo made before it.
- amazingman 9y ago>> For example you can have a feature branch that has many small commits and one merge commit that joins feature branch with master and you just need to sign the merge commit to make sure all of these small commits are OK. The above example still makes sense, even given your point about the mild absurdity of the idea that the entire repo is implicitly trusted.
- mikegerwitz 9y ago> One interesting voice in signing all commits by Linus: >> Signing each commit is totally stupid. It just means that you automate it, and you make the signature worth less. I've never bought that argument.[0] You should use whatever method actually addresses your threat model. If you're going to sign every commit (I do), then commit (no pun intended) to doing so properly. I use `git add -p` for every commit and review my changes, and enter my smartcard PIN for every single commit. I use it to assert my identity on those commits. If you automate signing past commits, then you open yourself up to attack. Saying "this idea is stupid because everyone is going to do it wrong" is not the basis of a strong argument. The other part of his argument is that the DAG itself allows you to just sign a single commit to verify the entire history. Firstly: that's different than signing each commit, which asserts identity of the author. Secondly, which has always been my argument, is that it rests on the security of SHA-1, which has been under question for quite a while, and has since been demonstrably broken. Are second preimage attacks unlikely with SHA-1? At least today, yes. Consider your threat model. Linus didn't even do that. He said long ago that SHA-1 was intended for integrity, not security, so retrofitting it in an argument is also not useful. [0]: https://mikegerwitz.com/papers/git-horror-story#merge-3 https://mikegerwitz.com/papers/git-horror-story#merge-3 ([0] from 2012 doesn't address the issue in this thread---expired or revoked keys.)
- hdhzy 9y agoBut isn't signing commits basically relying on SHA-1 values of tree and parent (this is what is signed ultimately [0])? That'd be the weakest link of the system. [0]: https://news.ycombinator.com/item?id=10353456 https://news.ycombinator.com/item?id=10353456