Note: Linus says otherwise, the two are very different: http://git.661346.n2.nabble.com/GPG-signing-for-git-commit-t...
One of the most important reasons it doesn't make sense to sign commits is that keys expire so when you sign something you implicitly say it is valid at most until the key is valid; nothing can be guaranteed after that. It is easy enough to re-sign a tag (even automatically) but you can't re-sign a commit without changing its identity and that defeats the whole purpose of git.
The only reason you'd want to sign commits is to defend from malicious maintainers ie if your patch is changed before being merged, or your authorship is removed, or a patch impersonating you is merged. It's probably better to sign your patches (ie the temporary moment where you interact) in that case: I see there was some work in that direction (https://lwn.net/Articles/813646/) but apparently it hasn't caught up (https://lore.kernel.org/signatures/ shows last signatures end of 2020)
I see that Ryabitsev also announced a git transparency log for the kernel:
https://people.kernel.org/monsieuricon/introducing-the-kerne...
This is very cool.
You wrote:
> ...it is valid at most until the key is valid
I don't follow. Do you mean while the key is valid?
I think the scenario you're describing is:
a) I'm issued a cert.
b) I create (and register) my PGP key.
c) I sign a commit with my key.
d) My cert is revoked.
e) Somehow my key is expired.
f) Somehow my commits are now flagged.
Would your concern be addressed by having transparency logs for both the certs and keys?The scenario I'm describing is simpler:
- You create a PGP key
- You sign a commit with that key
- The key expires (you definitely should have a key rotation process in-place, so keys should expire)
- I want to use your commit. I see it is signed but the key is expired. What is the value of the signature at this moment ?
When a key is expired your commits don't automatically become bad, they just become "unverifiable" but you can't resign them without changing their hash; that's why signing tags is better because you can re-sign tags quickly (before the key is expired).
> Would your concern be addressed by having transparency logs for both the certs and keys?
Transparency logs only catch the problem after they appear and raise the chance that they are detected but they don't prevent it from happening. If we're talking about making sure no one changes your patches/commits under your feets, a transparency log of commits is "enough", and that's basically what the git repository is all about.
> https://lwn.net/Articles/813646/
Huh? Replace one convoluted process for another convoluted and less capable one? Seems like not invented here syndrome. Not surprised it's not used. If you're using email for critical, sensitive work, spend the 15 minutes to learn how PGP works and another to set it up. You can even sign your git commits and tags with them!
Also, get some yubikeys, they work well with pgp.
You can't sign patches directly because then they wouldn't be usable by the git tools like git-am. So you need a meta data-structure that contains all patches and relevant information kinda like a pseudo-commit: the author, message and patch itself. Then that meta data-structure can be pgp-encrypted and sent by email, as described by your link and as you implied was not done
> Why is this a problem, the key was valid however at the time the commit was made?
You want to check the validity of a commit at the moment you use it, not the moment the commit was made: imagine I put up a fake tree, with a fake commit with you as an author but made with a fake key that already expired. What's the use of that signature ? Can a third-party cherry-pick that commit and trusting that "the key was valid at the time the commit was made" ? You can sign that you did something at some point but you can't sign that you never did something, or that you never used a given key.
> spend the 15 minutes to learn how PGP works and another to set it up
You can't seriously believe that it takes 15 minutes to understand how PGP works and 15 minutes to set up a functional environment and expect it to follow the best standards. Even reading the kernel's documentation on how to use pgp (https://www.kernel.org/doc/html/v5.1/process/maintainer-pgp-...) takes more than 15 minutes.
> Also, get some yubikeys, they work well with pgp.
I don't understand what's the link with the rest of the discussion
Only if you want them to expire. They don't have to.
> To my knowledge, there are no effective attacks against sha1 as used by git
Perhaps im missing something, but wouldn't a chosen prefix collision be relavent here? I imagine the real reason is that cost to pull it off for sha1 is somewhere in the $10,000-$100,000 range (but getting cheaper every year) which is lots of $$$ to attack something without an obvious attack scenario that can justify it.
Similarly, the git commits you merge themselves could have that done - the actual git commit serialization gives you a fair bit of ability to append stuff to it that isn't shown in the UI. That wouldn't affect the signed git commits. But it's still dubious to have the ability to change old history in a checkout.
Anyway, Git is apparently moving towards SHA256 support, so hopefully this problem will be fixed soon: https://lwn.net/Articles/823352/
Citation needed. When SHA1 was cracked, it cost $110k worth of cloud computing. And there was some restriction on the two files which matched checksums. IIRC it was like the Birthday Paradox — you don’t pick one and find another sharing the same match, but you generate billions of mutations of similar binaries and statistically two would have the same checksum.
Not exactly easy, fast, cheap, or work with all use cases.
So to get a nefarious file that puts in an exploit or something useful for an attacker AND causes a SHA1 collision is a very very high bar to meet, currently.
Hopefully they replace SHA1 with SHA256/etc before the capability becomes feasible.
I think the last time I saw this come up the response was that git will just ignore your attempt to merge a new file if the checksum is the same. So you would have to compromise the repo server directly to replace it.
Doesn't this imply a tremendous amount of trust in the signer? It sounds like it's only a guarantee about history if every commit was signed.
> Just replacing an object in a repository is not enough; the attacker would have to find a way to distribute that object to other repositories around the world, which is not an easy task. The colliding object would have to function as C source (if the kernel were the target of attack here), and would have to stand up to a casual inspection — it would have to look like proper kernel source. https://lwn.net/Articles/715716/
It literally stands for Secure Hashing Algorithm.
https://www.usenix.org/conference/usenixsecurity20/presentat...
tl;dr: it proves data existed in the past. In the case of a PGP signature on a Git commit, that can prove the signature (and the repo contents) were created prior to the key being compromised.
1) Mostly, because sometimes you don't know when the key was compromised.
The idea is that you can use short-lived keys, bound to certificates via an ACME-style challenge, but based on an email address. The signature goes into a Transparency log to prove it happened while the cert was valid. Then revocation is no longer an issue.
OTS just depends on the Bitcoin block headers (megabytes/year), and the databases of timestamps maintained by the public calenders, (a few GB/year; it's new entry per calendar per second). It's a more easier to archive a few GB of data than the tens of terabytes in the public CT logs.
One way to know the key is valid is if you meet Linus himself and verify it first hand (like when you verify Whatsapp keys, which you do, right?). But not everyone can do that. PGP implements a "web of trust" security model. That means if someone you trust has signed Linus's key, you can verify his key via their signature. This extends beyond one hop; it's up to you how much you trust it based on its signatures.
This is in contrast to centralised systems like SSL/TLS where you have no choice but to trust entities like Microsoft, Google, Verisign etc.
https://www.kernel.org/signature.html
Looks like the kernel.org folks actually use the web of trust model.
This is the reason why the web of trust has, by and large, failed to reach any noteworthy amount of adoption. The web/operating system PKI is good enough for most purposes. Unless your usage scenario involves a massively critical government agency with good reason to be actually paranoid, "good enough" for the web means "good enough" to deliver a public key for the Linux kernel. Or more likely, "good enough" to deliver an installation image for the distribution of your choice that is theoretically signed with PGP/something actually reasonable, but whose signature you won't check anyway because the web PKI is, in fact, good enough.
The distribution of your choice may then possibly have verified the source of the public key, but that's so far upstream of you that, quite honestly, you have no way of checking anyway. Even if you bothered checking this being checked upstream, there are tons of other critical system components for which you would have to repeat this.
The purpose of a signature is to add authenticity assurances on top of integrity guarantees (which are necessary to authenticity, but independent). A document is signed by producing a digest of it, and that digest provides an integrity guarantee. The signature of the digest is then an additional authenticity guarantee.
"Integrity guarantees" means that it is vanishingly unlikely that someone can make a maliciously altered clone of that repository, including its history, all the way to the initial commit, including that signature.
The git hashes already provide pretty strong integrity guarantees of this sort. We can be confident that someone re-creating a fake history cannot end up at the same baseline at the HEAD, with the same commit hash. The strength of that confidence could be increased simply by adding additional, stronger hashes as part of a commit's content.
In terms of authenticity, the signature provides confidence (not a "guarantee") that whoever signed that commit held some beliefs about the repository, sufficient to want to put their signature to it
Someone could be duped into signing a corrupted repository, believing it to be genuine, in which case their beliefs were wrong. (And do not necessarily match their present beliefs!)
Someone could be coerced into signing corrupted repository, in which case their beliefs at the time of signing are that the repository is malicious, and that that they will be harmed if they don't comply.
Someone's private key could be compromised, so that an unauthorized agent perpetrates their signature without their knowledge or consent.
An authenticity assurance is not as easily quantifiable as an integrity guarantee. The integrity guarantee rests in the digest algorithm (how difficult is it to produce a document matching a given digest), but authencity assurances involve people problems.
Also, OpenPGP is an open published standard with an extensive infrastructure of implementations. It's hard to overcome that with a new proposal.
Gpg signature's are the only way of having any verification at all on who wrote a commit
My initial comment was dumb and deserved downvotes, but all git usage isn't the git usage you know of.
Ops, forgot to add a tag to your hash algorithm?