{"thread":{"id":"49025","subject":"abstracting commit signing/verify to support other signing schemes","startedAt":"2018-08-03T21:46:46Z","lastAt":"2018-08-08T23:14:44Z","messageCount":5,"participants":["Tacitus Aedifex","Jeff King","Randall S. Becker"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"354440","messageId":"20180803213834.GB7619@SDF.ORG","threadId":"49025","inReplyTo":null,"subject":"abstracting commit signing/verify to support other signing schemes","fromName":"Tacitus Aedifex","fromEmail":"aedifex@sdf.org","sentAt":"2018-08-03T21:38:34Z","receivedAt":"2018-08-03T21:46:46Z","isPatch":false,"sender":{"key":"aedifex@sdf.org","avatar":"https://gravatar.com/avatar/7d5361117c8a59b99af67c0282a2785183f7cee0f2a3294d8d3dcb7a6c00387d?d=mp&s=160"},"body":"I'm looking at the existing commit signing and verification\nintegration and it is all GPG specific. I'm interested in refactoring\nthe code to have a generic signing/verifying interface so that \"drivers\"\nfor other signing tools can be created and other signing tools can be\nused (e.g. OpenBSD signify).\n\nThe existing interface defined in gpg-interface.h is already fairly\ngeneric. It looks like the only things that would need to be fixed\nare the names of some members in the signature_check struct and the GPG\nspecific constants.\n\nI propose to rename the gpg-interface.h file to signature-interface.h.\nThere are several different ways to do the \"polymorphism\" needed to have\na base signature_check struct with a tool-specific part for storing the\ntool-specific data (e.g. gpg_output, gpg_status, result). I'm looking\nfor suggestions on the way this has been done in other places in the Git\ncode so I can do it the same way. My initial impulse it to have a union\nof tool-specific structs inside of the signature_check struct.\n\nThe plan for changing the signing behavior is to change the code looking\nfor commit.gpgsign in sequencer.c to instead look for commit.signtool.\nThe string value will define which signing tool to use. The default will\nbe null which is the equivilent to gpgsign=false. To get GPG\nsigning the user would set it to \"gpg\". To maintain backwards\ncompatibility, the code will continue to check for commit.gpgsign and\ntranslate that to commit.signtool=gpg and output a warning.\n\nI also think that it makes sense to move the user.signingkey to be\ngpg.signingkey since that only makes sense in the context of GPG.\n\nThe real trick here is how to handle signatures from different tools in\na given project. I think the answer is to store the value of\ncommit.signtool along with the signature blob associted with each signed\ncommit. That way the signature verification code can know which tool to\nuse to verify the signature. If a commit has a signture but no tool\nselector, the default will be to assume GPG to preserve backwards\ncompatibility.\n\nAny other thoughts and/or suggestions?\n\n//tæ\n"},{"id":"354443","messageId":"20180803220746.GA5404@sigill.intra.peff.net","threadId":"49025","inReplyTo":"20180803213834.GB7619@SDF.ORG","subject":"Re: abstracting commit signing/verify to support other signing schemes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-08-03T22:07:46Z","receivedAt":"2018-08-03T22:07:49Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Aug 03, 2018 at 09:38:34PM +0000, Tacitus Aedifex wrote:\n\n> I'm looking at the existing commit signing and verification\n> integration and it is all GPG specific. I'm interested in refactoring\n> the code to have a generic signing/verifying interface so that \"drivers\"\n> for other signing tools can be created and other signing tools can be\n> used (e.g. OpenBSD signify).\n> [...]\n> Any other thoughts and/or suggestions?\n\nThere's been some work on this lately. See this patch and the response\nthread:\n\n  https://public-inbox.org/git/20180409204129.43537-9-mastahyeti@gmail.com/\n\nOne of the main complaints there was that it was doing just enough to\nmake gpgsm work, and it was unclear if some of the abstractions would be\ninsufficient for something like signify.\n\nThe more recent work focused on just doing the minimum to provide\ngpg/gpgsm variants:\n\n  https://public-inbox.org/git/cover.1531831244.git.henning.schild@siemens.com/\n\nThat replaces the earlier patch series, and is currently merged to the\n'next' branch and is on track to get merged to 'master' before Git 2.19\nis released.\n\nOne of the downsides there is that if we eventually move to a generic\nsigning-tool config, we'd have to support two layers of historical\nabstraction (the original \"gpg.program\" config, and the new\n\"gpg.<tool>.*\" config).\n\nSo _if_ we knew what it would take to support signify, we could\npotentially adjust what's going into 2.19 in order to skip straight to\nthe more generic interface. But on the OTOH, it may not be worth\nrushing, and there is already a vague plan of how the gpg.<tool>.*\nconfig would interact with a more generic config.\n\nAnyway. Hopefully that gives you a sense of what the current state is,\nand that work should answer the questions you asked about how to\napproach the code changes.\n\n-Peff\n"},{"id":"354444","messageId":"000901d42b76$d071a0f0$7154e2d0$@nexbridge.com","threadId":"49025","inReplyTo":"20180803213834.GB7619@SDF.ORG","subject":"RE: abstracting commit signing/verify to support other signing schemes","fromName":"Randall S. Becker","fromEmail":"rsbecker@nexbridge.com","sentAt":"2018-08-03T22:10:34Z","receivedAt":"2018-08-03T22:10:49Z","isPatch":false,"sender":{"key":"randall.becker@nexbridge.ca","avatar":"https://avatars.githubusercontent.com/u/28956764?v=4"},"body":"On August 3, 2018 5:39 PM, Tacitus Aedifex wrote:\n> I'm looking at the existing commit signing and verification integration and it is\n> all GPG specific. I'm interested in refactoring the code to have a generic\n> signing/verifying interface so that \"drivers\"\n> for other signing tools can be created and other signing tools can be used\n> (e.g. OpenBSD signify).\n> \n> The existing interface defined in gpg-interface.h is already fairly generic. It\n> looks like the only things that would need to be fixed are the names of some\n> members in the signature_check struct and the GPG specific constants.\n> \n> I propose to rename the gpg-interface.h file to signature-interface.h.\n> There are several different ways to do the \"polymorphism\" needed to have a\n> base signature_check struct with a tool-specific part for storing the tool-\n> specific data (e.g. gpg_output, gpg_status, result). I'm looking for\n> suggestions on the way this has been done in other places in the Git code so I\n> can do it the same way. My initial impulse it to have a union of tool-specific\n> structs inside of the signature_check struct.\n> \n> The plan for changing the signing behavior is to change the code looking for\n> commit.gpgsign in sequencer.c to instead look for commit.signtool.\n> The string value will define which signing tool to use. The default will be null\n> which is the equivilent to gpgsign=false. To get GPG signing the user would\n> set it to \"gpg\". To maintain backwards compatibility, the code will continue to\n> check for commit.gpgsign and translate that to commit.signtool=gpg and\n> output a warning.\n> \n> I also think that it makes sense to move the user.signingkey to be\n> gpg.signingkey since that only makes sense in the context of GPG.\n> \n> The real trick here is how to handle signatures from different tools in a given\n> project. I think the answer is to store the value of commit.signtool along with\n> the signature blob associted with each signed commit. That way the\n> signature verification code can know which tool to use to verify the\n> signature. If a commit has a signture but no tool selector, the default will be\n> to assume GPG to preserve backwards compatibility.\n\nIf I may suggest something a little off the wall... the abstraction needs to go beyond just the signing tool, but the whole signing infrastructure. I would like to see something along the lines of introducing a signing authority into the mix, so that not only the tool of signing is abstracted, but also the interface to who, if anyone, is responsible for signing. If I had my dream, it would be that one (or more) signing authorities would have potentially overlapping responsibilities for signing parts of the tree either on demand or by requirement.\n\nSo when a commit occurs, at least on master, or other designated branches, it may be the repository requires a signature from a particular authority, regardless of whether the committer has requested one. And there may be more than one authority or notary involved. Or, the repository could accept the signature of the committer as abstracted.\n\nWhere I'm going is that I would like to see a tighter integration with block-chain concepts in git. My customer base has very tight requirements for this type of software certification. Signatures, GPG or other, may only go so far. I am even considering whether particular parts of the tree are even visible (remember the Islands of Sparceness discussion?).\n\nI expect to be able to contribute more to this conversation in a few months (current $NDA prohibition), if this goes anywhere.\n\nMy feature time machine window doesn't see this any time soon, if ever, but one never knows. I have my delusional hopes. 😉\n\nPlease take this as simply a suggestion for the long-term.\n\nCheers,\nRandall\n\n-- Brief whoami:\n NonStop developer since approximately 211288444200000000\n UNIX developer since approximately 421664400\n-- In my real life, I talk too much.\n\n\n\n"},{"id":"354683","messageId":"20180806202424.GA2315@SDF.ORG","threadId":"49025","inReplyTo":"20180803220746.GA5404@sigill.intra.peff.net","subject":"Re: abstracting commit signing/verify to support other signing schemes","fromName":"Tacitus Aedifex","fromEmail":"aedifex@sdf.org","sentAt":"2018-08-06T20:24:25Z","receivedAt":"2018-08-06T20:24:40Z","isPatch":false,"sender":{"key":"aedifex@sdf.org","avatar":"https://gravatar.com/avatar/7d5361117c8a59b99af67c0282a2785183f7cee0f2a3294d8d3dcb7a6c00387d?d=mp&s=160"},"body":"On Fri, Aug 03, 2018 at 06:07:46PM -0400, Jeff King wrote:\n>There's been some work on this lately. See this patch and the response\n>thread:\n>\n>  https://public-inbox.org/git/20180409204129.43537-9-mastahyeti@gmail.com/\n>\n>The more recent work focused on just doing the minimum to provide\n>gpg/gpgsm variants:\n>\n>  https://public-inbox.org/git/cover.1531831244.git.henning.schild@siemens.com/\n>\n>That replaces the earlier patch series, and is currently merged to the\n>'next' branch and is on track to get merged to 'master' before Git 2.19\n>is released.\n\nthank you for setting the context. it looks like both patch sets are going in \nthe same direction that i suggested, at least with the config variables.  \npersonally, i prefer the 'signingtool.<tool>' approach in the older patch set \nover the 'gpg.<tool>' approach in the newer patch set since my goal is to get \naway from assuming gpg.\n\nthe older patch set suggested the idea of using PEM strings to match up the \nsignature payload with a certain signing tool.  i can't tell if they mean the \n'pre-ecapsulation boundary' (e.g. '-----BEGIN FOO-----') or if they mean the \nencapsulated headers; both as defined in RFC 1421 [0].\n\nthe newer patch set looks specifically at the pre-encapsulation boundary to \nswitch behaviors. that works assuming that the signing tools all understand \nPEM. in the case of signify, it doesn't, so the driver code in git will have to \ntranslate to/from PEM.\n\ni suggest that we switch to a standard format for all signatures that is \nsimilar to the commit message format with colon ':' separated fields followed \nby a payload.  the colon separated fields would specify the signing tool used \nto generate the signature and the tool specific data followed by the signature \nblob like so:\n\n  signing-tool: gpg\n  gpg-keyid: 0123456789ABCDEF\n  \n  -----BEGIN PGP SIGNATURE-----\n  <base64 encoded signature>\n  -----END PGP SIGNATURE-----\n\nby adopting this format, git will be fully abstracted from the underlying \nsigning tool and the user can specify multiple signing tools in their config \nand git will be able to map the signature to the tool when verifying (e.g. git \nlog --show-signature).\n\na signify signature would look something like this:\n\n  signing-tool: signify\n  signify-public-key: <base64 encoded public key>\n  \n  <base64 encoded signature>\n\ni hope we adopt a more generic approach like this.\n\n>One of the downsides there is that if we eventually move to a generic\n>signing-tool config, we'd have to support two layers of historical\n>abstraction (the original \"gpg.program\" config, and the new\n>\"gpg.<tool>.*\" config).\n\ni like the idea of aliasing all of the old config variables to their equivilent \nand outputting a deprecation warning when we get plan on removing the aliases \naltogether in the future.\n\n>So _if_ we knew what it would take to support signify, we could\n>potentially adjust what's going into 2.19 in order to skip straight to\n>the more generic interface. But on the OTOH, it may not be worth\n>rushing, and there is already a vague plan of how the gpg.<tool>.*\n>config would interact with a more generic config.\n\nthere's no rush, but i would prefer that the newer patch set get changed to use \nthe more generic 'signingtool.<tool>.*' instead of 'gpg.<tool>.*'. if you all \nagree, i'll follow up with a patch to change that part of what is going into \n2.19.\n\nthen round two will be to experiment with a new, standard signature format that \ndoesn't assume anything about the underlying signing tool.\n\n//tæ\n\n[0] https://tools.ietf.org/html/rfc1421\n"},{"id":"354958","messageId":"20180808231440.GB21882@sigill.intra.peff.net","threadId":"49025","inReplyTo":"20180806202424.GA2315@SDF.ORG","subject":"Re: abstracting commit signing/verify to support other signing schemes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-08-08T23:14:41Z","receivedAt":"2018-08-08T23:14:44Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Aug 06, 2018 at 08:24:25PM +0000, Tacitus Aedifex wrote:\n\n> the older patch set suggested the idea of using PEM strings to match up the\n> signature payload with a certain signing tool.  i can't tell if they mean\n> the 'pre-ecapsulation boundary' (e.g. '-----BEGIN FOO-----') or if they mean\n> the encapsulated headers; both as defined in RFC 1421 [0].\n\nIt was the pre-encapsulation boundary (we didn't use that word, but it\nwas definitely the \"-----BEGIN\" line ;) ).\n\nAnd that was the sticking point: there was an open question of what\nsupport for something like signify would look like exactly, and what the\nmatching rules would need to be. My thought was to allow multiple\nmatching types, and \"PEM type\" (by which I meant that pre-encapsulation\nboundary) would be the first such type.\n\nBut that got punted on, since we didn't have a real-world example to\nlook at, and we really only cared about gpgsm in the near-term anyway.\nAnd that obviously does PEM. So the gpg.* tools all require PEM, but if\nwe add a generic signingtool config, it doesn't have to.\n\n> the newer patch set looks specifically at the pre-encapsulation boundary to\n> switch behaviors. that works assuming that the signing tools all understand\n> PEM. in the case of signify, it doesn't, so the driver code in git will have\n> to translate to/from PEM.\n\nRight. It might be fine to encapsulate it, though I prefer not inventing\nnew micro-formats if we can avoid it.\n\nThere actually _is_ an interesting micro-format already in Git, which is\nthat commit signatures (not tags) are held in the \"gpgsig\" header of the\ncommit. Which would be an awkward name for storing a non-gpg tool. We\nmay want to live with that for historical reasons, or we could switch to\na more generic name.\n\nThe actual PEM detection is for tags, where the signature is in the tag\nbody itself.\n\nIn either case, we could use some object header to indicate the\nsignature type (on the other hand, it could be possible to have multiple\nsignatures of different types).\n\n> i suggest that we switch to a standard format for all signatures that is\n> similar to the commit message format with colon ':' separated fields\n> followed by a payload.  the colon separated fields would specify the signing\n> tool used to generate the signature and the tool specific data followed by\n> the signature blob like so:\n> \n>  signing-tool: gpg\n>  gpg-keyid: 0123456789ABCDEF\n>  -----BEGIN PGP SIGNATURE-----\n>  <base64 encoded signature>\n>  -----END PGP SIGNATURE-----\n> \n> by adopting this format, git will be fully abstracted from the underlying\n> signing tool and the user can specify multiple signing tools in their config\n> and git will be able to map the signature to the tool when verifying (e.g.\n> git log --show-signature).\n\nOne problem with that for the signatures in tag bodies is that\n\"signing-tool: gpg\" looks like something a human might right (as opposed\nto the PEM boundary, which is a bit more obvious).\n\nIf we're going to make up a micro-format, it may be simpler to just have\nsomething PEM-like in the first place, and shove signify into that.\n\n> > So _if_ we knew what it would take to support signify, we could\n> > potentially adjust what's going into 2.19 in order to skip straight to\n> > the more generic interface. But on the OTOH, it may not be worth\n> > rushing, and there is already a vague plan of how the gpg.<tool>.*\n> > config would interact with a more generic config.\n> \n> there's no rush, but i would prefer that the newer patch set get changed to\n> use the more generic 'signingtool.<tool>.*' instead of 'gpg.<tool>.*'. if\n> you all agree, i'll follow up with a patch to change that part of what is\n> going into 2.19.\n\nI'm on the fence for that myself. The best way to get people to comment\nwould be to make a patch, and cc people involved in the earlier\ndiscussions.\n\n-Peff\n"}]}