# Signed Git Commit Structure Wolf McNally, Blockchain Commons ## Verifying Commits Using GIt Git can indeed verify commits. Note the `good signature` line below. ```shell $ git show --show-signature 3572bae2999f524635ced380cccaa8fe7ca6fbdf ``` ``` commit 3572bae2999f524635ced380cccaa8fe7ca6fbdf (HEAD -> master, origin/master) gpg: Signature made Fri Mar 1 03:36:22 2024 PST gpg: using RSA key 943652EE38441760C3DC35364B6C2FCF894780AE gpg: Good signature from "Wolf McNally <wolf@wolfmcnally.com>" [ultimate] Author: Wolf McNally <wolf@wolfmcnally.com> Date: Fri Mar 1 03:36:22 2024 -0800 Clarified README. diff --git a/README.md b/README.md index a05bcd9..9a0ea79 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ _For related Threat Modeling, see the [Seed Tool Manual](https://github.com/Bloc ### 1.6.1 (79) * THIS IS A RELEASE CANDIDATE -* Fixed: Some places in the app were still producing version 2 output descriptors. +* Fixed: Some places in the app were still producing version 2 output descriptors. Version 2 output descriptors are still supported for reading but only Version 3 descriptors are now produced. ### 1.6 (78) ``` ## Viewing Commits ```shell $ git cat-file commit 3572bae2999f524635ced380cccaa8fe7ca6fbdf ``` ``` tree de2e850dc1fab0387be6a3ae3f22546dff6631bd parent ed858de10c8bc82a8819d20a5cd0f5748d570bf2 author Wolf McNally <wolf@wolfmcnally.com> 1709292982 -0800 committer Wolf McNally <wolf@wolfmcnally.com> 1709292982 -0800 gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEElDZS7jhEF2DD3DU2S2wvz4lHgK4FAmXhvbYACgkQS2wvz4lH gK6ZFxAAkkAEthu4Cxqz/KgH4C+OeNH4tauGkFzgus6MkwyeqoVLCGxqQ3bYfDLM s6J5LovbMXNiPkloiaTB8XPtVQFI37+Vz2RGXqJnxUAOxa6WasOjJUItRR6G+zjJ QKeHz1DP5JXoEGfxkD6wPXFkOzvd6mhWYYrlduNAr44p17Vhq2w7JCLDm7ukBCJD DI6DObfFvwwXRV4xalLPluSIF079uatjbWJC3O1FOa0fFYrusuWxakMzXHtwOEtU vBurctpwf6qJUicBNymTlMx7HKPYqh5rVBQWOVC5BGJZtrikQN0GmCuDsp7HWdYB 2xGaQVfWRQqVz3POfLqLqq+D95RpEerqmnmtHd0NJx+gwHGJmcxgMBtDBevFZlFG 8f0olImncJmwdg76yYgNJxefnNfqYT/XaDlcWD3SSY5TARReGRtvRVL28hihkKL7 6/66sRzDssQ5/d379pFMxtgrGxEBRs78nIo2Ntxs3Da//+ayjTvoeCOQu+EUvOdu rqDE01dsrXOdMP04od4SaWeBO8FZgQAxSjKRgaub/tjc8X0nclzKaConpT0egtgT UE1dsQrkNYHZOnvKkNTkV7NnF9s8gOXNkHey5ycy/IYzYD8ym/l/n3hNTNfdXlWm MvFMyHTEetg7NgZ1XSyeeRRYGMkTE25FWi3Hj4oY7EjXIgPVQ4g= =gSpB -----END PGP SIGNATURE----- Clarified README. ``` ## Producing the signature image The interesting thing about the commit message above is that it is exactly what is needed to sign or verify, with the exception of the signature itself. In the Git source code, the file `commit.c` contains a function, [`write_commit_tree`](https://github.com/git/git/blob/c3ebe91b40c23a1b70dba36383a23016711d8bc0/commit.c#L1648), which is used to write the above information (without the signature) which is then signed (or verified) by `gpg` or `ssh-keygen` called from within Git. To verify this, we copy the part of the commit tree to a new file, `signed_data.txt`. This removes the signature from the middle of the file, and leaves the blank line separating the signature from the commit message. This is just a regular text file, including a trailing newline character. ``` tree de2e850dc1fab0387be6a3ae3f22546dff6631bd parent ed858de10c8bc82a8819d20a5cd0f5748d570bf2 author Wolf McNally <wolf@wolfmcnally.com> 1709292982 -0800 committer Wolf McNally <wolf@wolfmcnally.com> 1709292982 -0800 Clarified README. ``` We also copy the signature itself to `signature.asc`. The blank line after the `BEGIN PGP SIGNATURE` header must be preserved: ``` -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEElDZS7jhEF2DD3DU2S2wvz4lHgK4FAmXhvbYACgkQS2wvz4lH gK6ZFxAAkkAEthu4Cxqz/KgH4C+OeNH4tauGkFzgus6MkwyeqoVLCGxqQ3bYfDLM s6J5LovbMXNiPkloiaTB8XPtVQFI37+Vz2RGXqJnxUAOxa6WasOjJUItRR6G+zjJ QKeHz1DP5JXoEGfxkD6wPXFkOzvd6mhWYYrlduNAr44p17Vhq2w7JCLDm7ukBCJD DI6DObfFvwwXRV4xalLPluSIF079uatjbWJC3O1FOa0fFYrusuWxakMzXHtwOEtU vBurctpwf6qJUicBNymTlMx7HKPYqh5rVBQWOVC5BGJZtrikQN0GmCuDsp7HWdYB 2xGaQVfWRQqVz3POfLqLqq+D95RpEerqmnmtHd0NJx+gwHGJmcxgMBtDBevFZlFG 8f0olImncJmwdg76yYgNJxefnNfqYT/XaDlcWD3SSY5TARReGRtvRVL28hihkKL7 6/66sRzDssQ5/d379pFMxtgrGxEBRs78nIo2Ntxs3Da//+ayjTvoeCOQu+EUvOdu rqDE01dsrXOdMP04od4SaWeBO8FZgQAxSjKRgaub/tjc8X0nclzKaConpT0egtgT UE1dsQrkNYHZOnvKkNTkV7NnF9s8gOXNkHey5ycy/IYzYD8ym/l/n3hNTNfdXlWm MvFMyHTEetg7NgZ1XSyeeRRYGMkTE25FWi3Hj4oY7EjXIgPVQ4g= =gSpB -----END PGP SIGNATURE----- ``` We can then verify the signature: ```shell $ gpg --verify signature.asc signed_data.txt ``` ``` gpg: Signature made Fri Mar 1 03:36:22 2024 PST gpg: using RSA key 943652EE38441760C3DC35364B6C2FCF894780AE gpg: Good signature from "Wolf McNally <wolf@wolfmcnally.com>" [ultimate] ``` Therefore we now understand how Git produces the image used to sign. I haven't tried this with an SSH-signed commit yet, but I think it will work exactly the same way as a GPG-signed commit.