Remix.run Logo
▲ kazinator 6 hours ago

Only if the GPG signing process stupidly relies on the SHA-1 hash. I.e. if it takes an unsigned commit and signs only its SHA-1 hash and then creates a new commit with GPG headers. If that's how it works, that is massively stupid and can be fixed without forcing SHA-256 as a git hash. Just have the signing calculate its own digest for its own purposes.

That digest can be the SHA-256; since the infrastructure is there for it, signing should use SHA-256 regardless of what hash is used by the repository for identifying and linking content.

▲semiquaver 3 hours ago | parent | next [-]

  > if it takes an unsigned commit and signs only its SHA-1 hash and then creates a new commit with GPG headers
It does indeed. The bytes passed to GPG when constructing a signed commit look something like:

  tree eebfed94e75e7760540d1485c740902590a00332
  parent 04b871796dc0420f8e7561a895b52484b701d51a
  author Alice <alice@example.com> 1465981137 +0000
  committer Alice <alice@example.com> 1465981137 +0000

  Headline

  Message

where the contents being signed are entirely represented by the oids of the tree object and parent commit object. This string is very similar to the content that is fed to the hash function to produce a normal git commit object id.
▲kazinator an hour ago | parent [-]

Haha, well that is a screw up. The weak tree hash can be attacked, replacing the content that is itself not pulled into GPG.

The "bytes passed to GPG" of course get hashed by GPG, using something better than SHA-1.

All bytes that comprise the commit should be hashed by GPG, rather than depending on the content referencing hash in the object tracking system.

This is something that is possible; it is not a logically deductive necessity that we just scan the topmost object and trust the hashes it contains.

▲dwohnitmok an hour ago | parent [-]

> it is not a logically deductive necessity that we just scan the topmost object and trust the hashes it contains.

It kind of is. Otherwise the whole idea of signing a commit with a backing git history (rather than just a snapshot of a working directory) collapses. The only guarantee you have that the git history is what is claimed by the cryptographic signature is some sort of Merkle tree structure. Either the original one, or you have to construct a whole new parallel one with a better hash, in which case, as I bring up in a cousin comment, why not just use a better hash in your original one?

▲dwohnitmok an hour ago | parent | prev [-]

> If that's how it works, that is massively stupid and can be fixed without forcing SHA-256 as a git hash.

I don't think it's massively stupid. Unless you want to re-hash the entire Merkle tree structure to sign your commit, you basically have to trust the hashes in the Merkle tree (or have a separate parallel Merkle tree) at some point in what you sign, which means you do have to trust the SHA-1 hashes. Otherwise even with a cryptographic signature you can always spoof at least the git repo history (e.g. even if you try to directly hash the entire contents of the current commit).

Re-hashing the entire Merkle tree structure seems prohibitively expensive to generate (even with a lot of caching) and pretty complicated for e.g. verifying a signature. Or you can do that incrementally, but then you're just generating a whole new parallel Merkle tree structure.

Regardless, at the end of the day, you need to trust the integrity of the Merkle tree structure. And you can either do that by trusting the hashes of the current Merkle tree, or you have to completely recreate a new one with more trustworthy hashes, in which case why not just use better hashes in your original tree?