{"thread":{"id":"41258","subject":"[RFC] tag-ref and tag object binding","startedAt":"2016-01-25T21:22:09Z","lastAt":"2016-01-28T21:09:02Z","messageCount":17,"participants":["Santiago Torres","Michael J Gruber","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"276736","messageId":"20160125212208.GB26169@LykOS","threadId":"41258","inReplyTo":null,"subject":"[RFC] tag-ref and tag object binding","fromName":"Santiago Torres","fromEmail":"santiago@nyu.edu","sentAt":"2016-01-25T21:22:09Z","receivedAt":"2016-01-25T21:22:09Z","isPatch":false,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"Hello everyone.\n\nI've done some further research on the security properties of git\nmetadata and I think I've identified something that might be worth\ndiscussing. In this case, The issue is related to the refs that point to\ngit tag objects. Specifically, the \"loose\" nature of tag refs might\npossibly trick people into installing the wrong revision (version?) of a\nfile.\n\nTo elaborate, the ref of a tag object can be moved around in the same\nway a branch can be moved around (either manually or by using git\ncommands). If someone with write access can modify where this ref points\nto, and points it to another valid tag (e.g., an older, vulnerable\nversion), then many tools that work under the assumption of static tags\nmight mistakenly install/pull the wrong reivision of source code. I've\nverified that this is possible to pull off in package managers such as\nPIP, rubygems, gradle(maven), as well as git submodules tracking tags.\n\nIn order to stay loyal to the way files in the .git directory are\nordered, I don't think that making the ref file (or packed refs) files\ndifferently is an option. However, I think that it could be possible to\nstore the \"origin ref\" in the git tag object, so tools can verify that\nthey are looking at the appropriate tag. There might also be a simpler\nsolution to this, and I would appreciate any feedback.\n\nWhat do you guys think?\n\nThanks!\nSantiago.\n"},{"id":"276771","messageId":"56A73DE6.5050201@drmicha.warpmail.net","threadId":"41258","inReplyTo":"20160125212208.GB26169@LykOS","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-01-26T09:35:34Z","receivedAt":"2016-01-26T09:35:34Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Santiago Torres venit, vidit, dixit 25.01.2016 22:22:\n> Hello everyone.\n> \n> I've done some further research on the security properties of git\n> metadata and I think I've identified something that might be worth\n> discussing. In this case, The issue is related to the refs that point to\n> git tag objects. Specifically, the \"loose\" nature of tag refs might\n> possibly trick people into installing the wrong revision (version?) of a\n> file.\n> \n> To elaborate, the ref of a tag object can be moved around in the same\n> way a branch can be moved around (either manually or by using git\n> commands). If someone with write access can modify where this ref points\n> to, and points it to another valid tag (e.g., an older, vulnerable\n> version), then many tools that work under the assumption of static tags\n> might mistakenly install/pull the wrong reivision of source code. I've\n> verified that this is possible to pull off in package managers such as\n> PIP, rubygems, gradle(maven), as well as git submodules tracking tags.\n> \n> In order to stay loyal to the way files in the .git directory are\n> ordered, I don't think that making the ref file (or packed refs) files\n> differently is an option. However, I think that it could be possible to\n> store the \"origin ref\" in the git tag object, so tools can verify that\n> they are looking at the appropriate tag. There might also be a simpler\n> solution to this, and I would appreciate any feedback.\n> \n> What do you guys think?\n> \n> Thanks!\n> Santiago.\n\nIf you cannot trust those with write access to a repo that you are\npulling and installing from you might want to re-check where you are\npulling or installing from ;)\n\nIn fact, just like you shouldn't blindly download and install a tarball\n(but check its signature) you shouldn't blindly pull and install from a\nrepo.\n\nYour best bet is checking the signature of signed tags. Now, if you're\nworried about someone maliciously pointing you to the wrong, correctly\nsigned tag then you should verify that the tag object contains the tag\n\"name\" that you expect (for example by using \"git verify-tag -v\" or \"git\ncat-file -p\"), since that is part of the signed content.\n\nMichael\n"},{"id":"276818","messageId":"20160126152941.GA31951@LykOS","threadId":"41258","inReplyTo":"56A73DE6.5050201@drmicha.warpmail.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Santiago Torres","fromEmail":"santiago@nyu.edu","sentAt":"2016-01-26T15:29:42Z","receivedAt":"2016-01-26T15:29:42Z","isPatch":false,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"On Tue, Jan 26, 2016 at 10:35:34AM +0100, Michael J Gruber wrote:\n> Santiago Torres venit, vidit, dixit 25.01.2016 22:22:\n> > Hello everyone.\n> > \n> > I've done some further research on the security properties of git\n> > metadata and I think I've identified something that might be worth\n> > discussing. In this case, The issue is related to the refs that point to\n> > git tag objects. Specifically, the \"loose\" nature of tag refs might\n> > possibly trick people into installing the wrong revision (version?) of a\n> > file.\n> > \n> > To elaborate, the ref of a tag object can be moved around in the same\n> > way a branch can be moved around (either manually or by using git\n> > commands). If someone with write access can modify where this ref points\n> > to, and points it to another valid tag (e.g., an older, vulnerable\n> > version), then many tools that work under the assumption of static tags\n> > might mistakenly install/pull the wrong reivision of source code. I've\n> > verified that this is possible to pull off in package managers such as\n> > PIP, rubygems, gradle(maven), as well as git submodules tracking tags.\n> > \n> > In order to stay loyal to the way files in the .git directory are\n> > ordered, I don't think that making the ref file (or packed refs) files\n> > differently is an option. However, I think that it could be possible to\n> > store the \"origin ref\" in the git tag object, so tools can verify that\n> > they are looking at the appropriate tag. There might also be a simpler\n> > solution to this, and I would appreciate any feedback.\n> > \n> > What do you guys think?\n> > \n> > Thanks!\n> > Santiago.\n> \n> If you cannot trust those with write access to a repo that you are\n> pulling and installing from you might want to re-check where you are\n> pulling or installing from ;)\n\nYeah, I see your point, but mechanisms to ensure the server's origin can\nbe bypassed (e.g., a MITM). I don't think it would hurt to ensure the\nsource pointed to is the source itself. The tag signature can help us do\nthis.\n\n> \n> In fact, just like you shouldn't blindly download and install a tarball\n> (but check its signature) you shouldn't blindly pull and install from a\n> repo.\n\nYep. As a matter of fact, many of these package managers can install\nfrom a specific commit, which should be safer. However, I do think that\npointing to a tag is more \"usable\" given that they are human-readable.\nAlso, tags are usually meant to point to releases, so it follows its\ndesign pattern doesn't it?. I think it wouldn't be a bad idea to provide\na hard-binding between tag-refs and tags themselves.\n\n> \n> Your best bet is checking the signature of signed tags. Now, if you're\n> worried about someone maliciously pointing you to the wrong, correctly\n> signed tag then you should verify that the tag object contains the tag\n> \"name\" that you expect (for example by using \"git verify-tag -v\" or \"git\n> cat-file -p\"), since that is part of the signed content.\n\nYep, this is my intuition behind my proposal. While someone can manually\ninspect a tag (git tag -v [ref]) to ensure he's getting the correct one,\nthere's no mechanism to ensure that the ref is pointing to the intended\ntag. I do believe that package managers and git submodules could check\nwhether the ref is pointing to the right tag with a small change in the\ntag header. Although it would be up to each tool to implement this\ncheck.\n\nI don't think that an addition like this would get in the way of any\nexisting git workflow, and should be backwards-compatible right?\n\nThanks,\n-Santiago.\n"},{"id":"276831","messageId":"20160126202651.GA1090@sigill.intra.peff.net","threadId":"41258","inReplyTo":"20160126152941.GA31951@LykOS","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-01-26T20:26:51Z","receivedAt":"2016-01-26T20:26:51Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:\n\n> > If you cannot trust those with write access to a repo that you are\n> > pulling and installing from you might want to re-check where you are\n> > pulling or installing from ;)\n> \n> Yeah, I see your point, but mechanisms to ensure the server's origin can\n> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the\n> source pointed to is the source itself. The tag signature can help us do\n> this.\n\nRight. I think the more interesting use case here is \"I trust the\nupstream repository owner, but I do not trust their hosting site of\nchoice.\"\n\n> > Your best bet is checking the signature of signed tags. Now, if you're\n> > worried about someone maliciously pointing you to the wrong, correctly\n> > signed tag then you should verify that the tag object contains the tag\n> > \"name\" that you expect (for example by using \"git verify-tag -v\" or \"git\n> > cat-file -p\"), since that is part of the signed content.\n> \n> Yep, this is my intuition behind my proposal. While someone can manually\n> inspect a tag (git tag -v [ref]) to ensure he's getting the correct one,\n> there's no mechanism to ensure that the ref is pointing to the intended\n> tag. I do believe that package managers and git submodules could check\n> whether the ref is pointing to the right tag with a small change in the\n> tag header. Although it would be up to each tool to implement this\n> check.\n> \n> I don't think that an addition like this would get in the way of any\n> existing git workflow, and should be backwards-compatible right?\n\nDoesn't this already exist?\n\n  $ git cat-file tag v2.0.0\n  object e156455ea49124c140a67623f22a393db62d5d98\n  type commit\n  tag v2.0.0\n  tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700\n\n  Git 2.0\n  -----BEGIN PGP SIGNATURE-----\n  [...]\n  -----END PGP SIGNATURE-----\n\nTag objects already have a \"tag\" header, which is part of the signed\ncontent. If you use \"git verify-tag -v\", you can check both that the\nsignature is valid and that the tag is the one you are expecting.\n\nOf course, \"verify-tag\" could do this for you if you give it a refname,\ntoo, but I think that may be the tip of the iceberg in terms of\nautomatic verification. In particular, verify-tag knows it was signed by\n_somebody_, but it doesn't know what the signing policy is. As a human,\n_I_ know that Junio is the right person to be signing the release tag,\nbut no tool does.\n\nGit pretty much punts on all of these issues and assumes either a human\nor a smarter tool is looking at the verification output. But I don't\nthink it would hurt to build in some features to let git automatically\ncheck some things, if only to avoid callers duplicating work to\nimplement the checks themselves.\n\n-Peff\n"},{"id":"276833","messageId":"xmqqwpqwavtf.fsf@gitster.mtv.corp.google.com","threadId":"41258","inReplyTo":"20160126202651.GA1090@sigill.intra.peff.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-26T21:13:16Z","receivedAt":"2016-01-26T21:13:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:\n>\n>> > If you cannot trust those with write access to a repo that you are\n>> > pulling and installing from you might want to re-check where you are\n>> > pulling or installing from ;)\n>> \n>> Yeah, I see your point, but mechanisms to ensure the server's origin can\n>> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the\n>> source pointed to is the source itself. The tag signature can help us do\n>> this.\n>\n> Right. I think the more interesting use case here is \"I trust the\n> upstream repository owner, but I do not trust their hosting site of\n> choice.\"\n\nYup, and push-certificate is there to help with that issue.\n"},{"id":"276835","messageId":"20160126214449.GA5966@LykOS.WiFi.IPv4InfoBelow","threadId":"41258","inReplyTo":"20160126202651.GA1090@sigill.intra.peff.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Santiago Torres","fromEmail":"santiago@nyu.edu","sentAt":"2016-01-26T21:44:51Z","receivedAt":"2016-01-26T21:44:51Z","isPatch":false,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"On Tue, Jan 26, 2016 at 03:26:51PM -0500, Jeff King wrote:\n> On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:\n> \n> > > If you cannot trust those with write access to a repo that you are\n> > > pulling and installing from you might want to re-check where you are\n> > > pulling or installing from ;)\n> > \n> > Yeah, I see your point, but mechanisms to ensure the server's origin can\n> > be bypassed (e.g., a MITM). I don't think it would hurt to ensure the\n> > source pointed to is the source itself. The tag signature can help us do\n> > this.\n> \n> Right. I think the more interesting use case here is \"I trust the\n> upstream repository owner, but I do not trust their hosting site of\n> choice.\"\n\nYes, I think this is another possible scenario. Thanks for pointing it\nout.\n\n> \n> > > Your best bet is checking the signature of signed tags. Now, if you're\n> > > worried about someone maliciously pointing you to the wrong, correctly\n> > > signed tag then you should verify that the tag object contains the tag\n> > > \"name\" that you expect (for example by using \"git verify-tag -v\" or \"git\n> > > cat-file -p\"), since that is part of the signed content.\n> > \n> > Yep, this is my intuition behind my proposal. While someone can manually\n> > inspect a tag (git tag -v [ref]) to ensure he's getting the correct one,\n> > there's no mechanism to ensure that the ref is pointing to the intended\n> > tag. I do believe that package managers and git submodules could check\n> > whether the ref is pointing to the right tag with a small change in the\n> > tag header. Although it would be up to each tool to implement this\n> > check.\n> > \n> > I don't think that an addition like this would get in the way of any\n> > existing git workflow, and should be backwards-compatible right?\n> \n> Doesn't this already exist?\n> \n>   $ git cat-file tag v2.0.0\n>   object e156455ea49124c140a67623f22a393db62d5d98\n>   type commit\n>   tag v2.0.0\n>   tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700\n> \n>   Git 2.0\n>   -----BEGIN PGP SIGNATURE-----\n>   [...]\n>   -----END PGP SIGNATURE-----\n> \n> Tag objects already have a \"tag\" header, which is part of the signed\n> content. If you use \"git verify-tag -v\", you can check both that the\n> signature is valid and that the tag is the one you are expecting.\n\nOh, I inspected the tag object with cat-file, but I assumed this was\nbeing inserted by the command itself (by \"pretty printing\"). This is\nexactly what I was thinking.\n\n> \n> Of course, \"verify-tag\" could do this for you if you give it a refname,\n> too, but I think that may be the tip of the iceberg in terms of\n> automatic verification. \n\nYes, I think it could be a good first step though (maybe returning non-0\nif the tag header could help in this case).\n\nIf this header exists, I think that package managers (and git\nsubmodules) should use it to verify this metadata attacks don't take\nplace; it sounds rather simple.\n\n> In particular, verify-tag knows it was signed by\n> _somebody_, but it doesn't know what the signing policy is. As a human,\n> _I_ know that Junio is the right person to be signing the release tag,\n> but no tool does.\n\nYes, shipping a keychain might be helpful, I know the folks at I2P[1] do\nthat in their monotone repository. Maybe something similar could be an\nextension to git? (using hooks, possibly?)\n\n> \n> Git pretty much punts on all of these issues and assumes either a human\n> or a smarter tool is looking at the verification output. \n\nYeah, I agree. This works pretty well in some workflows (e.g., the one\nin this very ML), but I have the feeling this is not the trend that\nnewer users of the tool are adopting.\n\n> But I don't think it would hurt to build in some features to let git\n> automatically check some things, if only to avoid callers duplicating\n> work to implement the checks themselves.\n\nYeah, I think this check (and maybe others) could be quite simple to\nintegrate and lessen the workload on the git user. Inspecting each git\ntag after recursively cloning might mitigate an attack like this, but it\nsounds burdensome.\n\nThanks!\n-Santiago.\n\n[1]\nhttps://geti2p.net/en/get-involved/guides/monotone#setting-up-trust-evaluation-hooks\n"},{"id":"276842","messageId":"xmqq1t94arkx.fsf@gitster.mtv.corp.google.com","threadId":"41258","inReplyTo":"20160126202651.GA1090@sigill.intra.peff.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-26T22:44:46Z","receivedAt":"2016-01-26T22:44:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n>> I don't think that an addition like this would get in the way of any\n>> existing git workflow, and should be backwards-compatible right?\n>\n> Doesn't this already exist?\n>\n>   $ git cat-file tag v2.0.0\n>   object e156455ea49124c140a67623f22a393db62d5d98\n>   type commit\n>   tag v2.0.0\n>   tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700\n>\n>   Git 2.0\n>   -----BEGIN PGP SIGNATURE-----\n>   [...]\n>   -----END PGP SIGNATURE-----\n>\n> Tag objects already have a \"tag\" header, which is part of the signed\n> content. If you use \"git verify-tag -v\", you can check both that the\n> signature is valid and that the tag is the one you are expecting.\n\nAnother thing worth mentioning is that \"fsck\" does not insist that\nrefs/tags/$NAME must have a \"tag\" line that says \"tag $NAME\", and\nthat is a very deliberate design decision.  A project may want to\nallow multiple people tag the same commit with the same tagname and\npublish all of them in the same ref hierarchy.  For example, while I\nam away, Peff may make an emergency maintenance release and tag it\nlike so:\n\n    $ git tag -s -m 'Git v2.7.1' v2.7.1 master\n    $ git push $there tags/v2.7.1:tags/peff/v2.7.1 master\n\nand announce to the list that he has cut a release, and published\nhis signed tag as peff/v2.7.1 in the public repository.  While\neverybody in the project trusts Peff as much as they trust me, I\nwould still want to sign the same commit myself, endorsing what Peff\ndid for the project, when I come back, by doing something like:\n\n    $ git tag -s -m 'Git v2.7.1' v2.7.1 peff/v2.7.1^0\n    $ git push $there v2.7.1\n\nIn fact, I think \"git describe\" uses the name recorded in the\nclosest tag, not the refname such a tag is found at, when giveing a\nname to the commit.  E.g.\n\n    $ git tag foo v2.7.0\n    $ git tag -d v2.7.0\n    $ git describe master\n    warning: tag 'v2.7.0' is really 'foo' here\n    v2.7.0-170-ge572fef\n"},{"id":"276866","messageId":"56A87056.2010309@drmicha.warpmail.net","threadId":"41258","inReplyTo":"20160126202651.GA1090@sigill.intra.peff.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-01-27T07:23:02Z","receivedAt":"2016-01-27T07:23:02Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 26.01.2016 21:26:\n> On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:\n> \n>>> If you cannot trust those with write access to a repo that you are\n>>> pulling and installing from you might want to re-check where you are\n>>> pulling or installing from ;)\n>>\n>> Yeah, I see your point, but mechanisms to ensure the server's origin can\n>> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the\n>> source pointed to is the source itself. The tag signature can help us do\n>> this.\n> \n> Right. I think the more interesting use case here is \"I trust the\n> upstream repository owner, but I do not trust their hosting site of\n> choice.\"\n> \n>>> Your best bet is checking the signature of signed tags. Now, if you're\n>>> worried about someone maliciously pointing you to the wrong, correctly\n>>> signed tag then you should verify that the tag object contains the tag\n>>> \"name\" that you expect (for example by using \"git verify-tag -v\" or \"git\n>>> cat-file -p\"), since that is part of the signed content.\n>>\n>> Yep, this is my intuition behind my proposal. While someone can manually\n>> inspect a tag (git tag -v [ref]) to ensure he's getting the correct one,\n>> there's no mechanism to ensure that the ref is pointing to the intended\n>> tag. I do believe that package managers and git submodules could check\n>> whether the ref is pointing to the right tag with a small change in the\n>> tag header. Although it would be up to each tool to implement this\n>> check.\n>>\n>> I don't think that an addition like this would get in the way of any\n>> existing git workflow, and should be backwards-compatible right?\n> \n> Doesn't this already exist?\n> \n>   $ git cat-file tag v2.0.0\n>   object e156455ea49124c140a67623f22a393db62d5d98\n>   type commit\n>   tag v2.0.0\n>   tagger Junio C Hamano <gitster@pobox.com> 1401300269 -0700\n> \n>   Git 2.0\n>   -----BEGIN PGP SIGNATURE-----\n>   [...]\n>   -----END PGP SIGNATURE-----\n> \n> Tag objects already have a \"tag\" header, which is part of the signed\n> content. If you use \"git verify-tag -v\", you can check both that the\n> signature is valid and that the tag is the one you are expecting.\n\nYes, that's what I described in my last paragraph, using the term\n(embedded) tag \"name\" which is technically wrong (it's not the tag\nobject's name, which would be a sha1) but the natural term for users.\n\n> Of course, \"verify-tag\" could do this for you if you give it a refname,\n> too, but I think that may be the tip of the iceberg in terms of\n> automatic verification. In particular, verify-tag knows it was signed by\n> _somebody_, but it doesn't know what the signing policy is. As a human,\n> _I_ know that Junio is the right person to be signing the release tag,\n> but no tool does.\n> \n> Git pretty much punts on all of these issues and assumes either a human\n> or a smarter tool is looking at the verification output. But I don't\n> think it would hurt to build in some features to let git automatically\n> check some things, if only to avoid callers duplicating work to\n> implement the checks themselves.\n\nThat is really a can of worms for several reasons:\n\n- Do you fetch tags into refs/tags/ or refs/tags/upstream/ or wherever,\nand which part of the tag refname should we check for?\n\nWe can DWIM that to the last part after / and allow \"--tagname\" to\noverride, of course.\n\n- By all means, we need to avoid a false sense of security. \"GOOD\nSIGNATURE\" in gpg terms is bad enough with the usual trust model when\nusers don't check who actually made that signature.\n\nIf you don't *really* check the signature then anyone can shove a signed\ntag object under your nose with the *expected tag header* (tag \"name\")\nso that there is no gain at all, unless you envison a scenario where Man\nI. T. Middle can mess with refs but not objects.\n\nSo, for those who shy away from for-each-ref and such, we may add the\nheader check to verify-tag, with a big warning about the marginal gain\nin security (or the requirements for an actual gain).\n\nMichael\n"},{"id":"276868","messageId":"20160127073357.GA7066@sigill.intra.peff.net","threadId":"41258","inReplyTo":"56A87056.2010309@drmicha.warpmail.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-01-27T07:33:58Z","receivedAt":"2016-01-27T07:33:58Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 27, 2016 at 08:23:02AM +0100, Michael J Gruber wrote:\n\n> > Tag objects already have a \"tag\" header, which is part of the signed\n> > content. If you use \"git verify-tag -v\", you can check both that the\n> > signature is valid and that the tag is the one you are expecting.\n> \n> Yes, that's what I described in my last paragraph, using the term\n> (embedded) tag \"name\" which is technically wrong (it's not the tag\n> object's name, which would be a sha1) but the natural term for users.\n\nIndeed. I should have read further back in the quoting. :)\n\n> > Git pretty much punts on all of these issues and assumes either a human\n> > or a smarter tool is looking at the verification output. But I don't\n> > think it would hurt to build in some features to let git automatically\n> > check some things, if only to avoid callers duplicating work to\n> > implement the checks themselves.\n> \n> That is really a can of worms for several reasons:\n> [...]\n> So, for those who shy away from for-each-ref and such, we may add the\n> header check to verify-tag, with a big warning about the marginal gain\n> in security (or the requirements for an actual gain).\n\nYeah, definitely. My thinking was that `verify-tag` could learn a series\nof optional consistency checks, enabled by command line options, and\nverifying programs (or humans) could turn them on to avoid having to\nreplicate them manually. So something like:\n\n  git verify-tag \\\n    --verify-tagger-matches-key \\\n    --verify-tag-matches-ref \\ # or --verify-tag-matches=v2.0.0\n    v2.0.0\n\nor to implement more specific policy, maybe an option to check for a\n_specific_ tagger, either by email (as provided by gpg) or even key-id.\n\nThose are all things that are not _too_ hard to do if you're willing to\nparse gpg or git output, but we could make life easier for our callers.\nAnd hopefully by asking for specific, concrete checks, it doesn't\nintroduce a false sense of security. I.e., we're not making a foolproof\ntool; we're making building blocks that one could use for a more\nfoolproof tool.\n\n-Peff\n"},{"id":"276869","messageId":"56A87764.9070101@drmicha.warpmail.net","threadId":"41258","inReplyTo":"20160127073357.GA7066@sigill.intra.peff.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-01-27T07:53:08Z","receivedAt":"2016-01-27T07:53:08Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 27.01.2016 08:33:\n> On Wed, Jan 27, 2016 at 08:23:02AM +0100, Michael J Gruber wrote:\n> \n>>> Tag objects already have a \"tag\" header, which is part of the signed\n>>> content. If you use \"git verify-tag -v\", you can check both that the\n>>> signature is valid and that the tag is the one you are expecting.\n>>\n>> Yes, that's what I described in my last paragraph, using the term\n>> (embedded) tag \"name\" which is technically wrong (it's not the tag\n>> object's name, which would be a sha1) but the natural term for users.\n> \n> Indeed. I should have read further back in the quoting. :)\n> \n>>> Git pretty much punts on all of these issues and assumes either a human\n>>> or a smarter tool is looking at the verification output. But I don't\n>>> think it would hurt to build in some features to let git automatically\n>>> check some things, if only to avoid callers duplicating work to\n>>> implement the checks themselves.\n>>\n>> That is really a can of worms for several reasons:\n>> [...]\n>> So, for those who shy away from for-each-ref and such, we may add the\n>> header check to verify-tag, with a big warning about the marginal gain\n>> in security (or the requirements for an actual gain).\n> \n> Yeah, definitely. My thinking was that `verify-tag` could learn a series\n> of optional consistency checks, enabled by command line options, and\n> verifying programs (or humans) could turn them on to avoid having to\n> replicate them manually. So something like:\n> \n>   git verify-tag \\\n>     --verify-tagger-matches-key \\\n>     --verify-tag-matches-ref \\ # or --verify-tag-matches=v2.0.0\n>     v2.0.0\n> \n> or to implement more specific policy, maybe an option to check for a\n> _specific_ tagger, either by email (as provided by gpg) or even key-id.\n> \n> Those are all things that are not _too_ hard to do if you're willing to\n> parse gpg or git output, but we could make life easier for our callers.\n> And hopefully by asking for specific, concrete checks, it doesn't\n> introduce a false sense of security. I.e., we're not making a foolproof\n> tool; we're making building blocks that one could use for a more\n> foolproof tool.\n\nOK, let's make a tool that helps fooling as well as proofing :)\n\nI'll look into the tag header check. Maybe \"--check-tagname\"? \"check\"\nseems to imply less than \"verify\".\n\nAs for the gpg related stuff: We provide the full diagnostic output from\ngpg on request. But I think a mismatch between the signing key's uid and\nthe taggers' name/email is more common than not, and on the other hand a\nsignature by a key identified by its uid is meaningless unless you keep\nyour keyring tidy... We could punt on that and let users identify the\nkey by any means that gpg allows, of course, and check that the\nsignature comes from whatever \"gpg --list-key <userspecified>\" gives as\nlong as it's unique.\n\nBut maybe I'm biased by my zoo of uids/emails addresses/full name\nspellings... and general paranoia regarding the term \"verify\" ;)\n\nMichael\n"},{"id":"276871","messageId":"20160127080901.GA7651@sigill.intra.peff.net","threadId":"41258","inReplyTo":"56A87764.9070101@drmicha.warpmail.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-01-27T08:09:02Z","receivedAt":"2016-01-27T08:09:02Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 27, 2016 at 08:53:08AM +0100, Michael J Gruber wrote:\n\n> > Yeah, definitely. My thinking was that `verify-tag` could learn a series\n> > of optional consistency checks, enabled by command line options, and\n> > verifying programs (or humans) could turn them on to avoid having to\n> > replicate them manually. So something like:\n> > \n> >   git verify-tag \\\n> >     --verify-tagger-matches-key \\\n> >     --verify-tag-matches-ref \\ # or --verify-tag-matches=v2.0.0\n> >     v2.0.0\n> > \n> > or to implement more specific policy, maybe an option to check for a\n> > _specific_ tagger, either by email (as provided by gpg) or even key-id.\n> > \n> > Those are all things that are not _too_ hard to do if you're willing to\n> > parse gpg or git output, but we could make life easier for our callers.\n> > And hopefully by asking for specific, concrete checks, it doesn't\n> > introduce a false sense of security. I.e., we're not making a foolproof\n> > tool; we're making building blocks that one could use for a more\n> > foolproof tool.\n> \n> OK, let's make a tool that helps fooling as well as proofing :)\n> \n> I'll look into the tag header check. Maybe \"--check-tagname\"? \"check\"\n> seems to imply less than \"verify\".\n\nYeah, I think that is fine (I actually wrote --check originally; I'm not\nquite sure why I decided to change it).\n\n> As for the gpg related stuff: We provide the full diagnostic output from\n> gpg on request. But I think a mismatch between the signing key's uid and\n> the taggers' name/email is more common than not,\n\nIs it? I'd think if you are using that name with a signed tag, you would\nbother to issue (and get people to sign) the matching uid. Certainly it\nis the case for git and linux signatures, but I admit that it a pretty\nsmall sampling size.\n\nThe bigger issue is that gpg seems to give us only _one_ uid, when there\nmay be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a\nsub-key that has several uids associated with it. The one that \"git\nverify-tag --raw\" shows from gpg is gitster@pobox.com, which is good,\nbut I think that's just because it happens to be the first uid. Or maybe\nthere is some gpg arcana going on that I don't know about.\n\n> and on the other hand a\n> signature by a key identified by its uid is meaningless unless you keep\n> your keyring tidy... We could punt on that and let users identify the\n> key by any means that gpg allows, of course, and check that the\n> signature comes from whatever \"gpg --list-key <userspecified>\" gives as\n> long as it's unique.\n\nRight, I think it's an open question whether people actually participate\nin the web of trust. I don't have a good signature path to Junio's key,\nbut I happen to know what it is based on past interaction.\n\nBut then, I also do not really verify tags. Why would I? I routinely\nfetch and run \"make\" on the result, and there is no cryptographic\nprotection there at all. Verifying tag signatures after a release seems\nall but pointless. :)\n\nI think for any of this to be useful, it has to be part of some tool\nthat is very opinionated on policy. E.g., imagine a post-fetch hook that\nvalidated that each incoming commit was signed, and that the signer was\npart of a whitelisted group of keys that you \"somehow\" got hold of\nout-of-band for your project. That is not that useful for an open-source\nproject, but I could see the appeal for a proprietary development\nenvironment.\n\n-Peff\n"},{"id":"276877","messageId":"56A88A69.6030503@drmicha.warpmail.net","threadId":"41258","inReplyTo":"20160127080901.GA7651@sigill.intra.peff.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-01-27T09:14:17Z","receivedAt":"2016-01-27T09:14:17Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 27.01.2016 09:09:\n> On Wed, Jan 27, 2016 at 08:53:08AM +0100, Michael J Gruber wrote:\n> \n>>> Yeah, definitely. My thinking was that `verify-tag` could learn a series\n>>> of optional consistency checks, enabled by command line options, and\n>>> verifying programs (or humans) could turn them on to avoid having to\n>>> replicate them manually. So something like:\n>>>\n>>>   git verify-tag \\\n>>>     --verify-tagger-matches-key \\\n>>>     --verify-tag-matches-ref \\ # or --verify-tag-matches=v2.0.0\n>>>     v2.0.0\n>>>\n>>> or to implement more specific policy, maybe an option to check for a\n>>> _specific_ tagger, either by email (as provided by gpg) or even key-id.\n>>>\n>>> Those are all things that are not _too_ hard to do if you're willing to\n>>> parse gpg or git output, but we could make life easier for our callers.\n>>> And hopefully by asking for specific, concrete checks, it doesn't\n>>> introduce a false sense of security. I.e., we're not making a foolproof\n>>> tool; we're making building blocks that one could use for a more\n>>> foolproof tool.\n>>\n>> OK, let's make a tool that helps fooling as well as proofing :)\n>>\n>> I'll look into the tag header check. Maybe \"--check-tagname\"? \"check\"\n>> seems to imply less than \"verify\".\n> \n> Yeah, I think that is fine (I actually wrote --check originally; I'm not\n> quite sure why I decided to change it).\n> \n>> As for the gpg related stuff: We provide the full diagnostic output from\n>> gpg on request. But I think a mismatch between the signing key's uid and\n>> the taggers' name/email is more common than not,\n> \n> Is it? I'd think if you are using that name with a signed tag, you would\n> bother to issue (and get people to sign) the matching uid. Certainly it\n> is the case for git and linux signatures, but I admit that it a pretty\n> small sampling size.\n> \n> The bigger issue is that gpg seems to give us only _one_ uid, when there\n> may be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a\n> sub-key that has several uids associated with it. The one that \"git\n> verify-tag --raw\" shows from gpg is gitster@pobox.com, which is good,\n> but I think that's just because it happens to be the first uid. Or maybe\n> there is some gpg arcana going on that I don't know about.\n\nYou do not sign with a uid, you sign with a (sub)key, and the tag is\nsigned with Junio's primary key. His subkey is encryption only.\n\nuids do not identify keys, you can add and delete them at will without\nchanging the primary key id. To help recognize (\"identify\") a key, gpg\ndisplays the uid with the most recent self-signature, which is usually\nthe most \"recent uid\".\n\nYou do sign a uid.\n\nSo, if you want to be sure that a tag is signed \"with a specific uid\" by\nrelying on signatures from a set of signers, you would really need to\ncheck that the key that signed the tag has a signature on the correct\nuid. Having a signed key with the right uid in it doesn't mean much\nunlss the right uid is signed.\n\nE.g., I have a key with many signatures, and I could have Junio's uid on\nit in a minute without invalidating any of those signatures.\n\n>> and on the other hand a\n>> signature by a key identified by its uid is meaningless unless you keep\n>> your keyring tidy... We could punt on that and let users identify the\n>> key by any means that gpg allows, of course, and check that the\n>> signature comes from whatever \"gpg --list-key <userspecified>\" gives as\n>> long as it's unique.\n> \n> Right, I think it's an open question whether people actually participate\n> in the web of trust. I don't have a good signature path to Junio's key,\n> but I happen to know what it is based on past interaction.\n> \n> But then, I also do not really verify tags. Why would I? I routinely\n> fetch and run \"make\" on the result, and there is no cryptographic\n> protection there at all. Verifying tag signatures after a release seems\n> all but pointless. :)\n\nNo signature protects us from our own dogfood :)\n\n> I think for any of this to be useful, it has to be part of some tool\n> that is very opinionated on policy. E.g., imagine a post-fetch hook that\n> validated that each incoming commit was signed, and that the signer was\n> part of a whitelisted group of keys that you \"somehow\" got hold of\n> out-of-band for your project. That is not that useful for an open-source\n> project, but I could see the appeal for a proprietary development\n> environment.\n\nThat one is easy already by setting \"GNUPGHOME\" to a special dir with a\nsmall keyring and tight trust settings (or having a dedicated account on\nthe incoming side in the first place).\n\nMichael\n"},{"id":"276922","messageId":"xmqqmvrq99mt.fsf@gitster.mtv.corp.google.com","threadId":"41258","inReplyTo":"56A88A69.6030503@drmicha.warpmail.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-27T18:10:02Z","receivedAt":"2016-01-27T18:10:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Jeff King venit, vidit, dixit 27.01.2016 09:09:\n>\n>> The bigger issue is that gpg seems to give us only _one_ uid, when there\n>> may be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a\n>> sub-key that has several uids associated with it. The one that \"git\n>> verify-tag --raw\" shows from gpg is gitster@pobox.com, which is good,\n>> but I think that's just because it happens to be the first uid. Or maybe\n>> there is some gpg arcana going on that I don't know about.\n>\n> You do not sign with a uid, you sign with a (sub)key, and the tag is\n> signed with Junio's primary key. His subkey is encryption only.\n\nHmm, actually I meant to sign my tags with signing subkey, not the\nprimary one, but I may have made a mistake.\n\n> You do sign a uid.\n>\n> So, if you want to be sure that a tag is signed \"with a specific uid\" by\n> relying on signatures from a set of signers, you would really need to\n> check that the key that signed the tag has a signature on the correct\n> uid. Having a signed key with the right uid in it doesn't mean much\n> unlss the right uid is signed.\n>\n> E.g., I have a key with many signatures, and I could have Junio's uid on\n> it in a minute without invalidating any of those signatures.\n\nI have signatures on my primary key from others, and my signing key\nis signed by my primary key and by no other keys.  Here is an\nabbreviated output from running \"gpg --list-sigs 96AFE6CB\":\n\npub   4096R/713660A7 2011-10-01\nuid                  Junio C Hamano <gitster@pobox.com>\nsig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>\nsig          93674C40 2011-10-04  Theodore Y. Ts'o <tytso@mit.edu>\nsig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>\nsig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>\nsig          02A80207 2011-10-05  Andrew Morton (akpm) <akpm@linux-foundation.org>\nuid                  Junio C Hamano <junio@pobox.com>\nsig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>\nsig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>\nsig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>\nuid                  Junio C Hamano <jch@google.com>\nsig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>\nsig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>\nsub   4096R/833262C4 2011-10-01\nsig          713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\nsub   4096R/96AFE6CB 2011-10-03 [expires: 2017-09-20]\nsig          713660A7 2015-09-21  Junio C Hamano <gitster@pobox.com>\nsub   4096R/B3F7CAC9 2014-09-20 [expires: 2017-09-19]\nsig          713660A7 2014-09-20  Junio C Hamano <gitster@pobox.com>\n\nSo I understand that the way you trust 96AFE6CB has to be indirect.\nYou may have somebody's key you know belongs to that somebody you\ntrust (say, Linus) in the list of signers of 713660A7 (my primary),\nand you know 96AFE6CB is a key I use because it is signed by my\nprimary key.\n\nYou can add a subkey to your keyring a uid that says \"Junio\", but\nthe signature on that subkey would not have a signature by me you\ncan verify by following the web of trust.  You are correct to point\nout that \"this key claims to be by somebody, and it has some\nsignature\" is not a sufficient reason for you to trust it.\n\n> That one is easy already by setting \"GNUPGHOME\" to a special dir with a\n> small keyring and tight trust settings (or having a dedicated account on\n> the incoming side in the first place).\n\nYes, I understand that the above is how automated services per\nproject should be set up, with a dedicated verification keyring that\nholds keys the project trusts.\n"},{"id":"276928","messageId":"56A923FB.4050308@drmicha.warpmail.net","threadId":"41258","inReplyTo":"xmqqmvrq99mt.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-01-27T20:09:31Z","receivedAt":"2016-01-27T20:09:31Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Junio C Hamano venit, vidit, dixit 27.01.2016 19:10:\n> Michael J Gruber <git@drmicha.warpmail.net> writes:\n> \n>> Jeff King venit, vidit, dixit 27.01.2016 09:09:\n>>\n>>> The bigger issue is that gpg seems to give us only _one_ uid, when there\n>>> may be several. E.g., Junio's v2.7.0 is signed by 96AFE6CB, which is a\n>>> sub-key that has several uids associated with it. The one that \"git\n>>> verify-tag --raw\" shows from gpg is gitster@pobox.com, which is good,\n>>> but I think that's just because it happens to be the first uid. Or maybe\n>>> there is some gpg arcana going on that I don't know about.\n>>\n>> You do not sign with a uid, you sign with a (sub)key, and the tag is\n>> signed with Junio's primary key. His subkey is encryption only.\n> \n> Hmm, actually I meant to sign my tags with signing subkey, not the\n> primary one, but I may have made a mistake.\n\nOops, I needed to refresh my copy of your key, sorry. You did sign 2.7.0\nwith the subkey 0xB0B5E88696AFE6CB\n\n>> You do sign a uid.\n>>\n>> So, if you want to be sure that a tag is signed \"with a specific uid\" by\n>> relying on signatures from a set of signers, you would really need to\n>> check that the key that signed the tag has a signature on the correct\n>> uid. Having a signed key with the right uid in it doesn't mean much\n>> unlss the right uid is signed.\n>>\n>> E.g., I have a key with many signatures, and I could have Junio's uid on\n>> it in a minute without invalidating any of those signatures.\n> \n> I have signatures on my primary key from others, and my signing key\n> is signed by my primary key and by no other keys.  Here is an\n> abbreviated output from running \"gpg --list-sigs 96AFE6CB\":\n> \n> pub   4096R/713660A7 2011-10-01\n> uid                  Junio C Hamano <gitster@pobox.com>\n> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>\n> sig          93674C40 2011-10-04  Theodore Y. Ts'o <tytso@mit.edu>\n> sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>\n> sig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>\n> sig          02A80207 2011-10-05  Andrew Morton (akpm) <akpm@linux-foundation.org>\n> uid                  Junio C Hamano <junio@pobox.com>\n> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>\n> sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>\n> sig          C11804F0 2011-10-04  Theodore Ts'o <tytso@mit.edu>\n> uid                  Junio C Hamano <jch@google.com>\n> sig 3        713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sig          F3119B9A 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sig          493BACE4 2011-10-04  H. Peter Anvin (hpa) <hpa@zytor.com>\n> sig          00411886 2012-07-20  Linus Torvalds <torvalds@linux-foundation.org>\n> sub   4096R/833262C4 2011-10-01\n> sig          713660A7 2011-10-01  Junio C Hamano <gitster@pobox.com>\n> sub   4096R/96AFE6CB 2011-10-03 [expires: 2017-09-20]\n> sig          713660A7 2015-09-21  Junio C Hamano <gitster@pobox.com>\n> sub   4096R/B3F7CAC9 2014-09-20 [expires: 2017-09-19]\n> sig          713660A7 2014-09-20  Junio C Hamano <gitster@pobox.com>\n> \n> So I understand that the way you trust 96AFE6CB has to be indirect.\n> You may have somebody's key you know belongs to that somebody you\n> trust (say, Linus) in the list of signers of 713660A7 (my primary),\n> and you know 96AFE6CB is a key I use because it is signed by my\n> primary key.\n> \n> You can add a subkey to your keyring a uid that says \"Junio\", but\n> the signature on that subkey would not have a signature by me you\n> can verify by following the web of trust.  You are correct to point\n> out that \"this key claims to be by somebody, and it has some\n> signature\" is not a sufficient reason for you to trust it.\n\n\"subkey\" and \"uid\" are different things. You bind a subkey to your\nprimary key with that self-signature. subkeys don't carry any other\nsignatures.\n\nA primary key \"carries\" the uids, and whenever someone \"signs your key\"\nthey in fact sign a specific uid - usually all, resulting in multiple\nsignatures, one for each uid of the (primary) key.\n\nA key is usually considered trusted if it carries \"a\" signature from a\ntrusted key.\n\nSo, assuming my key carries a signature from a trusted key to at least\none uid, it would be trusted no matter what (fake) uids I add to it later.\n\n>> That one is easy already by setting \"GNUPGHOME\" to a special dir with a\n>> small keyring and tight trust settings (or having a dedicated account on\n>> the incoming side in the first place).\n> \n> Yes, I understand that the above is how automated services per\n> project should be set up, with a dedicated verification keyring that\n> holds keys the project trusts.\n\nMichael\n"},{"id":"276929","messageId":"20160127202111.GA30212@sigill.intra.peff.net","threadId":"41258","inReplyTo":"56A923FB.4050308@drmicha.warpmail.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-01-27T20:21:11Z","receivedAt":"2016-01-27T20:21:11Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 27, 2016 at 09:09:31PM +0100, Michael J Gruber wrote:\n\n> \"subkey\" and \"uid\" are different things. You bind a subkey to your\n> primary key with that self-signature. subkeys don't carry any other\n> signatures.\n> \n> A primary key \"carries\" the uids, and whenever someone \"signs your key\"\n> they in fact sign a specific uid - usually all, resulting in multiple\n> signatures, one for each uid of the (primary) key.\n> \n> A key is usually considered trusted if it carries \"a\" signature from a\n> trusted key.\n> \n> So, assuming my key carries a signature from a trusted key to at least\n> one uid, it would be trusted no matter what (fake) uids I add to it later.\n\nRight. I think I didn't do a good job of explaining myself earlier, so\nlet me try to rephrase.\n\nWhen we look at the v2.7 tag, GPG sees that we are signed by Junio's\nsubkey, 96AFE6CB. It then knows that belongs to the main public key\n713660A7, because the main key signed the subkey. And then it sees that\nthere are several uids for that main key, each with their own signatures\nby other people.\n\nSo of the three uids that I have for that key:\n\n  pub   4096R/713660A7 2011-10-01\n  uid                  Junio C Hamano <gitster@pobox.com>\n  uid                  Junio C Hamano <jch@google.com>\n  uid                  Junio C Hamano <junio@pobox.com>\n\nit reports back to git only one (the pobox.com), which we relay to the\nuser via --raw. If we wanted to check that the key matches the \"tagger\"\nheader, that works. But why did gpg return that first uid, and not any\nof the others? We would ideally see all of them, and consider it OK if\nit matches any uid (assuming that uid is sufficiently signed for gpg to\nconsider it valid).\n\nWeirder, if you _don't_ use \"--raw\", the human-readable output gives us\nall of the uids as \"aka\" lines:\n\n  $ git verify-tag v2.7.0\n  $ git verify-tag v2.7.0\n  gpg: Signature made Mon 04 Jan 2016 05:08:12 PM EST using RSA key ID 96AFE6CB\n  gpg: Good signature from \"Junio C Hamano <gitster@pobox.com>\"\n  gpg:                 aka \"Junio C Hamano <jch@google.com>\"\n  gpg:                 aka \"Junio C Hamano <junio@pobox.com>\"\n\n  $ git verify-tag --raw v2.7.0\n  [GNUPG:] SIG_ID xFANmHj+QJ1gwIcoRuT5BF/y8H4 2016-01-04 1451945292\n  [GNUPG:] GOODSIG B0B5E88696AFE6CB Junio C Hamano <gitster@pobox.com>\n  [GNUPG:] VALIDSIG E1F036B1FEE7221FC778ECEFB0B5E88696AFE6CB 2016-01-04 1451945292 0 4 0 1 2 00 96E07AF25771955980DAD10020D04E5A713660A7\n  [GNUPG:] TRUST_FULLY\n\nIt seems like we should be able to get the raw-output to tell us all of\nthose uids. I guess it is not the end of the world to go back to gpg and\nsay \"give me all of the valid uids that match this signing key\", but it\nseems silly to have to do so.\n\n-Peff\n"},{"id":"277006","messageId":"20160128210634.GD9629@LykOS","threadId":"41258","inReplyTo":"56A87764.9070101@drmicha.warpmail.net","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Santiago Torres","fromEmail":"santiago@nyu.edu","sentAt":"2016-01-28T21:06:34Z","receivedAt":"2016-01-28T21:06:34Z","isPatch":false,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"Hello, sorry for being MIA yesterday among all this movement...\n\nOn Wed, Jan 27, 2016 at 08:53:08AM +0100, Michael J Gruber wrote:\n> Jeff King venit, vidit, dixit 27.01.2016 08:33:\n> > On Wed, Jan 27, 2016 at 08:23:02AM +0100, Michael J Gruber wrote:\n> > \n> >>> Tag objects already have a \"tag\" header, which is part of the signed\n> >>> content. If you use \"git verify-tag -v\", you can check both that the\n> >>> signature is valid and that the tag is the one you are expecting.\n> >>\n> >> Yes, that's what I described in my last paragraph, using the term\n> >> (embedded) tag \"name\" which is technically wrong (it's not the tag\n> >> object's name, which would be a sha1) but the natural term for users.\n> > \n> > Indeed. I should have read further back in the quoting. :)\n> > \n> >>> Git pretty much punts on all of these issues and assumes either a human\n> >>> or a smarter tool is looking at the verification output. But I don't\n> >>> think it would hurt to build in some features to let git automatically\n> >>> check some things, if only to avoid callers duplicating work to\n> >>> implement the checks themselves.\n> >>\n> >> That is really a can of worms for several reasons:\n> >> [...]\n> >> So, for those who shy away from for-each-ref and such, we may add the\n> >> header check to verify-tag, with a big warning about the marginal gain\n> >> in security (or the requirements for an actual gain).\n> > \n> > Yeah, definitely. My thinking was that `verify-tag` could learn a series\n> > of optional consistency checks, enabled by command line options, and\n> > verifying programs (or humans) could turn them on to avoid having to\n> > replicate them manually. So something like:\n> > \n> >   git verify-tag \\\n> >     --verify-tagger-matches-key \\\n> >     --verify-tag-matches-ref \\ # or --verify-tag-matches=v2.0.0\n> >     v2.0.0\n> > \n> > or to implement more specific policy, maybe an option to check for a\n> > _specific_ tagger, either by email (as provided by gpg) or even key-id.\n> > \n> > Those are all things that are not _too_ hard to do if you're willing to\n> > parse gpg or git output, but we could make life easier for our callers.\n> > And hopefully by asking for specific, concrete checks, it doesn't\n> > introduce a false sense of security. I.e., we're not making a foolproof\n> > tool; we're making building blocks that one could use for a more\n> > foolproof tool.\n> \n> OK, let's make a tool that helps fooling as well as proofing :)\n> \n> I'll look into the tag header check. Maybe \"--check-tagname\"? \"check\"\n> seems to imply less than \"verify\".\n\nThis seems like exactly what I was thinking of. What I believe would be\nhelpful is to provide upstream tools the means to automatically verify tags\n(--check-tagname could return non-0 if the tagname doesn't match), could\nthis possibly be the default behavior (--no-check-tagname instead)?\nWhat worries me is something like this experiment with pip: \n\n(git-tag2) santiago@LykOS:~$ pip install -e git+https://github.com/santiagotorres/django/@1.8.3#egg=django\nObtaining django from\n\ngit+https://github.com/santiagotorres/django/@1.8.3#egg=django\n  Cloning https://github.com/santiagotorres/django/ (to 1.8.3) to\n  ./.virtualenvs/git-tag2/src/django\n  Installing collected packages: django\n    Running setup.py develop for django\nSuccessfully installed django\n(git-tag2) santiago@LykOS:~$ django-admin.py --version\n1.4.10\n\nI only had to swap the tag refs and push for this simulation. Needless\nto say, this deprectated django version (1.4.10) is vulnerable to a wide\nrange known exploits that include session hijacking, DoS, \"MySQL\ntypecasting\" and XSS.  And the person who served this tampered tag could\nexploit the webserver right away (knows who got this vulnerable\npackage).\n\nOf course, this could also trick a CI system and have people package the\nwrong version of django.\n\nI agree that nothing beats manual inspection of a paranoid developer,\nbut these tools are widely used today and could avoid these edge cases.\n\n> \n> As for the gpg related stuff: We provide the full diagnostic output from\n> gpg on request. But I think a mismatch between the signing key's uid and\n> the taggers' name/email is more common than not, and on the other hand a\n> signature by a key identified by its uid is meaningless unless you keep\n> your keyring tidy... We could punt on that and let users identify the\n> key by any means that gpg allows, of course, and check that the\n> signature comes from whatever \"gpg --list-key <userspecified>\" gives as\n> long as it's unique.\n> \n> But maybe I'm biased by my zoo of uids/emails addresses/full name\n> spellings... and general paranoia regarding the term \"verify\" ;)\n\nYeah, I believe the gpg related stuff might be a little out of scope. I\nthink, for the sake of this RFC, that we could assume that tools/people\nhave acess to the right key and could perform verification. As it was\nalready pointed out, key distribution and a project-specific gpg\nkeychain could be integrated.\n\nThe problem I see is that, even with the right key and a proper\nsignature, the tag metadata can still be modified and it wouldn't be\ndetected.\n\nThanks!\n-Santiago.\n"},{"id":"277007","messageId":"20160128210902.GE9629@LykOS","threadId":"41258","inReplyTo":"xmqqwpqwavtf.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC] tag-ref and tag object binding","fromName":"Santiago Torres","fromEmail":"santiago@nyu.edu","sentAt":"2016-01-28T21:09:02Z","receivedAt":"2016-01-28T21:09:02Z","isPatch":false,"sender":{"key":"santiago@nyu.edu","avatar":"https://avatars.githubusercontent.com/u/3579933?v=4"},"body":"On Tue, Jan 26, 2016 at 01:13:16PM -0800, Junio C Hamano wrote:\n> Jeff King <peff@peff.net> writes:\n> \n> > On Tue, Jan 26, 2016 at 10:29:42AM -0500, Santiago Torres wrote:\n> >\n> >> > If you cannot trust those with write access to a repo that you are\n> >> > pulling and installing from you might want to re-check where you are\n> >> > pulling or installing from ;)\n> >> \n> >> Yeah, I see your point, but mechanisms to ensure the server's origin can\n> >> be bypassed (e.g., a MITM). I don't think it would hurt to ensure the\n> >> source pointed to is the source itself. The tag signature can help us do\n> >> this.\n> >\n> > Right. I think the more interesting use case here is \"I trust the\n> > upstream repository owner, but I do not trust their hosting site of\n> > choice.\"\n> \n> Yup, and push-certificate is there to help with that issue.\n\nYes, I agree, but wouldn't this provide an in-band solution to this\nvery particular scenario. In order to provide the spureous tag, you have\nto provide the tagname it should be pointing to (or tamper with the tag\nobject).\n\nPush certificates can address many other sorts of attacks, but are not\nin-band in this sense are they?\n\nThanks!\n-Santiago.\n"}]}