Hi! ludo@gnu.org (Ludovic Courtès) skribis: > Sixth, OK, we’ll use libgit2, and write Guile bindings, maybe based on > the CHICKEN bindings², easy! Well no, it turns out that libgit2³ has no > support for signed commits (the ‘signature’ abstraction there has > nothing to do with OpenPGP signatures.) > > Seventh, even if it did, what would we do with the raw ASCII-armored > OpenPGP signature? GPG and GPGME are waaaay too high-level, so we’d > need to implement OpenPGP (in Guile, maybe based on the OpenPGP library > in Bigloo?)?! This bit was too pessimistic it seems. :-) With the quick-hack libgit2 bindings attached, I can run this program, which authenticates HEAD: --8<---------------cut here---------------start------------->8--- (use-modules (guix git) (guix gnupg) (srfi srfi-11) (srfi srfi-26)) (let* ((repo (open-repository ".")) (head (repository-head repo)) (commit-id (reference-target head))) (let-values (((signature signed-data) (commit-signature repo commit-id))) (with-fluids ((%default-port-encoding "UTF-8")) (call-with-output-file "/tmp/s" (cut display signature <>)) (call-with-output-file "/tmp/d" (cut display signed-data <>))) (pk (gnupg-verify "/tmp/s" "/tmp/d")))) --8<---------------cut here---------------end--------------->8--- … which gives: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guile t.scm gpg: Signature made Thu 21 Jul 2016 06:53:27 PM CEST using RSA key ID 3D9AEBB5 gpg: Good signature from "Ludovic Courtès " [full] gpg: aka "Ludovic Courtès " [full] gpg: aka "Ludovic Courtès (Inria) " [full] ;;; (((unparsed-line "[GNUPG:] NEWSIG") (signature-id "5U2RqMgQpDFefFuBzsYBDsrL9xg" "2016-07-21" 1469120007) (good-signature "090B11993D9AEBB5" "Ludovic Courtès ") (valid-signature "3CE464558A84FDC69DB40CFB090B11993D9AEBB5" "2016-07-21" 1469120007) (unparsed-line "[GNUPG:] TRUST_FULLY"))) --8<---------------cut here---------------end--------------->8--- So I think we can go from here. Our repo would contain a Scheme list of authorized OpenPGP fingerprints, and we’d check whether the fingerprint that shows up in ‘valid-signature’ above is among them (IMO this is better than using a GnuPG keyring because GnuPG keyrings are opaque binary blobs—we wouldn’t be able to diff subsequent revisions of the keyring—and they contain full OpenPGP keys, including signature packets and all that, which we don’t need/want for authorization purposes; we may still want to store a keyring though, but simply for the purposes of allowing gpg to check signatures.) Since we just need to read Git objects, after all, another option would be to avoid libgit2 and read them ourselves, which wouldn’t be hard (I’d expect ~500 lines of code), would avoid the dependency, and be more robust (no C!). However, ‘guix pull’ can make good use of libgit2 to directly clone/pull in the future, so it makes sense to have libgit2 bindings. It Would Be Nice if the libgit2 bindings were maintained separately. We can start with just the features we need as (guix git), but if anyone wants to “externalize” it and improve it, that would be more than welcome! Thoughts? Thanks, Ludo’.